[Groonga-commit] groonga/groonga at d8fb286 [master] nginx: use the latest mainline release

Back to archive index

Kouhei Sutou null+****@clear*****
Fri Jul 4 15:15:55 JST 2014


Kouhei Sutou	2014-07-04 15:15:55 +0900 (Fri, 04 Jul 2014)

  New Revision: d8fb28610065306f7f12388e2107189f72666e05
  https://github.com/groonga/groonga/commit/d8fb28610065306f7f12388e2107189f72666e05

  Message:
    nginx: use the latest mainline release
    
        1.4.7 ->
        1.7.2

  Added files:
    vendor/nginx-1.7.2/contrib/vim/ftdetect/nginx.vim
    vendor/nginx-1.7.2/contrib/vim/indent/nginx.vim
    vendor/nginx-1.7.2/contrib/vim/syntax/nginx.vim
    vendor/nginx-1.7.2/src/core/ngx_proxy_protocol.c
    vendor/nginx-1.7.2/src/core/ngx_proxy_protocol.h
    vendor/nginx-1.7.2/src/core/ngx_syslog.c
    vendor/nginx-1.7.2/src/core/ngx_syslog.h
    vendor/nginx-1.7.2/src/http/modules/ngx_http_auth_request_module.c
    vendor/nginx-1.7.2/src/http/modules/ngx_http_upstream_hash_module.c
  Modified files:
    nginx_version
  Renamed files:
    vendor/nginx-1.7.2/CHANGES
      (from vendor/nginx-1.4.7/CHANGES)
    vendor/nginx-1.7.2/CHANGES.ru
      (from vendor/nginx-1.4.7/CHANGES.ru)
    vendor/nginx-1.7.2/LICENSE
      (from vendor/nginx-1.4.7/LICENSE)
    vendor/nginx-1.7.2/README
      (from vendor/nginx-1.4.7/README)
    vendor/nginx-1.7.2/auto/cc/acc
      (from vendor/nginx-1.4.7/auto/cc/acc)
    vendor/nginx-1.7.2/auto/cc/bcc
      (from vendor/nginx-1.4.7/auto/cc/bcc)
    vendor/nginx-1.7.2/auto/cc/ccc
      (from vendor/nginx-1.4.7/auto/cc/ccc)
    vendor/nginx-1.7.2/auto/cc/clang
      (from vendor/nginx-1.4.7/auto/cc/clang)
    vendor/nginx-1.7.2/auto/cc/conf
      (from vendor/nginx-1.4.7/auto/cc/conf)
    vendor/nginx-1.7.2/auto/cc/gcc
      (from vendor/nginx-1.4.7/auto/cc/gcc)
    vendor/nginx-1.7.2/auto/cc/icc
      (from vendor/nginx-1.4.7/auto/cc/icc)
    vendor/nginx-1.7.2/auto/cc/msvc
      (from vendor/nginx-1.4.7/auto/cc/msvc)
    vendor/nginx-1.7.2/auto/cc/name
      (from vendor/nginx-1.4.7/auto/cc/name)
    vendor/nginx-1.7.2/auto/cc/owc
      (from vendor/nginx-1.4.7/auto/cc/owc)
    vendor/nginx-1.7.2/auto/cc/sunc
      (from vendor/nginx-1.4.7/auto/cc/sunc)
    vendor/nginx-1.7.2/auto/define
      (from vendor/nginx-1.4.7/auto/define)
    vendor/nginx-1.7.2/auto/endianness
      (from vendor/nginx-1.4.7/auto/endianness)
    vendor/nginx-1.7.2/auto/feature
      (from vendor/nginx-1.4.7/auto/feature)
    vendor/nginx-1.7.2/auto/have
      (from vendor/nginx-1.4.7/auto/have)
    vendor/nginx-1.7.2/auto/have_headers
      (from vendor/nginx-1.4.7/auto/have_headers)
    vendor/nginx-1.7.2/auto/headers
      (from vendor/nginx-1.4.7/auto/headers)
    vendor/nginx-1.7.2/auto/include
      (from vendor/nginx-1.4.7/auto/include)
    vendor/nginx-1.7.2/auto/init
      (from vendor/nginx-1.4.7/auto/init)
    vendor/nginx-1.7.2/auto/install
      (from vendor/nginx-1.4.7/auto/install)
    vendor/nginx-1.7.2/auto/lib/conf
      (from vendor/nginx-1.4.7/auto/lib/conf)
    vendor/nginx-1.7.2/auto/lib/geoip/conf
      (from vendor/nginx-1.4.7/auto/lib/geoip/conf)
    vendor/nginx-1.7.2/auto/lib/google-perftools/conf
      (from vendor/nginx-1.4.7/auto/lib/google-perftools/conf)
    vendor/nginx-1.7.2/auto/lib/libatomic/conf
      (from vendor/nginx-1.4.7/auto/lib/libatomic/conf)
    vendor/nginx-1.7.2/auto/lib/libatomic/make
      (from vendor/nginx-1.4.7/auto/lib/libatomic/make)
    vendor/nginx-1.7.2/auto/lib/libgd/conf
      (from vendor/nginx-1.4.7/auto/lib/libgd/conf)
    vendor/nginx-1.7.2/auto/lib/libxslt/conf
      (from vendor/nginx-1.4.7/auto/lib/libxslt/conf)
    vendor/nginx-1.7.2/auto/lib/make
      (from vendor/nginx-1.4.7/auto/lib/make)
    vendor/nginx-1.7.2/auto/lib/md5/conf
      (from vendor/nginx-1.4.7/auto/lib/md5/conf)
    vendor/nginx-1.7.2/auto/lib/md5/make
      (from vendor/nginx-1.4.7/auto/lib/md5/make)
    vendor/nginx-1.7.2/auto/lib/md5/makefile.bcc
      (from vendor/nginx-1.4.7/auto/lib/md5/makefile.bcc)
    vendor/nginx-1.7.2/auto/lib/md5/makefile.msvc
      (from vendor/nginx-1.4.7/auto/lib/md5/makefile.msvc)
    vendor/nginx-1.7.2/auto/lib/md5/makefile.owc
      (from vendor/nginx-1.4.7/auto/lib/md5/makefile.owc)
    vendor/nginx-1.7.2/auto/lib/openssl/conf
      (from vendor/nginx-1.4.7/auto/lib/openssl/conf)
    vendor/nginx-1.7.2/auto/lib/openssl/make
      (from vendor/nginx-1.4.7/auto/lib/openssl/make)
    vendor/nginx-1.7.2/auto/lib/openssl/makefile.bcc
      (from vendor/nginx-1.4.7/auto/lib/openssl/makefile.bcc)
    vendor/nginx-1.7.2/auto/lib/openssl/makefile.msvc
      (from vendor/nginx-1.4.7/auto/lib/openssl/makefile.msvc)
    vendor/nginx-1.7.2/auto/lib/pcre/conf
      (from vendor/nginx-1.4.7/auto/lib/pcre/conf)
    vendor/nginx-1.7.2/auto/lib/pcre/make
      (from vendor/nginx-1.4.7/auto/lib/pcre/make)
    vendor/nginx-1.7.2/auto/lib/pcre/makefile.bcc
      (from vendor/nginx-1.4.7/auto/lib/pcre/makefile.bcc)
    vendor/nginx-1.7.2/auto/lib/pcre/makefile.msvc
      (from vendor/nginx-1.4.7/auto/lib/pcre/makefile.msvc)
    vendor/nginx-1.7.2/auto/lib/pcre/makefile.owc
      (from vendor/nginx-1.4.7/auto/lib/pcre/makefile.owc)
    vendor/nginx-1.7.2/auto/lib/perl/conf
      (from vendor/nginx-1.4.7/auto/lib/perl/conf)
    vendor/nginx-1.7.2/auto/lib/perl/make
      (from vendor/nginx-1.4.7/auto/lib/perl/make)
    vendor/nginx-1.7.2/auto/lib/sha1/conf
      (from vendor/nginx-1.4.7/auto/lib/sha1/conf)
    vendor/nginx-1.7.2/auto/lib/sha1/make
      (from vendor/nginx-1.4.7/auto/lib/sha1/make)
    vendor/nginx-1.7.2/auto/lib/sha1/makefile.bcc
      (from vendor/nginx-1.4.7/auto/lib/sha1/makefile.bcc)
    vendor/nginx-1.7.2/auto/lib/sha1/makefile.msvc
      (from vendor/nginx-1.4.7/auto/lib/sha1/makefile.msvc)
    vendor/nginx-1.7.2/auto/lib/sha1/makefile.owc
      (from vendor/nginx-1.4.7/auto/lib/sha1/makefile.owc)
    vendor/nginx-1.7.2/auto/lib/test
      (from vendor/nginx-1.4.7/auto/lib/test)
    vendor/nginx-1.7.2/auto/lib/zlib/conf
      (from vendor/nginx-1.4.7/auto/lib/zlib/conf)
    vendor/nginx-1.7.2/auto/lib/zlib/make
      (from vendor/nginx-1.4.7/auto/lib/zlib/make)
    vendor/nginx-1.7.2/auto/lib/zlib/makefile.bcc
      (from vendor/nginx-1.4.7/auto/lib/zlib/makefile.bcc)
    vendor/nginx-1.7.2/auto/lib/zlib/makefile.msvc
      (from vendor/nginx-1.4.7/auto/lib/zlib/makefile.msvc)
    vendor/nginx-1.7.2/auto/lib/zlib/makefile.owc
      (from vendor/nginx-1.4.7/auto/lib/zlib/makefile.owc)
    vendor/nginx-1.7.2/auto/lib/zlib/patch.zlib.h
      (from vendor/nginx-1.4.7/auto/lib/zlib/patch.zlib.h)
    vendor/nginx-1.7.2/auto/make
      (from vendor/nginx-1.4.7/auto/make)
    vendor/nginx-1.7.2/auto/modules
      (from vendor/nginx-1.4.7/auto/modules)
    vendor/nginx-1.7.2/auto/nohave
      (from vendor/nginx-1.4.7/auto/nohave)
    vendor/nginx-1.7.2/auto/options
      (from vendor/nginx-1.4.7/auto/options)
    vendor/nginx-1.7.2/auto/os/conf
      (from vendor/nginx-1.4.7/auto/os/conf)
    vendor/nginx-1.7.2/auto/os/darwin
      (from vendor/nginx-1.4.7/auto/os/darwin)
    vendor/nginx-1.7.2/auto/os/freebsd
      (from vendor/nginx-1.4.7/auto/os/freebsd)
    vendor/nginx-1.7.2/auto/os/linux
      (from vendor/nginx-1.4.7/auto/os/linux)
    vendor/nginx-1.7.2/auto/os/solaris
      (from vendor/nginx-1.4.7/auto/os/solaris)
    vendor/nginx-1.7.2/auto/os/win32
      (from vendor/nginx-1.4.7/auto/os/win32)
    vendor/nginx-1.7.2/auto/sources
      (from vendor/nginx-1.4.7/auto/sources)
    vendor/nginx-1.7.2/auto/stubs
      (from vendor/nginx-1.4.7/auto/stubs)
    vendor/nginx-1.7.2/auto/summary
      (from vendor/nginx-1.4.7/auto/summary)
    vendor/nginx-1.7.2/auto/types/sizeof
      (from vendor/nginx-1.4.7/auto/types/sizeof)
    vendor/nginx-1.7.2/auto/types/typedef
      (from vendor/nginx-1.4.7/auto/types/typedef)
    vendor/nginx-1.7.2/auto/types/uintptr_t
      (from vendor/nginx-1.4.7/auto/types/uintptr_t)
    vendor/nginx-1.7.2/auto/types/value
      (from vendor/nginx-1.4.7/auto/types/value)
    vendor/nginx-1.7.2/auto/unix
      (from vendor/nginx-1.4.7/auto/unix)
    vendor/nginx-1.7.2/conf/fastcgi.conf
      (from vendor/nginx-1.4.7/conf/fastcgi.conf)
    vendor/nginx-1.7.2/conf/fastcgi_params
      (from vendor/nginx-1.4.7/conf/fastcgi_params)
    vendor/nginx-1.7.2/conf/koi-utf
      (from vendor/nginx-1.4.7/conf/koi-utf)
    vendor/nginx-1.7.2/conf/koi-win
      (from vendor/nginx-1.4.7/conf/koi-win)
    vendor/nginx-1.7.2/conf/mime.types
      (from vendor/nginx-1.4.7/conf/mime.types)
    vendor/nginx-1.7.2/conf/nginx.conf
      (from vendor/nginx-1.4.7/conf/nginx.conf)
    vendor/nginx-1.7.2/conf/scgi_params
      (from vendor/nginx-1.4.7/conf/scgi_params)
    vendor/nginx-1.7.2/conf/uwsgi_params
      (from vendor/nginx-1.4.7/conf/uwsgi_params)
    vendor/nginx-1.7.2/conf/win-utf
      (from vendor/nginx-1.4.7/conf/win-utf)
    vendor/nginx-1.7.2/configure
      (from vendor/nginx-1.4.7/configure)
    vendor/nginx-1.7.2/contrib/README
      (from vendor/nginx-1.4.7/contrib/README)
    vendor/nginx-1.7.2/contrib/geo2nginx.pl
      (from vendor/nginx-1.4.7/contrib/geo2nginx.pl)
    vendor/nginx-1.7.2/contrib/unicode2nginx/koi-utf
      (from vendor/nginx-1.4.7/contrib/unicode2nginx/koi-utf)
    vendor/nginx-1.7.2/contrib/unicode2nginx/unicode-to-nginx.pl
      (from vendor/nginx-1.4.7/contrib/unicode2nginx/unicode-to-nginx.pl)
    vendor/nginx-1.7.2/contrib/unicode2nginx/win-utf
      (from vendor/nginx-1.4.7/contrib/unicode2nginx/win-utf)
    vendor/nginx-1.7.2/html/50x.html
      (from vendor/nginx-1.4.7/html/50x.html)
    vendor/nginx-1.7.2/html/index.html
      (from vendor/nginx-1.4.7/html/index.html)
    vendor/nginx-1.7.2/man/nginx.8
      (from vendor/nginx-1.4.7/man/nginx.8)
    vendor/nginx-1.7.2/src/core/nginx.c
      (from vendor/nginx-1.4.7/src/core/nginx.c)
    vendor/nginx-1.7.2/src/core/nginx.h
      (from vendor/nginx-1.4.7/src/core/nginx.h)
    vendor/nginx-1.7.2/src/core/ngx_array.c
      (from vendor/nginx-1.4.7/src/core/ngx_array.c)
    vendor/nginx-1.7.2/src/core/ngx_array.h
      (from vendor/nginx-1.4.7/src/core/ngx_array.h)
    vendor/nginx-1.7.2/src/core/ngx_buf.c
      (from vendor/nginx-1.4.7/src/core/ngx_buf.c)
    vendor/nginx-1.7.2/src/core/ngx_buf.h
      (from vendor/nginx-1.4.7/src/core/ngx_buf.h)
    vendor/nginx-1.7.2/src/core/ngx_conf_file.c
      (from vendor/nginx-1.4.7/src/core/ngx_conf_file.c)
    vendor/nginx-1.7.2/src/core/ngx_conf_file.h
      (from vendor/nginx-1.4.7/src/core/ngx_conf_file.h)
    vendor/nginx-1.7.2/src/core/ngx_config.h
      (from vendor/nginx-1.4.7/src/core/ngx_config.h)
    vendor/nginx-1.7.2/src/core/ngx_connection.c
      (from vendor/nginx-1.4.7/src/core/ngx_connection.c)
    vendor/nginx-1.7.2/src/core/ngx_connection.h
      (from vendor/nginx-1.4.7/src/core/ngx_connection.h)
    vendor/nginx-1.7.2/src/core/ngx_core.h
      (from vendor/nginx-1.4.7/src/core/ngx_core.h)
    vendor/nginx-1.7.2/src/core/ngx_cpuinfo.c
      (from vendor/nginx-1.4.7/src/core/ngx_cpuinfo.c)
    vendor/nginx-1.7.2/src/core/ngx_crc.h
      (from vendor/nginx-1.4.7/src/core/ngx_crc.h)
    vendor/nginx-1.7.2/src/core/ngx_crc32.c
      (from vendor/nginx-1.4.7/src/core/ngx_crc32.c)
    vendor/nginx-1.7.2/src/core/ngx_crc32.h
      (from vendor/nginx-1.4.7/src/core/ngx_crc32.h)
    vendor/nginx-1.7.2/src/core/ngx_crypt.c
      (from vendor/nginx-1.4.7/src/core/ngx_crypt.c)
    vendor/nginx-1.7.2/src/core/ngx_crypt.h
      (from vendor/nginx-1.4.7/src/core/ngx_crypt.h)
    vendor/nginx-1.7.2/src/core/ngx_cycle.c
      (from vendor/nginx-1.4.7/src/core/ngx_cycle.c)
    vendor/nginx-1.7.2/src/core/ngx_cycle.h
      (from vendor/nginx-1.4.7/src/core/ngx_cycle.h)
    vendor/nginx-1.7.2/src/core/ngx_file.c
      (from vendor/nginx-1.4.7/src/core/ngx_file.c)
    vendor/nginx-1.7.2/src/core/ngx_file.h
      (from vendor/nginx-1.4.7/src/core/ngx_file.h)
    vendor/nginx-1.7.2/src/core/ngx_hash.c
      (from vendor/nginx-1.4.7/src/core/ngx_hash.c)
    vendor/nginx-1.7.2/src/core/ngx_hash.h
      (from vendor/nginx-1.4.7/src/core/ngx_hash.h)
    vendor/nginx-1.7.2/src/core/ngx_inet.c
      (from vendor/nginx-1.4.7/src/core/ngx_inet.c)
    vendor/nginx-1.7.2/src/core/ngx_inet.h
      (from vendor/nginx-1.4.7/src/core/ngx_inet.h)
    vendor/nginx-1.7.2/src/core/ngx_list.c
      (from vendor/nginx-1.4.7/src/core/ngx_list.c)
    vendor/nginx-1.7.2/src/core/ngx_list.h
      (from vendor/nginx-1.4.7/src/core/ngx_list.h)
    vendor/nginx-1.7.2/src/core/ngx_log.c
      (from vendor/nginx-1.4.7/src/core/ngx_log.c)
    vendor/nginx-1.7.2/src/core/ngx_log.h
      (from vendor/nginx-1.4.7/src/core/ngx_log.h)
    vendor/nginx-1.7.2/src/core/ngx_md5.c
      (from vendor/nginx-1.4.7/src/core/ngx_md5.c)
    vendor/nginx-1.7.2/src/core/ngx_md5.h
      (from vendor/nginx-1.4.7/src/core/ngx_md5.h)
    vendor/nginx-1.7.2/src/core/ngx_murmurhash.c
      (from vendor/nginx-1.4.7/src/core/ngx_murmurhash.c)
    vendor/nginx-1.7.2/src/core/ngx_murmurhash.h
      (from vendor/nginx-1.4.7/src/core/ngx_murmurhash.h)
    vendor/nginx-1.7.2/src/core/ngx_open_file_cache.c
      (from vendor/nginx-1.4.7/src/core/ngx_open_file_cache.c)
    vendor/nginx-1.7.2/src/core/ngx_open_file_cache.h
      (from vendor/nginx-1.4.7/src/core/ngx_open_file_cache.h)
    vendor/nginx-1.7.2/src/core/ngx_output_chain.c
      (from vendor/nginx-1.4.7/src/core/ngx_output_chain.c)
    vendor/nginx-1.7.2/src/core/ngx_palloc.c
      (from vendor/nginx-1.4.7/src/core/ngx_palloc.c)
    vendor/nginx-1.7.2/src/core/ngx_palloc.h
      (from vendor/nginx-1.4.7/src/core/ngx_palloc.h)
    vendor/nginx-1.7.2/src/core/ngx_parse.c
      (from vendor/nginx-1.4.7/src/core/ngx_parse.c)
    vendor/nginx-1.7.2/src/core/ngx_parse.h
      (from vendor/nginx-1.4.7/src/core/ngx_parse.h)
    vendor/nginx-1.7.2/src/core/ngx_queue.c
      (from vendor/nginx-1.4.7/src/core/ngx_queue.c)
    vendor/nginx-1.7.2/src/core/ngx_queue.h
      (from vendor/nginx-1.4.7/src/core/ngx_queue.h)
    vendor/nginx-1.7.2/src/core/ngx_radix_tree.c
      (from vendor/nginx-1.4.7/src/core/ngx_radix_tree.c)
    vendor/nginx-1.7.2/src/core/ngx_radix_tree.h
      (from vendor/nginx-1.4.7/src/core/ngx_radix_tree.h)
    vendor/nginx-1.7.2/src/core/ngx_rbtree.c
      (from vendor/nginx-1.4.7/src/core/ngx_rbtree.c)
    vendor/nginx-1.7.2/src/core/ngx_rbtree.h
      (from vendor/nginx-1.4.7/src/core/ngx_rbtree.h)
    vendor/nginx-1.7.2/src/core/ngx_regex.c
      (from vendor/nginx-1.4.7/src/core/ngx_regex.c)
    vendor/nginx-1.7.2/src/core/ngx_regex.h
      (from vendor/nginx-1.4.7/src/core/ngx_regex.h)
    vendor/nginx-1.7.2/src/core/ngx_resolver.c
      (from vendor/nginx-1.4.7/src/core/ngx_resolver.c)
    vendor/nginx-1.7.2/src/core/ngx_resolver.h
      (from vendor/nginx-1.4.7/src/core/ngx_resolver.h)
    vendor/nginx-1.7.2/src/core/ngx_sha1.h
      (from vendor/nginx-1.4.7/src/core/ngx_sha1.h)
    vendor/nginx-1.7.2/src/core/ngx_shmtx.c
      (from vendor/nginx-1.4.7/src/core/ngx_shmtx.c)
    vendor/nginx-1.7.2/src/core/ngx_shmtx.h
      (from vendor/nginx-1.4.7/src/core/ngx_shmtx.h)
    vendor/nginx-1.7.2/src/core/ngx_slab.c
      (from vendor/nginx-1.4.7/src/core/ngx_slab.c)
    vendor/nginx-1.7.2/src/core/ngx_slab.h
      (from vendor/nginx-1.4.7/src/core/ngx_slab.h)
    vendor/nginx-1.7.2/src/core/ngx_spinlock.c
      (from vendor/nginx-1.4.7/src/core/ngx_spinlock.c)
    vendor/nginx-1.7.2/src/core/ngx_string.c
      (from vendor/nginx-1.4.7/src/core/ngx_string.c)
    vendor/nginx-1.7.2/src/core/ngx_string.h
      (from vendor/nginx-1.4.7/src/core/ngx_string.h)
    vendor/nginx-1.7.2/src/core/ngx_times.c
      (from vendor/nginx-1.4.7/src/core/ngx_times.c)
    vendor/nginx-1.7.2/src/core/ngx_times.h
      (from vendor/nginx-1.4.7/src/core/ngx_times.h)
    vendor/nginx-1.7.2/src/event/modules/ngx_aio_module.c
      (from vendor/nginx-1.4.7/src/event/modules/ngx_aio_module.c)
    vendor/nginx-1.7.2/src/event/modules/ngx_devpoll_module.c
      (from vendor/nginx-1.4.7/src/event/modules/ngx_devpoll_module.c)
    vendor/nginx-1.7.2/src/event/modules/ngx_epoll_module.c
      (from vendor/nginx-1.4.7/src/event/modules/ngx_epoll_module.c)
    vendor/nginx-1.7.2/src/event/modules/ngx_eventport_module.c
      (from vendor/nginx-1.4.7/src/event/modules/ngx_eventport_module.c)
    vendor/nginx-1.7.2/src/event/modules/ngx_kqueue_module.c
      (from vendor/nginx-1.4.7/src/event/modules/ngx_kqueue_module.c)
    vendor/nginx-1.7.2/src/event/modules/ngx_poll_module.c
      (from vendor/nginx-1.4.7/src/event/modules/ngx_poll_module.c)
    vendor/nginx-1.7.2/src/event/modules/ngx_rtsig_module.c
      (from vendor/nginx-1.4.7/src/event/modules/ngx_rtsig_module.c)
    vendor/nginx-1.7.2/src/event/modules/ngx_select_module.c
      (from vendor/nginx-1.4.7/src/event/modules/ngx_select_module.c)
    vendor/nginx-1.7.2/src/event/modules/ngx_win32_select_module.c
      (from vendor/nginx-1.4.7/src/event/modules/ngx_win32_select_module.c)
    vendor/nginx-1.7.2/src/event/ngx_event.c
      (from vendor/nginx-1.4.7/src/event/ngx_event.c)
    vendor/nginx-1.7.2/src/event/ngx_event.h
      (from vendor/nginx-1.4.7/src/event/ngx_event.h)
    vendor/nginx-1.7.2/src/event/ngx_event_accept.c
      (from vendor/nginx-1.4.7/src/event/ngx_event_accept.c)
    vendor/nginx-1.7.2/src/event/ngx_event_busy_lock.c
      (from vendor/nginx-1.4.7/src/event/ngx_event_busy_lock.c)
    vendor/nginx-1.7.2/src/event/ngx_event_busy_lock.h
      (from vendor/nginx-1.4.7/src/event/ngx_event_busy_lock.h)
    vendor/nginx-1.7.2/src/event/ngx_event_connect.c
      (from vendor/nginx-1.4.7/src/event/ngx_event_connect.c)
    vendor/nginx-1.7.2/src/event/ngx_event_connect.h
      (from vendor/nginx-1.4.7/src/event/ngx_event_connect.h)
    vendor/nginx-1.7.2/src/event/ngx_event_mutex.c
      (from vendor/nginx-1.4.7/src/event/ngx_event_mutex.c)
    vendor/nginx-1.7.2/src/event/ngx_event_openssl.c
      (from vendor/nginx-1.4.7/src/event/ngx_event_openssl.c)
    vendor/nginx-1.7.2/src/event/ngx_event_openssl.h
      (from vendor/nginx-1.4.7/src/event/ngx_event_openssl.h)
    vendor/nginx-1.7.2/src/event/ngx_event_openssl_stapling.c
      (from vendor/nginx-1.4.7/src/event/ngx_event_openssl_stapling.c)
    vendor/nginx-1.7.2/src/event/ngx_event_pipe.c
      (from vendor/nginx-1.4.7/src/event/ngx_event_pipe.c)
    vendor/nginx-1.7.2/src/event/ngx_event_pipe.h
      (from vendor/nginx-1.4.7/src/event/ngx_event_pipe.h)
    vendor/nginx-1.7.2/src/event/ngx_event_posted.c
      (from vendor/nginx-1.4.7/src/event/ngx_event_posted.c)
    vendor/nginx-1.7.2/src/event/ngx_event_posted.h
      (from vendor/nginx-1.4.7/src/event/ngx_event_posted.h)
    vendor/nginx-1.7.2/src/event/ngx_event_timer.c
      (from vendor/nginx-1.4.7/src/event/ngx_event_timer.c)
    vendor/nginx-1.7.2/src/event/ngx_event_timer.h
      (from vendor/nginx-1.4.7/src/event/ngx_event_timer.h)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_access_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_access_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_addition_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_addition_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_auth_basic_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_auth_basic_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_autoindex_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_autoindex_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_browser_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_browser_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_charset_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_charset_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_chunked_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_chunked_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_dav_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_dav_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_degradation_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_degradation_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_empty_gif_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_empty_gif_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_fastcgi_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_fastcgi_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_flv_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_flv_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_geo_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_geo_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_geoip_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_geoip_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_gunzip_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_gunzip_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_gzip_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_gzip_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_gzip_static_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_gzip_static_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_headers_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_headers_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_image_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_image_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_index_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_index_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_limit_conn_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_limit_conn_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_limit_req_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_limit_req_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_log_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_log_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_map_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_map_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_memcached_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_memcached_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_mp4_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_mp4_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_not_modified_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_not_modified_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_proxy_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_proxy_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_random_index_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_random_index_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_range_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_range_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_realip_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_realip_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_referer_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_referer_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_rewrite_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_rewrite_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_scgi_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_scgi_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_secure_link_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_secure_link_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_split_clients_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_split_clients_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_ssi_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_ssi_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_ssi_filter_module.h
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_ssi_filter_module.h)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_ssl_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_ssl_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_ssl_module.h
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_ssl_module.h)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_static_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_static_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_stub_status_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_stub_status_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_sub_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_sub_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_upstream_ip_hash_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_upstream_ip_hash_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_upstream_keepalive_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_upstream_keepalive_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_upstream_least_conn_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_upstream_least_conn_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_userid_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_userid_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_uwsgi_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_uwsgi_module.c)
    vendor/nginx-1.7.2/src/http/modules/ngx_http_xslt_filter_module.c
      (from vendor/nginx-1.4.7/src/http/modules/ngx_http_xslt_filter_module.c)
    vendor/nginx-1.7.2/src/http/modules/perl/Makefile.PL
      (from vendor/nginx-1.4.7/src/http/modules/perl/Makefile.PL)
    vendor/nginx-1.7.2/src/http/modules/perl/nginx.pm
      (from vendor/nginx-1.4.7/src/http/modules/perl/nginx.pm)
    vendor/nginx-1.7.2/src/http/modules/perl/nginx.xs
      (from vendor/nginx-1.4.7/src/http/modules/perl/nginx.xs)
    vendor/nginx-1.7.2/src/http/modules/perl/ngx_http_perl_module.c
      (from vendor/nginx-1.4.7/src/http/modules/perl/ngx_http_perl_module.c)
    vendor/nginx-1.7.2/src/http/modules/perl/ngx_http_perl_module.h
      (from vendor/nginx-1.4.7/src/http/modules/perl/ngx_http_perl_module.h)
    vendor/nginx-1.7.2/src/http/modules/perl/typemap
      (from vendor/nginx-1.4.7/src/http/modules/perl/typemap)
    vendor/nginx-1.7.2/src/http/ngx_http.c
      (from vendor/nginx-1.4.7/src/http/ngx_http.c)
    vendor/nginx-1.7.2/src/http/ngx_http.h
      (from vendor/nginx-1.4.7/src/http/ngx_http.h)
    vendor/nginx-1.7.2/src/http/ngx_http_busy_lock.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_busy_lock.c)
    vendor/nginx-1.7.2/src/http/ngx_http_busy_lock.h
      (from vendor/nginx-1.4.7/src/http/ngx_http_busy_lock.h)
    vendor/nginx-1.7.2/src/http/ngx_http_cache.h
      (from vendor/nginx-1.4.7/src/http/ngx_http_cache.h)
    vendor/nginx-1.7.2/src/http/ngx_http_config.h
      (from vendor/nginx-1.4.7/src/http/ngx_http_config.h)
    vendor/nginx-1.7.2/src/http/ngx_http_copy_filter_module.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_copy_filter_module.c)
    vendor/nginx-1.7.2/src/http/ngx_http_core_module.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_core_module.c)
    vendor/nginx-1.7.2/src/http/ngx_http_core_module.h
      (from vendor/nginx-1.4.7/src/http/ngx_http_core_module.h)
    vendor/nginx-1.7.2/src/http/ngx_http_file_cache.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_file_cache.c)
    vendor/nginx-1.7.2/src/http/ngx_http_header_filter_module.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_header_filter_module.c)
    vendor/nginx-1.7.2/src/http/ngx_http_parse.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_parse.c)
    vendor/nginx-1.7.2/src/http/ngx_http_parse_time.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_parse_time.c)
    vendor/nginx-1.7.2/src/http/ngx_http_postpone_filter_module.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_postpone_filter_module.c)
    vendor/nginx-1.7.2/src/http/ngx_http_request.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_request.c)
    vendor/nginx-1.7.2/src/http/ngx_http_request.h
      (from vendor/nginx-1.4.7/src/http/ngx_http_request.h)
    vendor/nginx-1.7.2/src/http/ngx_http_request_body.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_request_body.c)
    vendor/nginx-1.7.2/src/http/ngx_http_script.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_script.c)
    vendor/nginx-1.7.2/src/http/ngx_http_script.h
      (from vendor/nginx-1.4.7/src/http/ngx_http_script.h)
    vendor/nginx-1.7.2/src/http/ngx_http_spdy.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_spdy.c)
    vendor/nginx-1.7.2/src/http/ngx_http_spdy.h
      (from vendor/nginx-1.4.7/src/http/ngx_http_spdy.h)
    vendor/nginx-1.7.2/src/http/ngx_http_spdy_filter_module.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_spdy_filter_module.c)
    vendor/nginx-1.7.2/src/http/ngx_http_spdy_module.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_spdy_module.c)
    vendor/nginx-1.7.2/src/http/ngx_http_spdy_module.h
      (from vendor/nginx-1.4.7/src/http/ngx_http_spdy_module.h)
    vendor/nginx-1.7.2/src/http/ngx_http_special_response.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_special_response.c)
    vendor/nginx-1.7.2/src/http/ngx_http_upstream.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_upstream.c)
    vendor/nginx-1.7.2/src/http/ngx_http_upstream.h
      (from vendor/nginx-1.4.7/src/http/ngx_http_upstream.h)
    vendor/nginx-1.7.2/src/http/ngx_http_upstream_round_robin.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_upstream_round_robin.c)
    vendor/nginx-1.7.2/src/http/ngx_http_upstream_round_robin.h
      (from vendor/nginx-1.4.7/src/http/ngx_http_upstream_round_robin.h)
    vendor/nginx-1.7.2/src/http/ngx_http_variables.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_variables.c)
    vendor/nginx-1.7.2/src/http/ngx_http_variables.h
      (from vendor/nginx-1.4.7/src/http/ngx_http_variables.h)
    vendor/nginx-1.7.2/src/http/ngx_http_write_filter_module.c
      (from vendor/nginx-1.4.7/src/http/ngx_http_write_filter_module.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail.h
      (from vendor/nginx-1.4.7/src/mail/ngx_mail.h)
    vendor/nginx-1.7.2/src/mail/ngx_mail_auth_http_module.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_auth_http_module.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail_core_module.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_core_module.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail_handler.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_handler.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail_imap_handler.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_imap_handler.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail_imap_module.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_imap_module.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail_imap_module.h
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_imap_module.h)
    vendor/nginx-1.7.2/src/mail/ngx_mail_parse.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_parse.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail_pop3_handler.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_pop3_handler.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail_pop3_module.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_pop3_module.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail_pop3_module.h
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_pop3_module.h)
    vendor/nginx-1.7.2/src/mail/ngx_mail_proxy_module.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_proxy_module.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail_smtp_handler.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_smtp_handler.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail_smtp_module.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_smtp_module.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail_smtp_module.h
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_smtp_module.h)
    vendor/nginx-1.7.2/src/mail/ngx_mail_ssl_module.c
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_ssl_module.c)
    vendor/nginx-1.7.2/src/mail/ngx_mail_ssl_module.h
      (from vendor/nginx-1.4.7/src/mail/ngx_mail_ssl_module.h)
    vendor/nginx-1.7.2/src/misc/ngx_cpp_test_module.cpp
      (from vendor/nginx-1.4.7/src/misc/ngx_cpp_test_module.cpp)
    vendor/nginx-1.7.2/src/misc/ngx_google_perftools_module.c
      (from vendor/nginx-1.4.7/src/misc/ngx_google_perftools_module.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_aio_read.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_aio_read.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_aio_read_chain.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_aio_read_chain.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_aio_write.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_aio_write.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_aio_write_chain.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_aio_write_chain.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_alloc.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_alloc.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_alloc.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_alloc.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_atomic.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_atomic.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_channel.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_channel.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_channel.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_channel.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_daemon.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_daemon.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_darwin.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_darwin.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_darwin_config.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_darwin_config.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_darwin_init.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_darwin_init.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_darwin_sendfile_chain.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_darwin_sendfile_chain.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_errno.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_errno.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_errno.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_errno.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_file_aio_read.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_file_aio_read.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_files.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_files.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_files.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_files.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_freebsd.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_freebsd.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_config.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_freebsd_config.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_init.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_freebsd_init.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_rfork_thread.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_freebsd_rfork_thread.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_rfork_thread.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_freebsd_rfork_thread.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_sendfile_chain.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_freebsd_sendfile_chain.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_gcc_atomic_amd64.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_gcc_atomic_amd64.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_gcc_atomic_ppc.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_gcc_atomic_ppc.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_gcc_atomic_sparc64.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_gcc_atomic_sparc64.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_gcc_atomic_x86.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_gcc_atomic_x86.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_linux.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_linux.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_linux_aio_read.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_linux_aio_read.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_linux_config.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_linux_config.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_linux_init.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_linux_init.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_linux_sendfile_chain.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_linux_sendfile_chain.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_os.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_os.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_posix_config.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_posix_config.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_posix_init.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_posix_init.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_process.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_process.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_process.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_process.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_process_cycle.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_process_cycle.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_process_cycle.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_process_cycle.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_pthread_thread.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_pthread_thread.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_readv_chain.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_readv_chain.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_recv.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_recv.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_send.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_send.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_setaffinity.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_setaffinity.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_setaffinity.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_setaffinity.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_setproctitle.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_setproctitle.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_setproctitle.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_setproctitle.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_shmem.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_shmem.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_shmem.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_shmem.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_socket.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_socket.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_socket.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_socket.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_solaris.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_solaris.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_solaris_config.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_solaris_config.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_solaris_init.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_solaris_init.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_solaris_sendfilev_chain.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_solaris_sendfilev_chain.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_sunpro_amd64.il
      (from vendor/nginx-1.4.7/src/os/unix/ngx_sunpro_amd64.il)
    vendor/nginx-1.7.2/src/os/unix/ngx_sunpro_atomic_sparc64.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_sunpro_atomic_sparc64.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_sunpro_sparc64.il
      (from vendor/nginx-1.4.7/src/os/unix/ngx_sunpro_sparc64.il)
    vendor/nginx-1.7.2/src/os/unix/ngx_sunpro_x86.il
      (from vendor/nginx-1.4.7/src/os/unix/ngx_sunpro_x86.il)
    vendor/nginx-1.7.2/src/os/unix/ngx_thread.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_thread.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_time.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_time.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_time.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_time.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_udp_recv.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_udp_recv.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_user.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_user.c)
    vendor/nginx-1.7.2/src/os/unix/ngx_user.h
      (from vendor/nginx-1.4.7/src/os/unix/ngx_user.h)
    vendor/nginx-1.7.2/src/os/unix/ngx_writev_chain.c
      (from vendor/nginx-1.4.7/src/os/unix/ngx_writev_chain.c)
    vendor/nginx-1.7.2/src/os/unix/rfork_thread.S
      (from vendor/nginx-1.4.7/src/os/unix/rfork_thread.S)

  Modified: nginx_version (+1 -1)
===================================================================
--- nginx_version    2014-07-02 11:31:57 +0900 (be05bba)
+++ nginx_version    2014-07-04 15:15:55 +0900 (f8a696c)
@@ -1 +1 @@
-1.4.7
+1.7.2

  Renamed: vendor/nginx-1.7.2/CHANGES (+348 -19) 94%
===================================================================
--- vendor/nginx-1.4.7/CHANGES    2014-07-02 11:31:57 +0900 (4d9e62a)
+++ vendor/nginx-1.7.2/CHANGES    2014-07-04 15:15:55 +0900 (7a308e4)
@@ -1,5 +1,99 @@
 
-Changes with nginx 1.4.7                                         18 Mar 2014
+Changes with nginx 1.7.2                                         17 Jun 2014
+
+    *) Feature: the "hash" directive inside the "upstream" block.
+
+    *) Feature: defragmentation of free shared memory blocks.
+       Thanks to Wandenberg Peixoto and Yichun Zhang.
+
+    *) Bugfix: a segmentation fault might occur in a worker process if the
+       default value of the "access_log" directive was used; the bug had
+       appeared in 1.7.0.
+       Thanks to Piotr Sikora.
+
+    *) Bugfix: trailing slash was mistakenly removed from the last parameter
+       of the "try_files" directive.
+
+    *) Bugfix: nginx could not be built on OS X in some cases.
+
+    *) Bugfix: in the ngx_http_spdy_module.
+
+
+Changes with nginx 1.7.1                                         27 May 2014
+
+    *) Feature: the "$upstream_cookie_..." variables.
+
+    *) Feature: the $ssl_client_fingerprint variable.
+
+    *) Feature: the "error_log" and "access_log" directives now support
+       logging to syslog.
+
+    *) Feature: the mail proxy now logs client port on connect.
+
+    *) Bugfix: memory leak if the "ssl_stapling" directive was used.
+       Thanks to Filipe da Silva.
+
+    *) Bugfix: the "alias" directive used inside a location given by a
+       regular expression worked incorrectly if the "if" or "limit_except"
+       directives were used.
+
+    *) Bugfix: the "charset" directive did not set a charset to encoded
+       backend responses.
+
+    *) Bugfix: a "proxy_pass" directive without URI part might use original
+       request after the $args variable was set.
+       Thanks to Yichun Zhang.
+
+    *) Bugfix: in the "none" parameter in the "smtp_auth" directive; the bug
+       had appeared in 1.5.6.
+       Thanks to Svyatoslav Nikolsky.
+
+    *) Bugfix: if sub_filter and SSI were used together, then responses
+       might be transferred incorrectly.
+
+    *) Bugfix: nginx could not be built with the --with-file-aio option on
+       Linux/aarch64.
+
+
+Changes with nginx 1.7.0                                         24 Apr 2014
+
+    *) Feature: backend SSL certificate verification.
+
+    *) Feature: support for SNI while working with SSL backends.
+
+    *) Feature: the $ssl_server_name variable.
+
+    *) Feature: the "if" parameter of the "access_log" directive.
+
+
+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
@@ -8,11 +102,23 @@ Changes with nginx 1.4.7                                         18 Mar 2014
        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.4.6                                         04 Mar 2014
+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
@@ -22,15 +128,71 @@ Changes with nginx 1.4.6                                         04 Mar 2014
     *) 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.
 
-Changes with nginx 1.4.5                                         11 Feb 2014
+    *) 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: client connections might be immediately closed if deferred
-       accept was used; the bug had appeared in 1.3.15.
+    *) 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.
@@ -41,53 +203,217 @@ Changes with nginx 1.4.5                                         11 Feb 2014
     *) 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: memory leak in nginx/Windows.
+    *) 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.4.4                                         19 Nov 2013
+
+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".
 
-Changes with nginx 1.4.3                                         08 Oct 2013
+    *) Feature: the "proxy_cache_revalidate", "fastcgi_cache_revalidate",
+       "scgi_cache_revalidate", and "uwsgi_cache_revalidate" directives.
 
-    *) 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.
+    *) Feature: the "ssl_session_ticket_key" directive.
+       Thanks to Piotr Sikora.
 
-    *) Bugfix: a segmentation fault might occur on start or during
-       reconfiguration if the "try_files" directive was used with an empty
-       parameter.
+    *) Bugfix: the directive "add_header Cache-Control ''" added a
+       "Cache-Control" response header line with an empty value.
 
-    *) Bugfix: the $request_time variable did not work in nginx/Windows.
+    *) 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 the ngx_http_autoindex_module.
+    *) 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.
 
-Changes with nginx 1.4.2                                         17 Jul 2013
+    *) 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.
@@ -96,11 +422,14 @@ Changes with nginx 1.4.2                                         17 Jul 2013
        "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.4.1                                         07 May 2013
+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
@@ -6097,7 +6426,7 @@ Changes with nginx 0.1.16                                        25 Jan 2005
     *) Bugfix: the compressed response encrypted by SSL may not transferred
        complete.
 
-    *) Bugfix: the TCP-specific TCP_NODELAY, TCP_NOPSUH, and TCP_CORK
+    *) 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.

  Renamed: vendor/nginx-1.7.2/CHANGES.ru (+360 -22) 94%
===================================================================
--- vendor/nginx-1.4.7/CHANGES.ru    2014-07-02 11:31:57 +0900 (2f9f301)
+++ vendor/nginx-1.7.2/CHANGES.ru    2014-07-04 15:15:55 +0900 (67ac3f5)
@@ -1,5 +1,102 @@
 
-Изменения в nginx 1.4.7                                           18.03.2014
+Изменения в nginx 1.7.2                                           17.06.2014
+
+    *) Добавление: директива hash в блоке upstream.
+
+    *) Добавление: дефрагментация свободных блоков разделяемой памяти.
+       Спасибо Wandenberg Peixoto и Yichun Zhang.
+
+    *) Исправление: в рабочем процессе мог произойти segmentation fault,
+       если использовалось значение access_log по умолчанию; ошибка
+       появилась в 1.7.0.
+       Спасибо Piotr Sikora.
+
+    *) Исправление: завершающий слэш ошибочно удалялся из последнего
+       параметра директивы try_files.
+
+    *) Исправление: nginx мог не собираться на OS X.
+
+    *) Исправление: в модуле ngx_http_spdy_module.
+
+
+Изменения в nginx 1.7.1                                           27.05.2014
+
+    *) Добавление: переменные "$upstream_cookie_...".
+
+    *) Добавление: переменная $ssl_client_fingerprint.
+
+    *) Добавление: директивы error_log и access_log теперь поддерживают
+       логгирование в syslog.
+
+    *) Добавление: почтовый прокси-сервер теперь логгирует порт клиента при
+       соединении.
+
+    *) Исправление: утечки памяти при использовании директивы
+       "ssl_stapling".
+       Спасибо Filipe da Silva.
+
+    *) Исправление: директива alias внутри location'а, заданного регулярным
+       выражением, работала неправильно, если использовались директивы if
+       или limit_except.
+
+    *) Исправление: директива charset не ставила кодировку для сжатых
+       ответов бэкендов.
+
+    *) Исправление: директива proxy_pass без URI могла использовать
+       оригинальный запрос после установки переменной $args.
+       Спасибо Yichun Zhang.
+
+    *) Исправление: в работе параметра none директивы smtp_auth; ошибка
+       появилась в 1.5.6.
+       Спасибо Святославу Никольскому.
+
+    *) Исправление: при совместном использовании sub_filter и SSI ответы
+       могли передаваться неверно.
+
+    *) Исправление: nginx не собирался с параметром --with-file-aio на
+       Linux/aarch64.
+
+
+Изменения в nginx 1.7.0                                           24.04.2014
+
+    *) Добавление: проверка SSL-сертификатов бэкендов.
+
+    *) Добавление: поддержка SNI при работе с бэкендами по SSL.
+
+    *) Добавление: переменная $ssl_server_name.
+
+    *) Добавление: параметр if директивы access_log.
+
+
+Изменения в 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 могло происходить переполнение буфера в рабочем
@@ -8,11 +105,24 @@
        Спасибо 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.4.6                                           04.03.2014
+Изменения в 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;
@@ -22,15 +132,74 @@
     *) Исправление: при проксировании 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 теперь пропускает дорожки,
+       имеющие меньшую длину, чем запрошенная перемотка.
 
-Изменения в nginx 1.4.5                                           11.02.2014
+    *) Исправление: в рабочем процессе мог произойти 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ć.
 
-    *) Исправление: клиентские соединения могли сразу закрываться, если
-       использовался отложенный accept; ошибка появилась в 1.3.15.
+    *) Исправление: nginx неправильно обрабатывал закодированный символ "?"
+       в команде SSI include.
+
+    *) Исправление: модуль ngx_http_dav_module не раскодировал целевой URI
+       при обработке методов COPY и MOVE.
+
+    *) Исправление: resolver не понимал доменные имена с точкой в конце.
+       Спасибо Yichun Zhang.
 
     *) Исправление: при проксировании в логах могли появляться сообщения
        "zero size buf in output"; ошибка появилась в 1.3.9.
@@ -42,53 +211,219 @@
        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-соединению мог произойти таймаут.
 
-    *) Исправление: утечки памяти в nginx/Windows.
+    *) Исправление: директива master_process работала неправильно в
+       nginx/Windows.
+
+    *) Исправление: параметр setfib директивы listen мог не работать.
+
+    *) Исправление: в модуле ngx_http_spdy_module.
 
 
-Изменения в nginx 1.4.4                                           19.11.2013
+Изменения в nginx 1.5.7                                           19.11.2013
 
     *) Безопасность: символ, следующий за незакодированным пробелом в строке
        запроса, обрабатывался неправильно (CVE-2013-4547); ошибка появилась
        в 0.8.41.
        Спасибо Ivan Fratric из Google Security Team.
 
+    *) Изменение: уровень логгирования ошибок auth_basic об отсутствии
+       пароля понижен с уровня error до info.
 
-Изменения в nginx 1.4.3                                           08.10.2013
+    *) Добавление: директивы proxy_cache_revalidate,
+       fastcgi_cache_revalidate, scgi_cache_revalidate и
+       uwsgi_cache_revalidate.
 
-    *) Исправление: в рабочем процессе мог произойти segmentation fault,
-       если использовался модуль ngx_http_spdy_module и директива
-       client_body_in_file_only.
+    *) Добавление: директива ssl_session_ticket_key.
+       Спасибо Piotr Sikora.
 
-    *) Исправление: на старте или во время переконфигурации мог произойти
-       segmentation fault, если использовалась директива try_files с пустым
-       параметром.
+    *) Исправление: директива "add_header Cache-Control ''" добавляла строку
+       заголовка ответа "Cache-Control" с пустым значением.
 
-    *) Исправление: переменная $request_time не работала в nginx/Windows.
+    *) Исправление: директива "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.
 
-    *) Исправление: в модуле ngx_http_autoindex_module.
+    *) Исправление: на 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 относительных путей, заданных с помощью
+       переменных.
 
-Изменения в nginx 1.4.2                                           17.07.2013
+    *) Исправление: директива 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.
@@ -97,11 +432,14 @@
        если использовалась директива ssl_stapling.
        Спасибо Piotr Sikora.
 
+    *) Исправление: в почтовом прокси-сервере.
+       Спасибо Filipe Da Silva.
+
     *) Исправление: nginx/Windows мог перестать принимать соединения, если
        использовалось несколько рабочих процессов.
 
 
-Изменения в nginx 1.4.1                                           07.05.2013
+Изменения в nginx 1.5.0                                           07.05.2013
 
     *) Безопасность: при обработке специально созданного запроса мог
        перезаписываться стек рабочего процесса, что могло приводить к
@@ -427,7 +765,7 @@
     *) Изменение: параметр single директивы keepalive теперь игнорируется.
 
     *) Изменение: сжатие SSL теперь отключено в том числе при использовании
-       OpenSSL cтарее 1.0.0.
+       OpenSSL старее 1.0.0.
 
     *) Добавление: директиву "ip_hash" теперь можно использовать для
        балансировки IPv6 клиентов.
@@ -2704,7 +3042,7 @@
        умолчанию; ошибка появилась в 0.7.18.
        Спасибо Максиму Дунину.
 
-    *) Исправление: при проксировании SMPT nginx выдавал сообщение
+    *) Исправление: при проксировании SMTP nginx выдавал сообщение
        "250 2.0.0 OK" вместо "235 2.0.0 OK"; ошибка появилась в 0.7.22.
        Спасибо Максиму Дунину.
 
@@ -6190,7 +6528,7 @@
     *) Исправление: при использовании SSL сжатый ответ мог передаваться не
        до конца.
 
-    *) Исправление: опции TCP_NODELAY, TCP_NOPSUH и TCP_CORK, специфичные
+    *) Исправление: опции TCP_NODELAY, TCP_NOPUSH и TCP_CORK, специфичные
        для TCP сокетов, не используются для unix domain сокетов.
 
     *) Добавление: директива rewrite поддерживает перезаписывание
@@ -6254,7 +6592,7 @@
     *) Изменение: если в URI встречался символ %3F, то он считался началом
        строки аргументов.
 
-    *) Добавление: поддержка unix domain сoкетов в модуле
+    *) Добавление: поддержка unix domain сокетов в модуле
        ngx_http_proxy_module.
 
     *) Добавление: директивы ssl_engine и ssl_ciphers.

  Renamed: vendor/nginx-1.7.2/LICENSE (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/README (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/cc/acc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/cc/bcc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/cc/ccc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/cc/clang (+9 -3) 82%
===================================================================
--- vendor/nginx-1.4.7/auto/cc/clang    2014-07-02 11:31:57 +0900 (9f60d7b)
+++ vendor/nginx-1.7.2/auto/cc/clang    2014-07-04 15:15:55 +0900 (25707b4)
@@ -5,8 +5,8 @@
 # clang
 
 
-NGX_CLANG_VER=`$CC -v 2>&1 | grep 'clang version' 2>&1 \
-                           | sed -e 's/^.*clang version \(.*\)/\1/'`
+NGX_CLANG_VER=`$CC -v 2>&1 | grep '\(clang\|LLVM\) version' 2>&1 \
+                           | sed -e 's/^.* version \(.*\)/\1/'`
 
 echo " + clang version: $NGX_CLANG_VER"
 
@@ -82,13 +82,19 @@ 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"
 
+# deprecated system OpenSSL library on OS X
+if [ "$NGX_SYSTEM" = "Darwin" ]; then
+    CFLAGS="$CFLAGS -Wno-deprecated-declarations"
+fi
+
 # stop on warning
-#CFLAGS="$CFLAGS -Werror"
+CFLAGS="$CFLAGS -Werror"
 
 # debug
 CFLAGS="$CFLAGS -g"

  Renamed: vendor/nginx-1.7.2/auto/cc/conf (+23 -0) 89%
===================================================================
--- vendor/nginx-1.4.7/auto/cc/conf    2014-07-02 11:31:57 +0900 (8027b98)
+++ vendor/nginx-1.7.2/auto/cc/conf    2014-07-04 15:15:55 +0900 (edc6d74)
@@ -43,6 +43,29 @@ if test -n "$CFLAGS"; then
             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

  Renamed: vendor/nginx-1.7.2/auto/cc/gcc (+5 -0) 95%
===================================================================
--- vendor/nginx-1.4.7/auto/cc/gcc    2014-07-02 11:31:57 +0900 (c27d857)
+++ vendor/nginx-1.7.2/auto/cc/gcc    2014-07-04 15:15:55 +0900 (727f11e)
@@ -158,6 +158,11 @@ case "$NGX_GCC_VER" in
         CFLAGS="$CFLAGS -Wno-unused-parameter"
         # 4.2.1 shows the warning in wrong places
         #CFLAGS="$CFLAGS -Wunreachable-code"
+
+        # deprecated system OpenSSL library on OS X
+        if [ "$NGX_SYSTEM" = "Darwin" ]; then
+            CFLAGS="$CFLAGS -Wno-deprecated-declarations"
+        fi
     ;;
 
     *)

  Renamed: vendor/nginx-1.7.2/auto/cc/icc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/cc/msvc (+1 -0) 98%
===================================================================
--- vendor/nginx-1.4.7/auto/cc/msvc    2014-07-02 11:31:57 +0900 (1bf675e)
+++ vendor/nginx-1.7.2/auto/cc/msvc    2014-07-04 15:15:55 +0900 (393ba32)
@@ -106,6 +106,7 @@ 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"

  Renamed: vendor/nginx-1.7.2/auto/cc/name (+1 -1) 96%
===================================================================
--- vendor/nginx-1.4.7/auto/cc/name    2014-07-02 11:31:57 +0900 (7a5656c)
+++ vendor/nginx-1.7.2/auto/cc/name    2014-07-04 15:15:55 +0900 (51a7ed9)
@@ -67,7 +67,7 @@ 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 version' >/dev/null 2>&1`; then
+elif `$CC -v 2>&1 | grep '\(clang\|LLVM\) version' >/dev/null 2>&1`; then
     NGX_CC_NAME=clang
     echo " + using Clang C compiler"
 

  Renamed: vendor/nginx-1.7.2/auto/cc/owc (+4 -4) 90%
===================================================================
--- vendor/nginx-1.4.7/auto/cc/owc    2014-07-02 11:31:57 +0900 (22eb4c1)
+++ vendor/nginx-1.7.2/auto/cc/owc    2014-07-04 15:15:55 +0900 (a063aa3)
@@ -65,10 +65,10 @@ 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"
+#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

  Renamed: vendor/nginx-1.7.2/auto/cc/sunc (+1 -1) 99%
===================================================================
--- vendor/nginx-1.4.7/auto/cc/sunc    2014-07-02 11:31:57 +0900 (dd9cced)
+++ vendor/nginx-1.7.2/auto/cc/sunc    2014-07-04 15:15:55 +0900 (8f12d7c)
@@ -30,7 +30,7 @@ if [ -x $NGX_AUTOTEST ]; then
     ngx_sunc_ver=`$NGX_AUTOTEST`
 fi
 
-rm $NGX_AUTOTEST*
+rm -rf $NGX_AUTOTEST*
 
 # 1424 == 0x590, Sun Studio 12
 

  Renamed: vendor/nginx-1.7.2/auto/define (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/endianness (+2 -2) 93%
===================================================================
--- vendor/nginx-1.4.7/auto/endianness    2014-07-02 11:31:57 +0900 (87311a0)
+++ vendor/nginx-1.7.2/auto/endianness    2014-07-04 15:15:55 +0900 (93da2f8)
@@ -34,10 +34,10 @@ if [ -x $NGX_AUTOTEST ]; then
         echo " big endian"
     fi
 
-    rm $NGX_AUTOTEST*
+    rm -rf $NGX_AUTOTEST*
 
 else
-    rm $NGX_AUTOTEST*
+    rm -rf $NGX_AUTOTEST*
 
     echo
     echo "$0: error: cannot detect system byte ordering"

  Renamed: vendor/nginx-1.7.2/auto/feature (+1 -1) 99%
===================================================================
--- vendor/nginx-1.4.7/auto/feature    2014-07-02 11:31:57 +0900 (c13e51d)
+++ vendor/nginx-1.7.2/auto/feature    2014-07-04 15:15:55 +0900 (1145f28)
@@ -120,4 +120,4 @@ else
     echo "----------"    >> $NGX_AUTOCONF_ERR
 fi
 
-rm $NGX_AUTOTEST*
+rm -rf $NGX_AUTOTEST*

  Renamed: vendor/nginx-1.7.2/auto/have (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/have_headers (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/headers (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/include (+1 -1) 97%
===================================================================
--- vendor/nginx-1.4.7/auto/include    2014-07-02 11:31:57 +0900 (3466fda)
+++ vendor/nginx-1.7.2/auto/include    2014-07-04 15:15:55 +0900 (e34dabd)
@@ -58,4 +58,4 @@ else
     echo "----------"    >> $NGX_AUTOCONF_ERR
 fi
 
-rm $NGX_AUTOTEST*
+rm -rf $NGX_AUTOTEST*

  Renamed: vendor/nginx-1.7.2/auto/init (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/install (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/conf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/geoip/conf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/google-perftools/conf (+1 -1) 93%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/google-perftools/conf    2014-07-02 11:31:57 +0900 (7a9de30)
+++ vendor/nginx-1.7.2/auto/lib/google-perftools/conf    2014-07-04 15:15:55 +0900 (5d5ddae)
@@ -52,7 +52,7 @@ else
 
 cat << END
 
-$0: error: the Google perftool module requires the Google perftools
+$0: error: the Google perftools module requires the Google perftools
 library. You can either do not enable the module or install the library.
 
 END

  Renamed: vendor/nginx-1.7.2/auto/lib/libatomic/conf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/libatomic/make (+3 -1) 74%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/libatomic/make    2014-07-02 11:31:57 +0900 (023ed18)
+++ vendor/nginx-1.7.2/auto/lib/libatomic/make    2014-07-04 15:15:55 +0900 (c90318e)
@@ -9,6 +9,8 @@ $NGX_LIBATOMIC/src/libatomic_ops.a:	$NGX_LIBATOMIC/Makefile
 	cd $NGX_LIBATOMIC && \$(MAKE)
 
 $NGX_LIBATOMIC/Makefile:	$NGX_MAKEFILE
-	cd $NGX_LIBATOMIC && ./configure
+	cd $NGX_LIBATOMIC \\
+	&& if [ -f Makefile ]; then \$(MAKE) distclean; fi \\
+	&& ./configure
 
 END

  Renamed: vendor/nginx-1.7.2/auto/lib/libgd/conf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/libxslt/conf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/make (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/md5/conf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/md5/make (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/md5/makefile.bcc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/md5/makefile.msvc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/md5/makefile.owc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/openssl/conf (+4 -0) 93%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/openssl/conf    2014-07-02 11:31:57 +0900 (528ee17)
+++ vendor/nginx-1.7.2/auto/lib/openssl/conf    2014-07-04 15:15:55 +0900 (a65815f)
@@ -33,6 +33,10 @@ if [ $OPENSSL != NONE ]; then
             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
 

  Renamed: vendor/nginx-1.7.2/auto/lib/openssl/make (+1 -1) 96%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/openssl/make    2014-07-02 11:31:57 +0900 (9090fcb)
+++ vendor/nginx-1.7.2/auto/lib/openssl/make    2014-07-04 15:15:55 +0900 (e64acd9)
@@ -55,7 +55,7 @@ END
 
 $OPENSSL/.openssl/include/openssl/ssl.h:	$NGX_MAKEFILE
 	cd $OPENSSL \\
-	&& \$(MAKE) clean \\
+	&& if [ -f Makefile ]; then \$(MAKE) clean; fi \\
 	&& ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\
 	&& \$(MAKE) \\
 	&& \$(MAKE) install LIBDIR=lib

  Renamed: vendor/nginx-1.7.2/auto/lib/openssl/makefile.bcc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/openssl/makefile.msvc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/pcre/conf (+5 -0) 98%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/pcre/conf    2014-07-02 11:31:57 +0900 (3458600)
+++ vendor/nginx-1.7.2/auto/lib/pcre/conf    2014-07-04 15:15:55 +0900 (939f01b)
@@ -73,6 +73,11 @@ if [ $PCRE != NONE ]; then
 
         *)
             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"

  Renamed: vendor/nginx-1.7.2/auto/lib/pcre/make (+11 -11) 79%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/pcre/make    2014-07-02 11:31:57 +0900 (834779b)
+++ vendor/nginx-1.7.2/auto/lib/pcre/make    2014-07-04 15:15:55 +0900 (0a27a11)
@@ -23,16 +23,19 @@ case "$NGX_CC_NAME" in
         ngx_pcre=`echo \-DPCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"`
     ;;
 
-esac
+    *)
+        ngx_makefile=
+    ;;
 
+esac
 
-case "$NGX_PLATFORM" in
 
-    win32)
+if [ -n "$ngx_makefile" ]; then
 
-        cat << END                                            >> $NGX_MAKEFILE
+    cat << END                                                >> $NGX_MAKEFILE
 
-`echo "$PCRE/pcre.lib:	$NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"`
+`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"`
@@ -40,10 +43,9 @@ case "$NGX_PLATFORM" in
 
 END
 
-    ;;
+else
 
-    *)
-        cat << END                                            >> $NGX_MAKEFILE
+    cat << END                                                >> $NGX_MAKEFILE
 
 $PCRE/pcre.h:	$PCRE/Makefile
 
@@ -59,6 +61,4 @@ $PCRE/.libs/libpcre.a:	$PCRE/Makefile
 
 END
 
-    ;;
-
-esac
+fi

  Renamed: vendor/nginx-1.7.2/auto/lib/pcre/makefile.bcc (+4 -3) 79%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/pcre/makefile.bcc    2014-07-02 11:31:57 +0900 (1c140d6)
+++ vendor/nginx-1.7.2/auto/lib/pcre/makefile.bcc    2014-07-04 15:15:55 +0900 (7a0f2be)
@@ -4,7 +4,8 @@
 
 
 CFLAGS =	-q -O2 -tWM -w-8004 $(CPU_OPT)
-PCREFLAGS =	-DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10
+PCREFLAGS =	-DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10 \
+		-DSUPPORT_PCRE8 -DHAVE_MEMMOVE
 
 
 pcre.lib:
@@ -12,8 +13,8 @@ pcre.lib:
 
 	bcc32 -c $(CFLAGS) -I. $(PCREFLAGS) pcre_*.c
 
-	> pcre.lst
-	for %n in (*.obj) do @echo +%n & >> pcre.lst
+	copy /y nul pcre.lst
+	for %n in (*.obj) do @echo +%n ^^& >> pcre.lst
 	echo + >> pcre.lst
 
 	tlib pcre.****@pcre*****

  Renamed: vendor/nginx-1.7.2/auto/lib/pcre/makefile.msvc (+2 -1) 91%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/pcre/makefile.msvc    2014-07-02 11:31:57 +0900 (7a8da71)
+++ vendor/nginx-1.7.2/auto/lib/pcre/makefile.msvc    2014-07-04 15:15:55 +0900 (07fd9a2)
@@ -4,7 +4,8 @@
 
 
 CFLAGS =	-O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT)
-PCREFLAGS =	-DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10
+PCREFLAGS =	-DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10 \
+		-DSUPPORT_PCRE8 -DHAVE_MEMMOVE
 
 
 pcre.lib:

  Renamed: vendor/nginx-1.7.2/auto/lib/pcre/makefile.owc (+2 -1) 91%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/pcre/makefile.owc    2014-07-02 11:31:57 +0900 (bfb6920)
+++ vendor/nginx-1.7.2/auto/lib/pcre/makefile.owc    2014-07-04 15:15:55 +0900 (122fd5b)
@@ -4,7 +4,8 @@
 
 
 CFLAGS =	-c -zq -bt=nt -ot -op -oi -oe -s -bm $(CPU_OPT)
-PCREFLAGS =	-DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10
+PCREFLAGS =	-DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10 &
+		-DSUPPORT_PCRE8 -DHAVE_MEMMOVE
 
 
 pcre.lib:

  Renamed: vendor/nginx-1.7.2/auto/lib/perl/conf (+5 -0) 91%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/perl/conf    2014-07-02 11:31:57 +0900 (2fbaa76)
+++ vendor/nginx-1.7.2/auto/lib/perl/conf    2014-07-04 15:15:55 +0900 (91009f1)
@@ -52,6 +52,11 @@ if test -n "$NGX_PERL_VER"; then
         ngx_perl_ldopts=`echo $ngx_perl_ldopts | sed 's/ -pthread//'`
     fi
 
+    if [ "$NGX_SYSTEM" = "Darwin" ]; then
+        # OS X system perl wants to link universal binaries
+        ngx_perl_ldopts=`echo $ngx_perl_ldopts | sed -e 's/-arch x86_64 -arch i386//'`
+    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"
 

  Renamed: vendor/nginx-1.7.2/auto/lib/perl/make (+1 -0) 98%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/perl/make    2014-07-02 11:31:57 +0900 (260bd95)
+++ vendor/nginx-1.7.2/auto/lib/perl/make    2014-07-04 15:15:55 +0900 (d1c1b9e)
@@ -18,6 +18,7 @@ $NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.$ngx_perl_dlext: \\
 
 
 $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 \\

  Renamed: vendor/nginx-1.7.2/auto/lib/sha1/conf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/sha1/make (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/sha1/makefile.bcc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/sha1/makefile.msvc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/sha1/makefile.owc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/test (+1 -1) 96%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/test    2014-07-02 11:31:57 +0900 (907e235)
+++ vendor/nginx-1.7.2/auto/lib/test    2014-07-04 15:15:55 +0900 (ba943a2)
@@ -37,4 +37,4 @@ else
     echo " not found"
 fi
 
-rm $NGX_AUTOTEST*
+rm -rf $NGX_AUTOTEST*

  Renamed: vendor/nginx-1.7.2/auto/lib/zlib/conf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/zlib/make (+22 -1) 84%
===================================================================
--- vendor/nginx-1.4.7/auto/lib/zlib/make    2014-07-02 11:31:57 +0900 (9401a1d)
+++ vendor/nginx-1.7.2/auto/lib/zlib/make    2014-07-04 15:15:55 +0900 (7875ef6)
@@ -24,6 +24,10 @@ case "$NGX_CC_NAME" in
         ngx_zlib=`echo \-DZLIB=\"$ZLIB\" | sed -e "s/\//$ngx_regex_dirsep/g"`
     ;;
 
+    *)
+        ngx_makefile=
+    ;;
+
 esac
 
 
@@ -33,13 +37,30 @@ done=NO
 case "$NGX_PLATFORM" in
 
     win32)
-        cat << END                                            >> $NGX_MAKEFILE
+
+        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
     ;;
 

  Renamed: vendor/nginx-1.7.2/auto/lib/zlib/makefile.bcc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/zlib/makefile.msvc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/zlib/makefile.owc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/lib/zlib/patch.zlib.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/make (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/modules (+13 -0) 97%
===================================================================
--- vendor/nginx-1.4.7/auto/modules    2014-07-02 11:31:57 +0900 (a78e785)
+++ vendor/nginx-1.7.2/auto/modules    2014-07-04 15:15:55 +0900 (7885967)
@@ -42,6 +42,7 @@ 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"
@@ -220,6 +221,11 @@ if [ $HTTP_RANDOM_INDEX = YES ]; then
     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
@@ -365,6 +371,11 @@ if [ $HTTP_MP4 = YES ]; then
     HTTP_SRCS="$HTTP_SRCS $HTTP_MP4_SRCS"
 fi
 
+if [ $HTTP_UPSTREAM_HASH = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_HASH_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_HASH_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"
@@ -477,6 +488,8 @@ if [ $MAIL = YES ]; then
 
     modules="$modules $MAIL_PROXY_MODULE"
     MAIL_SRCS="$MAIL_SRCS $MAIL_PROXY_SRCS"
+
+    NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(MAIL_DEPS)"
 fi
 
 

  Renamed: vendor/nginx-1.7.2/auto/nohave (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/options (+10 -0) 97%
===================================================================
--- vendor/nginx-1.4.7/auto/options    2014-07-02 11:31:57 +0900 (6713379)
+++ vendor/nginx-1.7.2/auto/options    2014-07-04 15:15:55 +0900 (0d296ac)
@@ -14,6 +14,7 @@ NGX_PID_PATH=
 NGX_LOCK_PATH=
 NGX_USER=
 NGX_GROUP=
+NGX_BUILD=
 
 CC=${CC:-cc}
 CPP=
@@ -71,6 +72,7 @@ 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
@@ -97,6 +99,7 @@ HTTP_FLV=NO
 HTTP_MP4=NO
 HTTP_GUNZIP=NO
 HTTP_GZIP_STATIC=NO
+HTTP_UPSTREAM_HASH=YES
 HTTP_UPSTREAM_IP_HASH=YES
 HTTP_UPSTREAM_LEAST_CONN=YES
 HTTP_UPSTREAM_KEEPALIVE=YES
@@ -177,6 +180,7 @@ do
 
         --crossbuild=*)                  NGX_PLATFORM="$value"      ;;
 
+        --build=*)                       NGX_BUILD="$value"         ;;
         --builddir=*)                    NGX_OBJS="$value"          ;;
 
         --with-rtsig_module)             EVENT_RTSIG=YES            ;;
@@ -215,6 +219,7 @@ do
         --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       ;;
@@ -247,6 +252,7 @@ use the \"--without-http_limit_conn_module\" option instead"
         --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_hash_module) HTTP_UPSTREAM_HASH=NO  ;;
         --without-http_upstream_ip_hash_module) HTTP_UPSTREAM_IP_HASH=NO ;;
         --without-http_upstream_least_conn_module)
                                          HTTP_UPSTREAM_LEAST_CONN=NO ;;
@@ -339,6 +345,7 @@ cat << END
   --group=GROUP                      set non-privileged group for
                                      worker processes
 
+  --build=NAME                       set build name
   --builddir=DIR                     set build directory
 
   --with-rtsig_module                enable rtsig module
@@ -363,6 +370,7 @@ cat << END
   --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
@@ -389,6 +397,8 @@ cat << END
   --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_hash_module
+                                     disable ngx_http_upstream_hash_module
   --without-http_upstream_ip_hash_module
                                      disable ngx_http_upstream_ip_hash_module
   --without-http_upstream_least_conn_module

  Renamed: vendor/nginx-1.7.2/auto/os/conf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/os/darwin (+1 -1) 97%
===================================================================
--- vendor/nginx-1.4.7/auto/os/darwin    2014-07-02 11:31:57 +0900 (590e036)
+++ vendor/nginx-1.7.2/auto/os/darwin    2014-07-04 15:15:55 +0900 (b97518a)
@@ -112,5 +112,5 @@ 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)"
+                  n = OSAtomicCompareAndSwap32Barrier(0, 1, &lock)"
 . auto/feature

  Renamed: vendor/nginx-1.7.2/auto/os/freebsd (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/os/linux (+32 -0) 78%
===================================================================
--- vendor/nginx-1.4.7/auto/os/linux    2014-07-02 11:31:57 +0900 (c506d3d)
+++ vendor/nginx-1.7.2/auto/os/linux    2014-07-04 15:15:55 +0900 (19bf832)
@@ -65,9 +65,41 @@ if [ $ngx_found = yes ]; then
     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"

  Renamed: vendor/nginx-1.7.2/auto/os/solaris (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/os/win32 (+12 -1) 77%
===================================================================
--- vendor/nginx-1.4.7/auto/os/win32    2014-07-02 11:31:57 +0900 (21a54ba)
+++ vendor/nginx-1.7.2/auto/os/win32    2014-07-04 15:15:55 +0900 (0b9b461)
@@ -9,10 +9,21 @@ CORE_INCS="$WIN32_INCS"
 CORE_DEPS="$WIN32_DEPS"
 CORE_SRCS="$WIN32_SRCS $IOCP_SRCS"
 OS_CONFIG="$WIN32_CONFIG"
-CORE_LIBS="$CORE_LIBS advapi32.lib ws2_32.lib"
 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
 

  Renamed: vendor/nginx-1.7.2/auto/sources (+14 -2) 97%
===================================================================
--- vendor/nginx-1.4.7/auto/sources    2014-07-02 11:31:57 +0900 (90465c3)
+++ vendor/nginx-1.7.2/auto/sources    2014-07-04 15:15:55 +0900 (1287782)
@@ -36,7 +36,9 @@ CORE_DEPS="src/core/nginx.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_crypt.h \
+           src/core/ngx_proxy_protocol.h \
+           src/core/ngx_syslog.h"
 
 
 CORE_SRCS="src/core/nginx.c \
@@ -67,7 +69,9 @@ CORE_SRCS="src/core/nginx.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_crypt.c \
+           src/core/ngx_proxy_protocol.c \
+           src/core/ngx_syslog.c"
 
 
 REGEX_MODULE=ngx_regex_module
@@ -386,6 +390,10 @@ 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
 
@@ -489,6 +497,10 @@ HTTP_GZIP_STATIC_MODULE=ngx_http_gzip_static_module
 HTTP_GZIP_STATIC_SRCS=src/http/modules/ngx_http_gzip_static_module.c
 
 
+HTTP_UPSTREAM_HASH_MODULE=ngx_http_upstream_hash_module
+HTTP_UPSTREAM_HASH_SRCS=src/http/modules/ngx_http_upstream_hash_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
 

  Renamed: vendor/nginx-1.7.2/auto/stubs (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/summary (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/types/sizeof (+1 -1) 98%
===================================================================
--- vendor/nginx-1.4.7/auto/types/sizeof    2014-07-02 11:31:57 +0900 (e1d405c)
+++ vendor/nginx-1.7.2/auto/types/sizeof    2014-07-04 15:15:55 +0900 (9215a54)
@@ -45,7 +45,7 @@ if [ -x $NGX_AUTOTEST ]; then
 fi
 
 
-rm -f $NGX_AUTOTEST
+rm -rf $NGX_AUTOTEST*
 
 
 case $ngx_size in

  Renamed: vendor/nginx-1.7.2/auto/types/typedef (+1 -1) 98%
===================================================================
--- vendor/nginx-1.4.7/auto/types/typedef    2014-07-02 11:31:57 +0900 (d812293)
+++ vendor/nginx-1.7.2/auto/types/typedef    2014-07-04 15:15:55 +0900 (8b5c368)
@@ -49,7 +49,7 @@ END
         fi
     fi
 
-    rm -f $NGX_AUTOTEST
+    rm -rf $NGX_AUTOTEST*
 
     if [ $ngx_found = no ]; then
         echo $ngx_n " $ngx_try not found$ngx_c"

  Renamed: vendor/nginx-1.7.2/auto/types/uintptr_t (+1 -1) 97%
===================================================================
--- vendor/nginx-1.4.7/auto/types/uintptr_t    2014-07-02 11:31:57 +0900 (2f19080)
+++ vendor/nginx-1.7.2/auto/types/uintptr_t    2014-07-04 15:15:55 +0900 (f3cdccb)
@@ -33,7 +33,7 @@ else
     echo $ngx_n " uintptr_t not found" $ngx_c
 fi
 
-rm $NGX_AUTOTEST*
+rm -rf $NGX_AUTOTEST*
 
 
 if [ $found = no ]; then

  Renamed: vendor/nginx-1.7.2/auto/types/value (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/auto/unix (+40 -7) 94%
===================================================================
--- vendor/nginx-1.4.7/auto/unix    2014-07-02 11:31:57 +0900 (cd4209e)
+++ vendor/nginx-1.7.2/auto/unix    2014-07-04 15:15:55 +0900 (9b4764c)
@@ -330,7 +330,7 @@ ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_DEFER_ACCEPT, NULL, 0)"
 . auto/feature
 
 
-ngx_feature="TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT"
+ngx_feature="TCP_KEEPIDLE"
 ngx_feature_name="NGX_HAVE_KEEPALIVE_TUNABLE"
 ngx_feature_run=no
 ngx_feature_incs="#include <sys/socket.h>
@@ -344,6 +344,18 @@ ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_KEEPIDLE, 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
@@ -386,16 +398,36 @@ if [ $NGX_FILE_AIO = YES ]; then
 
     if [ $ngx_found = yes ]; then
         CORE_SRCS="$CORE_SRCS $FILE_AIO_SRCS"
+    fi
 
-    elif [ $ngx_found = no ]; then
+    if [ $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>"
+                          #include <sys/eventfd.h>"
         ngx_feature_path=
         ngx_feature_libs=
+        ngx_feature_test="struct iocb  iocb;
+                          iocb.aio_lio_opcode = IOCB_CMD_PREAD;
+                          iocb.aio_flags = IOCB_FLAG_RESFD;
+                          iocb.aio_resfd = -1;
+                          (void) eventfd(0, 0)"
+        . auto/feature
+
+        if [ $ngx_found = yes ]; then
+            have=NGX_HAVE_EVENTFD . auto/have
+            have=NGX_HAVE_SYS_EVENTFD_H . auto/have
+            CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS"
+        fi
+    fi
+
+    if [ $ngx_found = no ]; then
+
+        ngx_feature="Linux AIO support (SYS_eventfd)"
+        ngx_feature_incs="#include <linux/aio_abi.h>
+                          #include <sys/syscall.h>"
         ngx_feature_test="int  n = SYS_eventfd;
                           struct iocb  iocb;
                           iocb.aio_lio_opcode = IOCB_CMD_PREAD;
@@ -406,16 +438,17 @@ if [ $NGX_FILE_AIO = YES ]; then
         if [ $ngx_found = yes ]; then
             have=NGX_HAVE_EVENTFD . auto/have
             CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS"
+        fi
+    fi
 
-        else
-            cat << END
+    if [ $ngx_found = no ]; then
+        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
+        exit 1
     fi
 fi
 

  Renamed: vendor/nginx-1.7.2/conf/fastcgi.conf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/conf/fastcgi_params (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/conf/koi-utf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/conf/koi-win (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/conf/mime.types (+11 -2) 85%
===================================================================
--- vendor/nginx-1.4.7/conf/mime.types    2014-07-02 11:31:57 +0900 (8a218b2)
+++ vendor/nginx-1.7.2/conf/mime.types    2014-07-04 15:15:55 +0900 (89be9a4)
@@ -5,7 +5,7 @@ types {
     text/xml                              xml;
     image/gif                             gif;
     image/jpeg                            jpeg jpg;
-    application/x-javascript              js;
+    application/javascript                js;
     application/atom+xml                  atom;
     application/rss+xml                   rss;
 
@@ -24,13 +24,17 @@ types {
     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;
@@ -51,15 +55,19 @@ types {
     application/x-x509-ca-cert            der pem crt;
     application/x-xpinstall               xpi;
     application/xhtml+xml                 xhtml;
+    application/xspf+xml                  xspf;
     application/zip                       zip;
 
     application/octet-stream              bin exe dll;
     application/octet-stream              deb;
     application/octet-stream              dmg;
-    application/octet-stream              eot;
     application/octet-stream              iso img;
     application/octet-stream              msi msp msm;
 
+    application/vnd.openxmlformats-officedocument.wordprocessingml.document    docx;
+    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet          xlsx;
+    application/vnd.openxmlformats-officedocument.presentationml.presentation  pptx;
+
     audio/midi                            mid midi kar;
     audio/mpeg                            mp3;
     audio/ogg                             ogg;
@@ -67,6 +75,7 @@ types {
     audio/x-realaudio                     ra;
 
     video/3gpp                            3gpp 3gp;
+    video/mp2t                            ts;
     video/mp4                             mp4;
     video/mpeg                            mpeg mpg;
     video/quicktime                       mov;

  Renamed: vendor/nginx-1.7.2/conf/nginx.conf (+3 -4) 94%
===================================================================
--- vendor/nginx-1.4.7/conf/nginx.conf    2014-07-02 11:31:57 +0900 (3bb3389)
+++ vendor/nginx-1.7.2/conf/nginx.conf    2014-07-04 15:15:55 +0900 (29bc085)
@@ -96,18 +96,17 @@ http {
     # HTTPS server
     #
     #server {
-    #    listen       443;
+    #    listen       443 ssl;
     #    server_name  localhost;
 
-    #    ssl                  on;
     #    ssl_certificate      cert.pem;
     #    ssl_certificate_key  cert.key;
 
+    #    ssl_session_cache    shared:SSL:1m;
     #    ssl_session_timeout  5m;
 
-    #    ssl_protocols  SSLv2 SSLv3 TLSv1;
     #    ssl_ciphers  HIGH:!aNULL:!MD5;
-    #    ssl_prefer_server_ciphers   on;
+    #    ssl_prefer_server_ciphers  on;
 
     #    location / {
     #        root   html;

  Renamed: vendor/nginx-1.7.2/conf/scgi_params (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/conf/uwsgi_params (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/conf/win-utf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/configure (+4 -0) 96%
===================================================================
--- vendor/nginx-1.4.7/configure    2014-07-02 11:31:57 +0900 (d7d8189)
+++ vendor/nginx-1.7.2/configure    2014-07-04 15:15:55 +0900 (e8929b8)
@@ -108,4 +108,8 @@ have=NGX_HTTP_SCGI_TEMP_PATH value="\"$NGX_HTTP_SCGI_TEMP_PATH\""
 have=NGX_USER value="\"$NGX_USER\"" . auto/define
 have=NGX_GROUP value="\"$NGX_GROUP\"" . auto/define
 
+if [ ".$NGX_BUILD" != "." ]; then
+    have=NGX_BUILD value="\"$NGX_BUILD\"" . auto/define
+fi
+
 . auto/summary

  Renamed: vendor/nginx-1.7.2/contrib/README (+6 -0) 80%
===================================================================
--- vendor/nginx-1.4.7/contrib/README    2014-07-02 11:31:57 +0900 (094aa52)
+++ vendor/nginx-1.7.2/contrib/README    2014-07-04 15:15:55 +0900 (fec4b20)
@@ -13,3 +13,9 @@ unicode2nginx		by Maxim Dounin
 	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/.
+

  Renamed: vendor/nginx-1.7.2/contrib/geo2nginx.pl (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/contrib/unicode2nginx/koi-utf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/contrib/unicode2nginx/unicode-to-nginx.pl (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/contrib/unicode2nginx/win-utf (+0 -0) 100%
===================================================================

  Added: vendor/nginx-1.7.2/contrib/vim/ftdetect/nginx.vim (+4 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.7.2/contrib/vim/ftdetect/nginx.vim    2014-07-04 15:15:55 +0900 (3ae470d)
@@ -0,0 +1,4 @@
+au BufRead,BufNewFile *.nginx set ft=nginx
+au BufRead,BufNewFile */etc/nginx/* set ft=nginx
+au BufRead,BufNewFile */usr/local/nginx/conf/* set ft=nginx
+au BufRead,BufNewFile nginx.conf set ft=nginx

  Added: vendor/nginx-1.7.2/contrib/vim/indent/nginx.vim (+11 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.7.2/contrib/vim/indent/nginx.vim    2014-07-04 15:15:55 +0900 (8601366)
@@ -0,0 +1,11 @@
+if exists("b:did_indent")
+    finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=
+
+" cindent actually works for nginx' simple file structure
+setlocal cindent
+" Just make sure that the comments are not reset as defs would be.
+setlocal cinkeys-=0#

  Added: vendor/nginx-1.7.2/contrib/vim/syntax/nginx.vim (+703 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.7.2/contrib/vim/syntax/nginx.vim    2014-07-04 15:15:55 +0900 (50d809b)
@@ -0,0 +1,703 @@
+" Vim syntax file
+" Language: nginx.conf
+
+if exists("b:current_syntax")
+  finish
+end
+
+setlocal iskeyword+=.
+setlocal iskeyword+=/
+setlocal iskeyword+=:
+
+syn match ngxVariable '\$\(\w\+\|{\w\+}\)'
+syn match ngxVariableBlock '\$\(\w\+\|{\w\+}\)' contained
+syn match ngxVariableString '\$\(\w\+\|{\w\+}\)' contained
+syn region ngxBlock start=+^+ end=+{+ skip=+\${+ contains=ngxComment,ngxDirectiveBlock,ngxVariableBlock,ngxString oneline
+syn region ngxString start=+\z(["']\)+ end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString
+syn match ngxComment ' *#.*$'
+
+syn keyword ngxBoolean on
+syn keyword ngxBoolean off
+
+syn keyword ngxDirectiveBlock http         contained
+syn keyword ngxDirectiveBlock mail         contained
+syn keyword ngxDirectiveBlock events       contained
+syn keyword ngxDirectiveBlock server       contained
+syn keyword ngxDirectiveBlock types        contained
+syn keyword ngxDirectiveBlock location     contained
+syn keyword ngxDirectiveBlock upstream     contained
+syn keyword ngxDirectiveBlock charset_map  contained
+syn keyword ngxDirectiveBlock limit_except contained
+syn keyword ngxDirectiveBlock if           contained
+syn keyword ngxDirectiveBlock geo          contained
+syn keyword ngxDirectiveBlock map          contained
+
+syn keyword ngxDirectiveImportant include
+syn keyword ngxDirectiveImportant root
+syn keyword ngxDirectiveImportant server
+syn keyword ngxDirectiveImportant server_name
+syn keyword ngxDirectiveImportant listen
+syn keyword ngxDirectiveImportant internal
+syn keyword ngxDirectiveImportant proxy_pass
+syn keyword ngxDirectiveImportant memcached_pass
+syn keyword ngxDirectiveImportant fastcgi_pass
+syn keyword ngxDirectiveImportant try_files
+
+syn keyword ngxDirectiveControl break
+syn keyword ngxDirectiveControl return
+syn keyword ngxDirectiveControl rewrite
+syn keyword ngxDirectiveControl set
+
+syn keyword ngxDirectiveError error_page
+syn keyword ngxDirectiveError post_action
+
+syn keyword ngxDirectiveDeprecated connections
+syn keyword ngxDirectiveDeprecated imap
+syn keyword ngxDirectiveDeprecated open_file_cache_retest
+syn keyword ngxDirectiveDeprecated optimize_server_names
+syn keyword ngxDirectiveDeprecated satisfy_any
+
+syn keyword ngxDirective accept_mutex
+syn keyword ngxDirective accept_mutex_delay
+syn keyword ngxDirective access_log
+syn keyword ngxDirective add_after_body
+syn keyword ngxDirective add_before_body
+syn keyword ngxDirective add_header
+syn keyword ngxDirective addition_types
+syn keyword ngxDirective aio
+syn keyword ngxDirective alias
+syn keyword ngxDirective allow
+syn keyword ngxDirective ancient_browser
+syn keyword ngxDirective ancient_browser_value
+syn keyword ngxDirective auth_basic
+syn keyword ngxDirective auth_basic_user_file
+syn keyword ngxDirective auth_http
+syn keyword ngxDirective auth_http_header
+syn keyword ngxDirective auth_http_timeout
+syn keyword ngxDirective autoindex
+syn keyword ngxDirective autoindex_exact_size
+syn keyword ngxDirective autoindex_localtime
+syn keyword ngxDirective charset
+syn keyword ngxDirective charset_types
+syn keyword ngxDirective client_body_buffer_size
+syn keyword ngxDirective client_body_in_file_only
+syn keyword ngxDirective client_body_in_single_buffer
+syn keyword ngxDirective client_body_temp_path
+syn keyword ngxDirective client_body_timeout
+syn keyword ngxDirective client_header_buffer_size
+syn keyword ngxDirective client_header_timeout
+syn keyword ngxDirective client_max_body_size
+syn keyword ngxDirective connection_pool_size
+syn keyword ngxDirective create_full_put_path
+syn keyword ngxDirective daemon
+syn keyword ngxDirective dav_access
+syn keyword ngxDirective dav_methods
+syn keyword ngxDirective debug_connection
+syn keyword ngxDirective debug_points
+syn keyword ngxDirective default_type
+syn keyword ngxDirective degradation
+syn keyword ngxDirective degrade
+syn keyword ngxDirective deny
+syn keyword ngxDirective devpoll_changes
+syn keyword ngxDirective devpoll_events
+syn keyword ngxDirective directio
+syn keyword ngxDirective directio_alignment
+syn keyword ngxDirective empty_gif
+syn keyword ngxDirective env
+syn keyword ngxDirective epoll_events
+syn keyword ngxDirective error_log
+syn keyword ngxDirective eventport_events
+syn keyword ngxDirective expires
+syn keyword ngxDirective fastcgi_bind
+syn keyword ngxDirective fastcgi_buffer_size
+syn keyword ngxDirective fastcgi_buffers
+syn keyword ngxDirective fastcgi_busy_buffers_size
+syn keyword ngxDirective fastcgi_cache
+syn keyword ngxDirective fastcgi_cache_key
+syn keyword ngxDirective fastcgi_cache_methods
+syn keyword ngxDirective fastcgi_cache_min_uses
+syn keyword ngxDirective fastcgi_cache_path
+syn keyword ngxDirective fastcgi_cache_use_stale
+syn keyword ngxDirective fastcgi_cache_valid
+syn keyword ngxDirective fastcgi_catch_stderr
+syn keyword ngxDirective fastcgi_connect_timeout
+syn keyword ngxDirective fastcgi_hide_header
+syn keyword ngxDirective fastcgi_ignore_client_abort
+syn keyword ngxDirective fastcgi_ignore_headers
+syn keyword ngxDirective fastcgi_index
+syn keyword ngxDirective fastcgi_intercept_errors
+syn keyword ngxDirective fastcgi_max_temp_file_size
+syn keyword ngxDirective fastcgi_next_upstream
+syn keyword ngxDirective fastcgi_param
+syn keyword ngxDirective fastcgi_pass_header
+syn keyword ngxDirective fastcgi_pass_request_body
+syn keyword ngxDirective fastcgi_pass_request_headers
+syn keyword ngxDirective fastcgi_read_timeout
+syn keyword ngxDirective fastcgi_send_lowat
+syn keyword ngxDirective fastcgi_send_timeout
+syn keyword ngxDirective fastcgi_split_path_info
+syn keyword ngxDirective fastcgi_store
+syn keyword ngxDirective fastcgi_store_access
+syn keyword ngxDirective fastcgi_temp_file_write_size
+syn keyword ngxDirective fastcgi_temp_path
+syn keyword ngxDirective fastcgi_upstream_fail_timeout
+syn keyword ngxDirective fastcgi_upstream_max_fails
+syn keyword ngxDirective flv
+syn keyword ngxDirective geoip_city
+syn keyword ngxDirective geoip_country
+syn keyword ngxDirective google_perftools_profiles
+syn keyword ngxDirective gzip
+syn keyword ngxDirective gzip_buffers
+syn keyword ngxDirective gzip_comp_level
+syn keyword ngxDirective gzip_disable
+syn keyword ngxDirective gzip_hash
+syn keyword ngxDirective gzip_http_version
+syn keyword ngxDirective gzip_min_length
+syn keyword ngxDirective gzip_no_buffer
+syn keyword ngxDirective gzip_proxied
+syn keyword ngxDirective gzip_static
+syn keyword ngxDirective gzip_types
+syn keyword ngxDirective gzip_vary
+syn keyword ngxDirective gzip_window
+syn keyword ngxDirective if_modified_since
+syn keyword ngxDirective ignore_invalid_headers
+syn keyword ngxDirective image_filter
+syn keyword ngxDirective image_filter_buffer
+syn keyword ngxDirective image_filter_jpeg_quality
+syn keyword ngxDirective image_filter_transparency
+syn keyword ngxDirective imap_auth
+syn keyword ngxDirective imap_capabilities
+syn keyword ngxDirective imap_client_buffer
+syn keyword ngxDirective index
+syn keyword ngxDirective ip_hash
+syn keyword ngxDirective keepalive_requests
+syn keyword ngxDirective keepalive_timeout
+syn keyword ngxDirective kqueue_changes
+syn keyword ngxDirective kqueue_events
+syn keyword ngxDirective large_client_header_buffers
+syn keyword ngxDirective limit_conn
+syn keyword ngxDirective limit_conn_log_level
+syn keyword ngxDirective limit_rate
+syn keyword ngxDirective limit_rate_after
+syn keyword ngxDirective limit_req
+syn keyword ngxDirective limit_req_log_level
+syn keyword ngxDirective limit_req_zone
+syn keyword ngxDirective limit_zone
+syn keyword ngxDirective lingering_time
+syn keyword ngxDirective lingering_timeout
+syn keyword ngxDirective lock_file
+syn keyword ngxDirective log_format
+syn keyword ngxDirective log_not_found
+syn keyword ngxDirective log_subrequest
+syn keyword ngxDirective map_hash_bucket_size
+syn keyword ngxDirective map_hash_max_size
+syn keyword ngxDirective master_process
+syn keyword ngxDirective memcached_bind
+syn keyword ngxDirective memcached_buffer_size
+syn keyword ngxDirective memcached_connect_timeout
+syn keyword ngxDirective memcached_next_upstream
+syn keyword ngxDirective memcached_read_timeout
+syn keyword ngxDirective memcached_send_timeout
+syn keyword ngxDirective memcached_upstream_fail_timeout
+syn keyword ngxDirective memcached_upstream_max_fails
+syn keyword ngxDirective merge_slashes
+syn keyword ngxDirective min_delete_depth
+syn keyword ngxDirective modern_browser
+syn keyword ngxDirective modern_browser_value
+syn keyword ngxDirective msie_padding
+syn keyword ngxDirective msie_refresh
+syn keyword ngxDirective multi_accept
+syn keyword ngxDirective open_file_cache
+syn keyword ngxDirective open_file_cache_errors
+syn keyword ngxDirective open_file_cache_events
+syn keyword ngxDirective open_file_cache_min_uses
+syn keyword ngxDirective open_file_cache_valid
+syn keyword ngxDirective open_log_file_cache
+syn keyword ngxDirective output_buffers
+syn keyword ngxDirective override_charset
+syn keyword ngxDirective perl
+syn keyword ngxDirective perl_modules
+syn keyword ngxDirective perl_require
+syn keyword ngxDirective perl_set
+syn keyword ngxDirective pid
+syn keyword ngxDirective pop3_auth
+syn keyword ngxDirective pop3_capabilities
+syn keyword ngxDirective port_in_redirect
+syn keyword ngxDirective postpone_gzipping
+syn keyword ngxDirective postpone_output
+syn keyword ngxDirective protocol
+syn keyword ngxDirective proxy
+syn keyword ngxDirective proxy_bind
+syn keyword ngxDirective proxy_buffer
+syn keyword ngxDirective proxy_buffer_size
+syn keyword ngxDirective proxy_buffering
+syn keyword ngxDirective proxy_buffers
+syn keyword ngxDirective proxy_busy_buffers_size
+syn keyword ngxDirective proxy_cache
+syn keyword ngxDirective proxy_cache_key
+syn keyword ngxDirective proxy_cache_methods
+syn keyword ngxDirective proxy_cache_min_uses
+syn keyword ngxDirective proxy_cache_path
+syn keyword ngxDirective proxy_cache_use_stale
+syn keyword ngxDirective proxy_cache_valid
+syn keyword ngxDirective proxy_connect_timeout
+syn keyword ngxDirective proxy_headers_hash_bucket_size
+syn keyword ngxDirective proxy_headers_hash_max_size
+syn keyword ngxDirective proxy_hide_header
+syn keyword ngxDirective proxy_ignore_client_abort
+syn keyword ngxDirective proxy_ignore_headers
+syn keyword ngxDirective proxy_intercept_errors
+syn keyword ngxDirective proxy_max_temp_file_size
+syn keyword ngxDirective proxy_method
+syn keyword ngxDirective proxy_next_upstream
+syn keyword ngxDirective proxy_pass_error_message
+syn keyword ngxDirective proxy_pass_header
+syn keyword ngxDirective proxy_pass_request_body
+syn keyword ngxDirective proxy_pass_request_headers
+syn keyword ngxDirective proxy_read_timeout
+syn keyword ngxDirective proxy_redirect
+syn keyword ngxDirective proxy_send_lowat
+syn keyword ngxDirective proxy_send_timeout
+syn keyword ngxDirective proxy_set_body
+syn keyword ngxDirective proxy_set_header
+syn keyword ngxDirective proxy_ssl_session_reuse
+syn keyword ngxDirective proxy_store
+syn keyword ngxDirective proxy_store_access
+syn keyword ngxDirective proxy_temp_file_write_size
+syn keyword ngxDirective proxy_temp_path
+syn keyword ngxDirective proxy_timeout
+syn keyword ngxDirective proxy_upstream_fail_timeout
+syn keyword ngxDirective proxy_upstream_max_fails
+syn keyword ngxDirective random_index
+syn keyword ngxDirective read_ahead
+syn keyword ngxDirective real_ip_header
+syn keyword ngxDirective recursive_error_pages
+syn keyword ngxDirective request_pool_size
+syn keyword ngxDirective reset_timedout_connection
+syn keyword ngxDirective resolver
+syn keyword ngxDirective resolver_timeout
+syn keyword ngxDirective rewrite_log
+syn keyword ngxDirective rtsig_overflow_events
+syn keyword ngxDirective rtsig_overflow_test
+syn keyword ngxDirective rtsig_overflow_threshold
+syn keyword ngxDirective rtsig_signo
+syn keyword ngxDirective satisfy
+syn keyword ngxDirective secure_link_secret
+syn keyword ngxDirective send_lowat
+syn keyword ngxDirective send_timeout
+syn keyword ngxDirective sendfile
+syn keyword ngxDirective sendfile_max_chunk
+syn keyword ngxDirective server_name_in_redirect
+syn keyword ngxDirective server_names_hash_bucket_size
+syn keyword ngxDirective server_names_hash_max_size
+syn keyword ngxDirective server_tokens
+syn keyword ngxDirective set_real_ip_from
+syn keyword ngxDirective smtp_auth
+syn keyword ngxDirective smtp_capabilities
+syn keyword ngxDirective smtp_client_buffer
+syn keyword ngxDirective smtp_greeting_delay
+syn keyword ngxDirective so_keepalive
+syn keyword ngxDirective source_charset
+syn keyword ngxDirective ssi
+syn keyword ngxDirective ssi_ignore_recycled_buffers
+syn keyword ngxDirective ssi_min_file_chunk
+syn keyword ngxDirective ssi_silent_errors
+syn keyword ngxDirective ssi_types
+syn keyword ngxDirective ssi_value_length
+syn keyword ngxDirective ssl
+syn keyword ngxDirective ssl_certificate
+syn keyword ngxDirective ssl_certificate_key
+syn keyword ngxDirective ssl_ciphers
+syn keyword ngxDirective ssl_client_certificate
+syn keyword ngxDirective ssl_crl
+syn keyword ngxDirective ssl_dhparam
+syn keyword ngxDirective ssl_engine
+syn keyword ngxDirective ssl_prefer_server_ciphers
+syn keyword ngxDirective ssl_protocols
+syn keyword ngxDirective ssl_session_cache
+syn keyword ngxDirective ssl_session_timeout
+syn keyword ngxDirective ssl_verify_client
+syn keyword ngxDirective ssl_verify_depth
+syn keyword ngxDirective starttls
+syn keyword ngxDirective stub_status
+syn keyword ngxDirective sub_filter
+syn keyword ngxDirective sub_filter_once
+syn keyword ngxDirective sub_filter_types
+syn keyword ngxDirective tcp_nodelay
+syn keyword ngxDirective tcp_nopush
+syn keyword ngxDirective thread_stack_size
+syn keyword ngxDirective timeout
+syn keyword ngxDirective timer_resolution
+syn keyword ngxDirective types_hash_bucket_size
+syn keyword ngxDirective types_hash_max_size
+syn keyword ngxDirective underscores_in_headers
+syn keyword ngxDirective uninitialized_variable_warn
+syn keyword ngxDirective use
+syn keyword ngxDirective user
+syn keyword ngxDirective userid
+syn keyword ngxDirective userid_domain
+syn keyword ngxDirective userid_expires
+syn keyword ngxDirective userid_mark
+syn keyword ngxDirective userid_name
+syn keyword ngxDirective userid_p3p
+syn keyword ngxDirective userid_path
+syn keyword ngxDirective userid_service
+syn keyword ngxDirective valid_referers
+syn keyword ngxDirective variables_hash_bucket_size
+syn keyword ngxDirective variables_hash_max_size
+syn keyword ngxDirective worker_connections
+syn keyword ngxDirective worker_cpu_affinity
+syn keyword ngxDirective worker_priority
+syn keyword ngxDirective worker_processes
+syn keyword ngxDirective worker_rlimit_core
+syn keyword ngxDirective worker_rlimit_nofile
+syn keyword ngxDirective worker_rlimit_sigpending
+syn keyword ngxDirective worker_threads
+syn keyword ngxDirective working_directory
+syn keyword ngxDirective xclient
+syn keyword ngxDirective xml_entities
+syn keyword ngxDirective xslt_stylesheet
+syn keyword ngxDirective xslt_types
+
+" 3rd party module list:
+" http://wiki.nginx.org/Nginx3rdPartyModules
+
+" Accept Language Module <http://wiki.nginx.org/NginxAcceptLanguageModule>
+" Parses the Accept-Language header and gives the most suitable locale from a list of supported locales.
+syn keyword ngxDirectiveThirdParty set_from_accept_language
+
+" Access Key Module <http://wiki.nginx.org/NginxHttpAccessKeyModule>
+" Denies access unless the request URL contains an access key. 
+syn keyword ngxDirectiveThirdParty accesskey
+syn keyword ngxDirectiveThirdParty accesskey_arg
+syn keyword ngxDirectiveThirdParty accesskey_hashmethod
+syn keyword ngxDirectiveThirdParty accesskey_signature
+
+" Auth PAM Module <http://web.iti.upv.es/~sto/nginx/>
+" HTTP Basic Authentication using PAM.
+syn keyword ngxDirectiveThirdParty auth_pam
+syn keyword ngxDirectiveThirdParty auth_pam_service_name
+
+" Cache Purge Module <http://labs.frickle.com/nginx_ngx_cache_purge/>
+" Module adding ability to purge content from FastCGI and proxy caches.
+syn keyword ngxDirectiveThirdParty fastcgi_cache_purge
+syn keyword ngxDirectiveThirdParty proxy_cache_purge
+
+" Chunkin Module <http://wiki.nginx.org/NginxHttpChunkinModule>
+" HTTP 1.1 chunked-encoding request body support for Nginx.
+syn keyword ngxDirectiveThirdParty chunkin
+syn keyword ngxDirectiveThirdParty chunkin_keepalive
+syn keyword ngxDirectiveThirdParty chunkin_max_chunks_per_buf
+syn keyword ngxDirectiveThirdParty chunkin_resume
+
+" Circle GIF Module <http://wiki.nginx.org/NginxHttpCircleGifModule>
+" Generates simple circle images with the colors and size specified in the URL.
+syn keyword ngxDirectiveThirdParty circle_gif
+syn keyword ngxDirectiveThirdParty circle_gif_max_radius
+syn keyword ngxDirectiveThirdParty circle_gif_min_radius
+syn keyword ngxDirectiveThirdParty circle_gif_step_radius
+
+" Drizzle Module <http://github.com/chaoslawful/drizzle-nginx-module>
+" Make nginx talk directly to mysql, drizzle, and sqlite3 by libdrizzle.
+syn keyword ngxDirectiveThirdParty drizzle_connect_timeout
+syn keyword ngxDirectiveThirdParty drizzle_dbname
+syn keyword ngxDirectiveThirdParty drizzle_keepalive
+syn keyword ngxDirectiveThirdParty drizzle_module_header
+syn keyword ngxDirectiveThirdParty drizzle_pass
+syn keyword ngxDirectiveThirdParty drizzle_query
+syn keyword ngxDirectiveThirdParty drizzle_recv_cols_timeout
+syn keyword ngxDirectiveThirdParty drizzle_recv_rows_timeout
+syn keyword ngxDirectiveThirdParty drizzle_send_query_timeout
+syn keyword ngxDirectiveThirdParty drizzle_server
+
+" Echo Module <http://wiki.nginx.org/NginxHttpEchoModule>
+" Brings 'echo', 'sleep', 'time', 'exec' and more shell-style goodies to Nginx config file.
+syn keyword ngxDirectiveThirdParty echo
+syn keyword ngxDirectiveThirdParty echo_after_body
+syn keyword ngxDirectiveThirdParty echo_before_body
+syn keyword ngxDirectiveThirdParty echo_blocking_sleep
+syn keyword ngxDirectiveThirdParty echo_duplicate
+syn keyword ngxDirectiveThirdParty echo_end
+syn keyword ngxDirectiveThirdParty echo_exec
+syn keyword ngxDirectiveThirdParty echo_flush
+syn keyword ngxDirectiveThirdParty echo_foreach_split
+syn keyword ngxDirectiveThirdParty echo_location
+syn keyword ngxDirectiveThirdParty echo_location_async
+syn keyword ngxDirectiveThirdParty echo_read_request_body
+syn keyword ngxDirectiveThirdParty echo_request_body
+syn keyword ngxDirectiveThirdParty echo_reset_timer
+syn keyword ngxDirectiveThirdParty echo_sleep
+syn keyword ngxDirectiveThirdParty echo_subrequest
+syn keyword ngxDirectiveThirdParty echo_subrequest_async
+
+" Events Module <http://docs.dutov.org/nginx_modules_events_en.html>
+" Privides options for start/stop events.
+syn keyword ngxDirectiveThirdParty on_start
+syn keyword ngxDirectiveThirdParty on_stop
+
+" EY Balancer Module <http://github.com/ry/nginx-ey-balancer>
+" Adds a request queue to Nginx that allows the limiting of concurrent requests passed to the upstream.
+syn keyword ngxDirectiveThirdParty max_connections
+syn keyword ngxDirectiveThirdParty max_connections_max_queue_length
+syn keyword ngxDirectiveThirdParty max_connections_queue_timeout
+
+" Fancy Indexes Module <https://connectical.com/projects/ngx-fancyindex/wiki>
+" Like the built-in autoindex module, but fancier.
+syn keyword ngxDirectiveThirdParty fancyindex
+syn keyword ngxDirectiveThirdParty fancyindex_exact_size
+syn keyword ngxDirectiveThirdParty fancyindex_footer
+syn keyword ngxDirectiveThirdParty fancyindex_header
+syn keyword ngxDirectiveThirdParty fancyindex_localtime
+syn keyword ngxDirectiveThirdParty fancyindex_readme
+syn keyword ngxDirectiveThirdParty fancyindex_readme_mode
+
+" GeoIP Module (DEPRECATED) <http://wiki.nginx.org/NginxHttp3rdPartyGeoIPModule>
+" Country code lookups via the MaxMind GeoIP API.
+syn keyword ngxDirectiveThirdParty geoip_country_file
+
+" Headers More Module <http://wiki.nginx.org/NginxHttpHeadersMoreModule>
+" Set and clear input and output headers...more than "add"!
+syn keyword ngxDirectiveThirdParty more_clear_headers
+syn keyword ngxDirectiveThirdParty more_clear_input_headers
+syn keyword ngxDirectiveThirdParty more_set_headers
+syn keyword ngxDirectiveThirdParty more_set_input_headers
+
+" HTTP Push Module <http://pushmodule.slact.net/>
+" Turn Nginx into an adept long-polling HTTP Push (Comet) server.
+syn keyword ngxDirectiveThirdParty push_buffer_size
+syn keyword ngxDirectiveThirdParty push_listener
+syn keyword ngxDirectiveThirdParty push_message_timeout
+syn keyword ngxDirectiveThirdParty push_queue_messages
+syn keyword ngxDirectiveThirdParty push_sender
+
+" HTTP Redis Module <http://people.FreeBSD.ORG/~osa/ngx_http_redis-0.3.1.tar.gz>>
+" Redis <http://code.google.com/p/redis/> support.>
+syn keyword ngxDirectiveThirdParty redis_bind
+syn keyword ngxDirectiveThirdParty redis_buffer_size
+syn keyword ngxDirectiveThirdParty redis_connect_timeout
+syn keyword ngxDirectiveThirdParty redis_next_upstream
+syn keyword ngxDirectiveThirdParty redis_pass
+syn keyword ngxDirectiveThirdParty redis_read_timeout
+syn keyword ngxDirectiveThirdParty redis_send_timeout
+
+" HTTP JavaScript Module <http://wiki.github.com/kung-fu-tzu/ngx_http_js_module>
+" Embedding SpiderMonkey. Nearly full port on Perl module.
+syn keyword ngxDirectiveThirdParty js
+syn keyword ngxDirectiveThirdParty js_filter
+syn keyword ngxDirectiveThirdParty js_filter_types
+syn keyword ngxDirectiveThirdParty js_load
+syn keyword ngxDirectiveThirdParty js_maxmem
+syn keyword ngxDirectiveThirdParty js_require
+syn keyword ngxDirectiveThirdParty js_set
+syn keyword ngxDirectiveThirdParty js_utf8
+
+" Log Request Speed <http://wiki.nginx.org/NginxHttpLogRequestSpeed>
+" Log the time it took to process each request.
+syn keyword ngxDirectiveThirdParty log_request_speed_filter
+syn keyword ngxDirectiveThirdParty log_request_speed_filter_timeout
+
+" Memc Module <http://wiki.nginx.org/NginxHttpMemcModule>
+" An extended version of the standard memcached module that supports set, add, delete, and many more memcached commands.
+syn keyword ngxDirectiveThirdParty memc_buffer_size
+syn keyword ngxDirectiveThirdParty memc_cmds_allowed
+syn keyword ngxDirectiveThirdParty memc_connect_timeout
+syn keyword ngxDirectiveThirdParty memc_flags_to_last_modified
+syn keyword ngxDirectiveThirdParty memc_next_upstream
+syn keyword ngxDirectiveThirdParty memc_pass
+syn keyword ngxDirectiveThirdParty memc_read_timeout
+syn keyword ngxDirectiveThirdParty memc_send_timeout
+syn keyword ngxDirectiveThirdParty memc_upstream_fail_timeout
+syn keyword ngxDirectiveThirdParty memc_upstream_max_fails
+
+" Mogilefs Module <http://www.grid.net.ru/nginx/mogilefs.en.html>
+" Implements a MogileFS client, provides a replace to the Perlbal reverse proxy of the original MogileFS.
+syn keyword ngxDirectiveThirdParty mogilefs_connect_timeout
+syn keyword ngxDirectiveThirdParty mogilefs_domain
+syn keyword ngxDirectiveThirdParty mogilefs_methods
+syn keyword ngxDirectiveThirdParty mogilefs_noverify
+syn keyword ngxDirectiveThirdParty mogilefs_pass
+syn keyword ngxDirectiveThirdParty mogilefs_read_timeout
+syn keyword ngxDirectiveThirdParty mogilefs_send_timeout
+syn keyword ngxDirectiveThirdParty mogilefs_tracker
+
+" MP4 Streaming Lite Module <http://wiki.nginx.org/NginxMP4StreamingLite>
+" Will seek to a certain time within H.264/MP4 files when provided with a 'start' parameter in the URL. 
+syn keyword ngxDirectiveThirdParty mp4
+
+" Nginx Notice Module <http://xph.us/software/nginx-notice/>
+" Serve static file to POST requests.
+syn keyword ngxDirectiveThirdParty notice
+syn keyword ngxDirectiveThirdParty notice_type
+
+" Phusion Passenger <http://www.modrails.com/documentation.html>
+" Easy and robust deployment of Ruby on Rails application on Apache and Nginx webservers.
+syn keyword ngxDirectiveThirdParty passenger_base_uri
+syn keyword ngxDirectiveThirdParty passenger_default_user
+syn keyword ngxDirectiveThirdParty passenger_enabled
+syn keyword ngxDirectiveThirdParty passenger_log_level
+syn keyword ngxDirectiveThirdParty passenger_max_instances_per_app
+syn keyword ngxDirectiveThirdParty passenger_max_pool_size
+syn keyword ngxDirectiveThirdParty passenger_pool_idle_time
+syn keyword ngxDirectiveThirdParty passenger_root
+syn keyword ngxDirectiveThirdParty passenger_ruby
+syn keyword ngxDirectiveThirdParty passenger_use_global_queue
+syn keyword ngxDirectiveThirdParty passenger_user_switching
+syn keyword ngxDirectiveThirdParty rack_env
+syn keyword ngxDirectiveThirdParty rails_app_spawner_idle_time
+syn keyword ngxDirectiveThirdParty rails_env
+syn keyword ngxDirectiveThirdParty rails_framework_spawner_idle_time
+syn keyword ngxDirectiveThirdParty rails_spawn_method
+
+" RDS JSON Module <http://github.com/agentzh/rds-json-nginx-module>
+" Help ngx_drizzle and other DBD modules emit JSON data.
+syn keyword ngxDirectiveThirdParty rds_json
+syn keyword ngxDirectiveThirdParty rds_json_content_type
+syn keyword ngxDirectiveThirdParty rds_json_format
+syn keyword ngxDirectiveThirdParty rds_json_ret
+
+" RRD Graph Module <http://wiki.nginx.org/NginxNgx_rrd_graph>
+" This module provides an HTTP interface to RRDtool's graphing facilities.
+syn keyword ngxDirectiveThirdParty rrd_graph
+syn keyword ngxDirectiveThirdParty rrd_graph_root
+
+" Secure Download <http://wiki.nginx.org/NginxHttpSecureDownload>
+" Create expiring links.
+syn keyword ngxDirectiveThirdParty secure_download
+syn keyword ngxDirectiveThirdParty secure_download_fail_location
+syn keyword ngxDirectiveThirdParty secure_download_path_mode
+syn keyword ngxDirectiveThirdParty secure_download_secret
+
+" SlowFS Cache Module <http://labs.frickle.com/nginx_ngx_slowfs_cache/>
+" Module adding ability to cache static files.
+syn keyword ngxDirectiveThirdParty slowfs_big_file_size
+syn keyword ngxDirectiveThirdParty slowfs_cache
+syn keyword ngxDirectiveThirdParty slowfs_cache_key
+syn keyword ngxDirectiveThirdParty slowfs_cache_min_uses
+syn keyword ngxDirectiveThirdParty slowfs_cache_path
+syn keyword ngxDirectiveThirdParty slowfs_cache_purge
+syn keyword ngxDirectiveThirdParty slowfs_cache_valid
+syn keyword ngxDirectiveThirdParty slowfs_temp_path
+
+" Strip Module <http://wiki.nginx.org/NginxHttpStripModule>
+" Whitespace remover.
+syn keyword ngxDirectiveThirdParty strip
+
+" Substitutions Module <http://wiki.nginx.org/NginxHttpSubsModule>
+" A filter module which can do both regular expression and fixed string substitutions on response bodies.
+syn keyword ngxDirectiveThirdParty subs_filter
+syn keyword ngxDirectiveThirdParty subs_filter_types
+
+" Supervisord Module <http://labs.frickle.com/nginx_ngx_supervisord/>
+" Module providing nginx with API to communicate with supervisord and manage (start/stop) backends on-demand.
+syn keyword ngxDirectiveThirdParty supervisord
+syn keyword ngxDirectiveThirdParty supervisord_inherit_backend_status
+syn keyword ngxDirectiveThirdParty supervisord_name
+syn keyword ngxDirectiveThirdParty supervisord_start
+syn keyword ngxDirectiveThirdParty supervisord_stop
+
+" Upload Module <http://www.grid.net.ru/nginx/upload.en.html>
+" Parses multipart/form-data allowing arbitrary handling of uploaded files.
+syn keyword ngxDirectiveThirdParty upload_aggregate_form_field
+syn keyword ngxDirectiveThirdParty upload_buffer_size
+syn keyword ngxDirectiveThirdParty upload_cleanup
+syn keyword ngxDirectiveThirdParty upload_limit_rate
+syn keyword ngxDirectiveThirdParty upload_max_file_size
+syn keyword ngxDirectiveThirdParty upload_max_output_body_len
+syn keyword ngxDirectiveThirdParty upload_max_part_header_len
+syn keyword ngxDirectiveThirdParty upload_pass
+syn keyword ngxDirectiveThirdParty upload_pass_args
+syn keyword ngxDirectiveThirdParty upload_pass_form_field
+syn keyword ngxDirectiveThirdParty upload_set_form_field
+syn keyword ngxDirectiveThirdParty upload_store
+syn keyword ngxDirectiveThirdParty upload_store_access
+
+" Upload Progress Module <http://wiki.nginx.org/NginxHttpUploadProgressModule>
+" Tracks and reports upload progress.
+syn keyword ngxDirectiveThirdParty report_uploads
+syn keyword ngxDirectiveThirdParty track_uploads
+syn keyword ngxDirectiveThirdParty upload_progress
+syn keyword ngxDirectiveThirdParty upload_progress_content_type
+syn keyword ngxDirectiveThirdParty upload_progress_header
+syn keyword ngxDirectiveThirdParty upload_progress_json_output
+syn keyword ngxDirectiveThirdParty upload_progress_template
+
+" Upstream Fair Balancer <http://wiki.nginx.org/NginxHttpUpstreamFairModule>
+" Sends an incoming request to the least-busy backend server, rather than distributing requests round-robin.
+syn keyword ngxDirectiveThirdParty fair
+syn keyword ngxDirectiveThirdParty upstream_fair_shm_size
+
+" Upstream Consistent Hash <http://wiki.nginx.org/NginxHttpUpstreamConsistentHash>
+" Select backend based on Consistent hash ring.
+syn keyword ngxDirectiveThirdParty consistent_hash
+
+" Upstream Hash Module <http://wiki.nginx.org/NginxHttpUpstreamRequestHashModule>
+" Provides simple upstream load distribution by hashing a configurable variable.
+syn keyword ngxDirectiveThirdParty hash
+syn keyword ngxDirectiveThirdParty hash_again
+
+" XSS Module <http://github.com/agentzh/xss-nginx-module>
+" Native support for cross-site scripting (XSS) in an nginx.
+syn keyword ngxDirectiveThirdParty xss_callback_arg
+syn keyword ngxDirectiveThirdParty xss_get
+syn keyword ngxDirectiveThirdParty xss_input_types
+syn keyword ngxDirectiveThirdParty xss_output_type
+
+" uWSGI Module <http://wiki.nginx.org/HttpUwsgiModule>
+" Allows Nginx to interact with uWSGI processes and control what parameters are passed to the process.
+syn keyword ngxDirectiveThirdParty uwsgi_bind
+syn keyword ngxDirectiveThirdParty uwsgi_buffer_size
+syn keyword ngxDirectiveThirdParty uwsgi_buffering
+syn keyword ngxDirectiveThirdParty uwsgi_buffers
+syn keyword ngxDirectiveThirdParty uwsgi_busy_buffers_size
+syn keyword ngxDirectiveThirdParty uwsgi_cache
+syn keyword ngxDirectiveThirdParty uwsgi_cache_bypass
+syn keyword ngxDirectiveThirdParty uwsgi_cache_key
+syn keyword ngxDirectiveThirdParty uwsgi_cache_lock
+syn keyword ngxDirectiveThirdParty uwsgi_cache_lock_timeout
+syn keyword ngxDirectiveThirdParty uwsgi_cache_methods
+syn keyword ngxDirectiveThirdParty uwsgi_cache_min_uses
+syn keyword ngxDirectiveThirdParty uwsgi_cache_path
+syn keyword ngxDirectiveThirdParty uwsgi_cache_use_stale
+syn keyword ngxDirectiveThirdParty uwsgi_cache_valid
+syn keyword ngxDirectiveThirdParty uwsgi_connect_timeout
+syn keyword ngxDirectiveThirdParty uwsgi_hide_header
+syn keyword ngxDirectiveThirdParty uwsgi_ignore_client_abort
+syn keyword ngxDirectiveThirdParty uwsgi_ignore_headers
+syn keyword ngxDirectiveThirdParty uwsgi_intercept_errors
+syn keyword ngxDirectiveThirdParty uwsgi_max_temp_file_size
+syn keyword ngxDirectiveThirdParty uwsgi_modifier1
+syn keyword ngxDirectiveThirdParty uwsgi_modifier2
+syn keyword ngxDirectiveThirdParty uwsgi_next_upstream
+syn keyword ngxDirectiveThirdParty uwsgi_no_cache
+syn keyword ngxDirectiveThirdParty uwsgi_param
+syn keyword ngxDirectiveThirdParty uwsgi_pass
+syn keyword ngxDirectiveThirdParty uwsgi_pass_header
+syn keyword ngxDirectiveThirdParty uwsgi_pass_request_body
+syn keyword ngxDirectiveThirdParty uwsgi_pass_request_headers
+syn keyword ngxDirectiveThirdParty uwsgi_read_timeout
+syn keyword ngxDirectiveThirdParty uwsgi_send_timeout
+syn keyword ngxDirectiveThirdParty uwsgi_store
+syn keyword ngxDirectiveThirdParty uwsgi_store_access
+syn keyword ngxDirectiveThirdParty uwsgi_string
+syn keyword ngxDirectiveThirdParty uwsgi_temp_file_write_size
+syn keyword ngxDirectiveThirdParty uwsgi_temp_path
+
+" highlight
+
+hi link ngxComment Comment
+hi link ngxVariable Identifier
+hi link ngxVariableBlock Identifier
+hi link ngxVariableString PreProc
+hi link ngxBlock Normal
+hi link ngxString String
+
+hi link ngxBoolean Boolean
+hi link ngxDirectiveBlock Statement
+hi link ngxDirectiveImportant Type
+hi link ngxDirectiveControl Keyword
+hi link ngxDirectiveError Constant
+hi link ngxDirectiveDeprecated Error
+hi link ngxDirective Identifier
+hi link ngxDirectiveThirdParty Special
+
+let b:current_syntax = "nginx"

  Renamed: vendor/nginx-1.7.2/html/50x.html (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/html/index.html (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/man/nginx.8 (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/nginx.c (+3 -8) 98%
===================================================================
--- vendor/nginx-1.4.7/src/core/nginx.c    2014-07-02 11:31:57 +0900 (94df9bf)
+++ vendor/nginx-1.7.2/src/core/nginx.c    2014-07-04 15:15:55 +0900 (c75ee4f)
@@ -217,7 +217,7 @@ main(int argc, char *const *argv)
     }
 
     if (ngx_show_version) {
-        ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED);
+        ngx_write_stderr("nginx version: " NGINX_VER_BUILD NGX_LINEFEED);
 
         if (ngx_show_help) {
             ngx_write_stderr(
@@ -387,13 +387,8 @@ main(int argc, char *const *argv)
         return 1;
     }
 
-    if (cycle->log->file->fd != ngx_stderr) {
-
-        if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
-            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
-                          ngx_set_stderr_n " failed");
-            return 1;
-        }
+    if (ngx_log_redirect_stderr(cycle) != NGX_OK) {
+        return 1;
     }
 
     if (log->file->fd != ngx_stderr) {

  Renamed: vendor/nginx-1.7.2/src/core/nginx.h (+8 -2) 59%
===================================================================
--- vendor/nginx-1.4.7/src/core/nginx.h    2014-07-02 11:31:57 +0900 (77c88bf)
+++ vendor/nginx-1.7.2/src/core/nginx.h    2014-07-04 15:15:55 +0900 (81e351c)
@@ -9,10 +9,16 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version      1004007
-#define NGINX_VERSION      "1.4.7"
+#define nginx_version      1007002
+#define NGINX_VERSION      "1.7.2"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
+#ifdef NGX_BUILD
+#define NGINX_VER_BUILD    NGINX_VER " (" NGX_BUILD ")"
+#else
+#define NGINX_VER_BUILD    NGINX_VER
+#endif
+
 #define NGINX_VAR          "NGINX"
 #define NGX_OLDPID_EXT     ".oldbin"
 

  Renamed: vendor/nginx-1.7.2/src/core/ngx_array.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_array.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_buf.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_buf.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_conf_file.c (+9 -89) 95%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_conf_file.c    2014-07-02 11:31:57 +0900 (a262672)
+++ vendor/nginx-1.7.2/src/core/ngx_conf_file.c    2014-07-04 15:15:55 +0900 (d6b5cdf)
@@ -12,7 +12,6 @@
 
 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 ngx_int_t ngx_conf_test_full_name(ngx_str_t *name);
 static void ngx_conf_flush_files(ngx_cycle_t *cycle);
 
 
@@ -225,6 +224,11 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
              * "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;
@@ -262,7 +266,7 @@ done:
             ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
                           ngx_close_file_n " %s failed",
                           filename->data);
-            return NGX_CONF_ERROR;
+            rc = NGX_ERROR;
         }
 
         cf->conf_file = prev;
@@ -796,95 +800,11 @@ 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)
 {
-    size_t      len;
-    u_char     *p, *n, *prefix;
-    ngx_int_t   rc;
-
-    rc = ngx_conf_test_full_name(name);
-
-    if (rc == NGX_OK) {
-        return rc;
-    }
-
-    if (conf_prefix) {
-        len = cycle->conf_prefix.len;
-        prefix = cycle->conf_prefix.data;
-
-    } else {
-        len = cycle->prefix.len;
-        prefix = cycle->prefix.data;
-    }
-
-#if (NGX_WIN32)
+    ngx_str_t  *prefix;
 
-    if (rc == 2) {
-        len = rc;
-    }
-
-#endif
-
-    n = ngx_pnalloc(cycle->pool, len + name->len + 1);
-    if (n == NULL) {
-        return NGX_ERROR;
-    }
+    prefix = conf_prefix ? &cycle->conf_prefix : &cycle->prefix;
 
-    p = ngx_cpymem(n, prefix, len);
-    ngx_cpystrn(p, name->data, name->len + 1);
-
-    name->len += len;
-    name->data = n;
-
-    return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_conf_test_full_name(ngx_str_t *name)
-{
-#if (NGX_WIN32)
-    u_char  c0, c1;
-
-    c0 = name->data[0];
-
-    if (name->len < 2) {
-        if (c0 == '/') {
-            return 2;
-        }
-
-        return NGX_DECLINED;
-    }
-
-    c1 = name->data[1];
-
-    if (c1 == ':') {
-        c0 |= 0x20;
-
-        if ((c0 >= 'a' && c0 <= 'z')) {
-            return NGX_OK;
-        }
-
-        return NGX_DECLINED;
-    }
-
-    if (c1 == '/') {
-        return NGX_OK;
-    }
-
-    if (c0 == '/') {
-        return 2;
-    }
-
-    return NGX_DECLINED;
-
-#else
-
-    if (name->data[0] == '/') {
-        return NGX_OK;
-    }
-
-    return NGX_DECLINED;
-
-#endif
+    return ngx_get_full_name(cycle->pool, prefix, name);
 }
 
 

  Renamed: vendor/nginx-1.7.2/src/core/ngx_conf_file.h (+3 -3) 98%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_conf_file.h    2014-07-02 11:31:57 +0900 (237e6ec)
+++ vendor/nginx-1.7.2/src/core/ngx_conf_file.h    2014-07-04 15:15:55 +0900 (d73a6c8)
@@ -5,8 +5,8 @@
  */
 
 
-#ifndef _NGX_HTTP_CONF_FILE_H_INCLUDED_
-#define _NGX_HTTP_CONF_FILE_H_INCLUDED_
+#ifndef _NGX_CONF_FILE_H_INCLUDED_
+#define _NGX_CONF_FILE_H_INCLUDED_
 
 
 #include <ngx_config.h>
@@ -337,4 +337,4 @@ extern ngx_uint_t     ngx_max_module;
 extern ngx_module_t  *ngx_modules[];
 
 
-#endif /* _NGX_HTTP_CONF_FILE_H_INCLUDED_ */
+#endif /* _NGX_CONF_FILE_H_INCLUDED_ */

  Renamed: vendor/nginx-1.7.2/src/core/ngx_config.h (+2 -2) 95%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_config.h    2014-07-02 11:31:57 +0900 (b0cb17f)
+++ vendor/nginx-1.7.2/src/core/ngx_config.h    2014-07-04 15:15:55 +0900 (1da71f8)
@@ -80,8 +80,8 @@ 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
+#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

  Renamed: vendor/nginx-1.7.2/src/core/ngx_connection.c (+100 -29) 89%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_connection.c    2014-07-02 11:31:57 +0900 (986bf0d)
+++ vendor/nginx-1.7.2/src/core/ngx_connection.c    2014-07-04 15:15:55 +0900 (6b6e3b3)
@@ -41,7 +41,7 @@ ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen)
     ls->sockaddr = sa;
     ls->socklen = socklen;
 
-    len = ngx_sock_ntop(sa, text, NGX_SOCKADDR_STRLEN, 1);
+    len = ngx_sock_ntop(sa, socklen, text, NGX_SOCKADDR_STRLEN, 1);
     ls->addr_text.len = len;
 
     switch (ls->sockaddr->sa_family) {
@@ -82,6 +82,10 @@ ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen)
     ls->setfib = -1;
 #endif
 
+#if (NGX_HAVE_TCP_FASTOPEN)
+    ls->fastopen = -1;
+#endif
+
     return ls;
 }
 
@@ -93,8 +97,10 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
     ngx_uint_t                 i;
     ngx_listening_t           *ls;
     socklen_t                  olen;
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
+#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)
@@ -123,7 +129,7 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
 #if (NGX_HAVE_INET6)
         case AF_INET6:
              ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN;
-             len = NGX_INET6_ADDRSTRLEN + sizeof(":65535") - 1;
+             len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
              break;
 #endif
 
@@ -152,7 +158,8 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
             return NGX_ERROR;
         }
 
-        len = ngx_sock_ntop(ls[i].sockaddr, ls[i].addr_text.data, len, 1);
+        len = ngx_sock_ntop(ls[i].sockaddr, ls[i].socklen,
+                            ls[i].addr_text.data, len, 1);
         if (len == 0) {
             return NGX_ERROR;
         }
@@ -192,7 +199,9 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
 
 #if (NGX_HAVE_SETFIB)
 
-        if (getsockopt(ls[i].setfib, SOL_SOCKET, SO_SETFIB,
+        olen = sizeof(int);
+
+        if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
                        (void *) &ls[i].setfib, &olen)
             == -1)
         {
@@ -206,6 +215,27 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
 #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));
@@ -214,7 +244,7 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen)
             == -1)
         {
-            err = ngx_errno;
+            err = ngx_socket_errno;
 
             if (err == NGX_EINVAL) {
                 continue;
@@ -247,7 +277,13 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
         if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen)
             == -1)
         {
-            ngx_log_error(NGX_LOG_NOTICE, cycle->log, ngx_errno,
+            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;
@@ -296,7 +332,7 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
                 continue;
             }
 
-            if (ls[i].fd != -1) {
+            if (ls[i].fd != (ngx_socket_t) -1) {
                 continue;
             }
 
@@ -311,7 +347,7 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
 
             s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, 0);
 
-            if (s == -1) {
+            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;
@@ -463,16 +499,13 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
 void
 ngx_configure_listening_sockets(ngx_cycle_t *cycle)
 {
-    int                        keepalive;
+    int                        value;
     ngx_uint_t                 i;
     ngx_listening_t           *ls;
 
 #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++) {
@@ -502,39 +535,51 @@ ngx_configure_listening_sockets(ngx_cycle_t *cycle)
         }
 
         if (ls[i].keepalive) {
-            keepalive = (ls[i].keepalive == 1) ? 1 : 0;
+            value = (ls[i].keepalive == 1) ? 1 : 0;
 
             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE,
-                           (const void *) &keepalive, sizeof(int))
+                           (const void *) &value, sizeof(int))
                 == -1)
             {
                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                               "setsockopt(SO_KEEPALIVE, %d) %V failed, ignored",
-                              keepalive, &ls[i].addr_text);
+                              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 *) &ls[i].keepidle, sizeof(int))
+                           (const void *) &value, sizeof(int))
                 == -1)
             {
                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                               "setsockopt(TCP_KEEPIDLE, %d) %V failed, ignored",
-                              ls[i].keepidle, &ls[i].addr_text);
+                              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 *) &ls[i].keepintvl, sizeof(int))
+                           (const void *) &value, sizeof(int))
                 == -1)
             {
                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                              "setsockopt(TCP_KEEPINTVL, %d) %V failed, ignored",
-                             ls[i].keepintvl, &ls[i].addr_text);
+                             value, &ls[i].addr_text);
             }
         }
 
@@ -564,6 +609,19 @@ ngx_configure_listening_sockets(ngx_cycle_t *cycle)
         }
 #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;
@@ -603,7 +661,7 @@ ngx_configure_listening_sockets(ngx_cycle_t *cycle)
             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)
                 == -1)
             {
-                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                               "setsockopt(SO_ACCEPTFILTER, NULL) "
                               "for %V failed, ignored",
                               &ls[i].addr_text);
@@ -630,7 +688,7 @@ ngx_configure_listening_sockets(ngx_cycle_t *cycle)
                            &af, sizeof(struct accept_filter_arg))
                 == -1)
             {
-                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                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);
@@ -653,20 +711,20 @@ ngx_configure_listening_sockets(ngx_cycle_t *cycle)
                  * if syncookies were used), hence we use 1 second timeout
                  * here.
                  */
-                timeout = 1;
+                value = 1;
 
             } else {
-                timeout = 0;
+                value = 0;
             }
 
             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT,
-                           &timeout, sizeof(int))
+                           &value, sizeof(int))
                 == -1)
             {
-                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                               "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, "
                               "ignored",
-                              timeout, &ls[i].addr_text);
+                              value, &ls[i].addr_text);
 
                 continue;
             }
@@ -859,7 +917,7 @@ ngx_close_connection(ngx_connection_t *c)
     ngx_uint_t    log_error, level;
     ngx_socket_t  fd;
 
-    if (c->fd == -1) {
+    if (c->fd == (ngx_socket_t) -1) {
         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
         return;
     }
@@ -1034,6 +1092,10 @@ ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
     struct sockaddr_in6  *sin6;
 #endif
 
+    if (c->local_socklen == 0) {
+        return NGX_ERROR;
+    }
+
     switch (c->local_sockaddr->sa_family) {
 
 #if (NGX_HAVE_INET6)
@@ -1047,6 +1109,12 @@ ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
         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;
@@ -1068,13 +1136,16 @@ ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
         }
 
         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, s->data, s->len, port);
+    s->len = ngx_sock_ntop(c->local_sockaddr, c->local_socklen,
+                           s->data, s->len, port);
 
     return NGX_OK;
 }

  Renamed: vendor/nginx-1.7.2/src/core/ngx_connection.h (+11 -0) 94%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_connection.h    2014-07-02 11:31:57 +0900 (3daf2ee)
+++ vendor/nginx-1.7.2/src/core/ngx_connection.h    2014-07-04 15:15:55 +0900 (ed14e60)
@@ -80,6 +80,10 @@ struct ngx_listening_s {
     int                 setfib;
 #endif
 
+#if (NGX_HAVE_TCP_FASTOPEN)
+    int                 fastopen;
+#endif
+
 };
 
 
@@ -108,6 +112,7 @@ typedef enum {
 
 #define NGX_LOWLEVEL_BUFFERED  0x0f
 #define NGX_SSL_BUFFERED       0x01
+#define NGX_SPDY_BUFFERED      0x02
 
 
 struct ngx_connection_s {
@@ -134,11 +139,14 @@ struct ngx_connection_s {
     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;
 
@@ -166,12 +174,15 @@ struct ngx_connection_s {
     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
 

  Renamed: vendor/nginx-1.7.2/src/core/ngx_core.h (+5 -3) 94%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_core.h    2014-07-02 11:31:57 +0900 (dfcf2d5)
+++ vendor/nginx-1.7.2/src/core/ngx_core.h    2014-07-04 15:15:55 +0900 (aeea0c6)
@@ -77,11 +77,13 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
 #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 LF     (u_char) '\n'
+#define CR     (u_char) '\r'
+#define CRLF   "\r\n"
 
 
 #define ngx_abs(value)       (((value) >= 0) ? (value) : - (value))

  Renamed: vendor/nginx-1.7.2/src/core/ngx_cpuinfo.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_crc.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_crc32.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_crc32.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_crypt.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_crypt.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_cycle.c (+29 -99) 92%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_cycle.c    2014-07-02 11:31:57 +0900 (87b6d7d)
+++ vendor/nginx-1.7.2/src/core/ngx_cycle.c    2014-07-04 15:15:55 +0900 (d69783f)
@@ -11,7 +11,6 @@
 
 
 static void ngx_destroy_cycle_pools(ngx_conf_t *conf);
-static ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2);
 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);
@@ -36,8 +35,6 @@ ngx_tls_key_t          ngx_core_tls_key;
 static ngx_connection_t  dumb;
 /* STUB */
 
-static ngx_str_t  error_log = ngx_string(NGX_ERROR_LOG_PATH);
-
 
 ngx_cycle_t *
 ngx_init_cycle(ngx_cycle_t *old_cycle)
@@ -84,7 +81,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
 
     cycle->pool = pool;
     cycle->log = log;
-    cycle->new_log.log_level = NGX_LOG_ERR;
     cycle->old_cycle = old_cycle;
 
     cycle->conf_prefix.len = old_cycle->conf_prefix.len;
@@ -339,11 +335,8 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
     }
 
 
-    if (cycle->new_log.file == NULL) {
-        cycle->new_log.file = ngx_conf_open_file(cycle, &error_log);
-        if (cycle->new_log.file == NULL) {
-            goto failed;
-        }
+    if (ngx_log_open_default(cycle) != NGX_OK) {
+        goto failed;
     }
 
     /* open the new files */
@@ -500,13 +493,15 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
                     continue;
                 }
 
-                if (ngx_cmp_sockaddr(nls[n].sockaddr, ls[i].sockaddr) == NGX_OK)
+                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[n].backlog != nls[i].backlog) {
+                    if (ls[i].backlog != nls[n].backlog) {
                         nls[n].listen = 1;
                     }
 
@@ -537,7 +532,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
 
 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
 
-                    if (ls[n].deferred_accept && !nls[n].deferred_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)
@@ -549,8 +544,18 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
                 }
             }
 
-            if (nls[n].fd == -1) {
+            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
             }
         }
 
@@ -582,12 +587,8 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
 
     /* commit the new cycle configuration */
 
-    if (!ngx_use_stderr && cycle->log->file->fd != ngx_stderr) {
-
-        if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
-            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
-                          ngx_set_stderr_n " failed");
-        }
+    if (!ngx_use_stderr) {
+        (void) ngx_log_redirect_stderr(cycle);
     }
 
     pool->log = cycle->log;
@@ -659,7 +660,7 @@ old_shm_zone_done:
     ls = old_cycle->listening.elts;
     for (i = 0; i < old_cycle->listening.nelts; i++) {
 
-        if (ls[i].remain || ls[i].fd == -1) {
+        if (ls[i].remain || ls[i].fd == (ngx_socket_t) -1) {
             continue;
         }
 
@@ -823,7 +824,7 @@ failed:
 
     ls = cycle->listening.elts;
     for (i = 0; i < cycle->listening.nelts; i++) {
-        if (ls[i].fd == -1 || !ls[i].open) {
+        if (ls[i].fd == (ngx_socket_t) -1 || !ls[i].open) {
             continue;
         }
 
@@ -849,74 +850,6 @@ ngx_destroy_cycle_pools(ngx_conf_t *conf)
 
 
 static ngx_int_t
-ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2)
-{
-    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 (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:
-       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 (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;
-}
-
-
-static ngx_int_t
 ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *zn)
 {
     u_char           *file;
@@ -1171,6 +1104,8 @@ ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
                                   ngx_close_file_n " \"%s\" failed",
                                   file[i].name.data);
                 }
+
+                continue;
             }
 
             if (fi.st_uid != user) {
@@ -1184,6 +1119,8 @@ ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
                                       ngx_close_file_n " \"%s\" failed",
                                       file[i].name.data);
                     }
+
+                    continue;
                 }
             }
 
@@ -1200,6 +1137,8 @@ ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
                                       ngx_close_file_n " \"%s\" failed",
                                       file[i].name.data);
                     }
+
+                    continue;
                 }
             }
         }
@@ -1228,16 +1167,7 @@ ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
         file[i].fd = fd;
     }
 
-#if !(NGX_WIN32)
-
-    if (cycle->log->file->fd != STDERR_FILENO) {
-        if (dup2(cycle->log->file->fd, STDERR_FILENO) == -1) {
-            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
-                          "dup2(STDERR) failed");
-        }
-    }
-
-#endif
+    (void) ngx_log_redirect_stderr(cycle);
 }
 
 

  Renamed: vendor/nginx-1.7.2/src/core/ngx_cycle.h (+2 -0) 97%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_cycle.h    2014-07-02 11:31:57 +0900 (2e4bc4b)
+++ vendor/nginx-1.7.2/src/core/ngx_cycle.h    2014-07-04 15:15:55 +0900 (21bf5ca)
@@ -41,6 +41,8 @@ struct ngx_cycle_s {
     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;

  Renamed: vendor/nginx-1.7.2/src/core/ngx_file.c (+100 -8) 93%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_file.c    2014-07-02 11:31:57 +0900 (35f5f8d)
+++ vendor/nginx-1.7.2/src/core/ngx_file.c    2014-07-04 15:15:55 +0900 (7e6e921)
@@ -9,11 +9,102 @@
 #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)
 {
@@ -268,9 +359,6 @@ ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         return NULL;
     }
 
-    path->len = 0;
-    path->manager = NULL;
-    path->loader = NULL;
     path->conf_file = cf->conf_file->file.name.data;
     path->line = cf->conf_file->line;
 
@@ -311,7 +399,7 @@ ngx_conf_merge_path_value(ngx_conf_t *cf, ngx_path_t **path, ngx_path_t *prev,
         return NGX_CONF_OK;
     }
 
-    *path = ngx_palloc(cf->pool, sizeof(ngx_path_t));
+    *path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
     if (*path == NULL) {
         return NGX_CONF_ERROR;
     }
@@ -330,10 +418,6 @@ ngx_conf_merge_path_value(ngx_conf_t *cf, ngx_path_t **path, ngx_path_t *prev,
                    + init->level[1] + (init->level[1] ? 1 : 0)
                    + init->level[2] + (init->level[2] ? 1 : 0);
 
-    (*path)->manager = NULL;
-    (*path)->loader = NULL;
-    (*path)->conf_file = NULL;
-
     if (ngx_add_path(cf, path) != NGX_OK) {
         return NGX_CONF_ERROR;
     }
@@ -417,6 +501,14 @@ ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot)
         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) {

  Renamed: vendor/nginx-1.7.2/src/core/ngx_file.h (+3 -0) 97%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_file.h    2014-07-02 11:31:57 +0900 (18abf14)
+++ vendor/nginx-1.7.2/src/core/ngx_file.h    2014-07-04 15:15:55 +0900 (3ea6c28)
@@ -122,6 +122,9 @@ struct ngx_tree_ctx_s {
 };
 
 
+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,

  Renamed: vendor/nginx-1.7.2/src/core/ngx_hash.c (+6 -9) 98%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_hash.c    2014-07-02 11:31:57 +0900 (b532945)
+++ vendor/nginx-1.7.2/src/core/ngx_hash.c    2014-07-04 15:15:55 +0900 (c7bfed7)
@@ -282,7 +282,7 @@ ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
         start = hinit->max_size - 1000;
     }
 
-    for (size = start; size < hinit->max_size; size++) {
+    for (size = start; size <= hinit->max_size; size++) {
 
         ngx_memzero(test, size * sizeof(u_short));
 
@@ -312,15 +312,12 @@ ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
         continue;
     }
 
-    ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0,
-                  "could not build the %s, you should increase "
-                  "either %s_max_size: %i or %s_bucket_size: %i",
+    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);
-
-    ngx_free(test);
-
-    return NGX_ERROR;
+                  hinit->name, hinit->bucket_size, hinit->name);
 
 found:
 

  Renamed: vendor/nginx-1.7.2/src/core/ngx_hash.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_inet.c (+93 -5) 91%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_inet.c    2014-07-02 11:31:57 +0900 (7757ab7)
+++ vendor/nginx-1.7.2/src/core/ngx_inet.c    2014-07-04 15:15:55 +0900 (26c5bc4)
@@ -174,7 +174,8 @@ ngx_inet6_addr(u_char *p, size_t len, u_char *addr)
 
 
 size_t
-ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len, ngx_uint_t port)
+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;
@@ -230,9 +231,18 @@ ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len, ngx_uint_t port)
     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 ngx_snprintf(text, len, "unix:%s%Z", saun->sun_path) - text - 1;
+        return (p - text - 1);
 
 #endif
 
@@ -953,6 +963,9 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
     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";
@@ -1020,7 +1033,7 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
             goto failed;
         }
 
-        len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1);
+        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;
@@ -1053,7 +1066,8 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
             goto failed;
         }
 
-        len = ngx_sock_ntop((struct sockaddr *) sin6, p, len, 1);
+        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;
@@ -1138,7 +1152,8 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
                 return NGX_ERROR;
             }
 
-            len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1);
+            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;
@@ -1181,3 +1196,76 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
 }
 
 #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;
+}

  Renamed: vendor/nginx-1.7.2/src/core/ngx_inet.h (+4 -2) 92%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_inet.h    2014-07-02 11:31:57 +0900 (6a5a368)
+++ vendor/nginx-1.7.2/src/core/ngx_inet.h    2014-07-04 15:15:55 +0900 (0555750)
@@ -107,14 +107,16 @@ in_addr_t ngx_inet_addr(u_char *text, size_t len);
 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, u_char *text, size_t len,
-    ngx_uint_t port);
+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_ */

  Renamed: vendor/nginx-1.7.2/src/core/ngx_list.c (+1 -9) 81%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_list.c    2014-07-02 11:31:57 +0900 (89ea823)
+++ vendor/nginx-1.7.2/src/core/ngx_list.c    2014-07-04 15:15:55 +0900 (d0eb159)
@@ -19,18 +19,10 @@ ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size)
         return NULL;
     }
 
-    list->part.elts = ngx_palloc(pool, n * size);
-    if (list->part.elts == NULL) {
+    if (ngx_list_init(list, pool, n, size) != NGX_OK) {
         return NULL;
     }
 
-    list->part.nelts = 0;
-    list->part.next = NULL;
-    list->last = &list->part;
-    list->size = size;
-    list->nalloc = n;
-    list->pool = pool;
-
     return list;
 }
 

  Renamed: vendor/nginx-1.7.2/src/core/ngx_list.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_log.c (+191 -31) 67%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_log.c    2014-07-02 11:31:57 +0900 (d7830fb)
+++ vendor/nginx-1.7.2/src/core/ngx_log.c    2014-07-04 15:15:55 +0900 (375d52f)
@@ -10,6 +10,8 @@
 
 
 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[] = {
@@ -86,14 +88,11 @@ ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
 #endif
 {
 #if (NGX_HAVE_VARIADIC_MACROS)
-    va_list  args;
+    va_list      args;
 #endif
-    u_char  *p, *last, *msg;
-    u_char   errstr[NGX_MAX_ERROR_STR];
-
-    if (log->file->fd == NGX_INVALID_FILE) {
-        return;
-    }
+    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;
 
@@ -140,11 +139,33 @@ ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
 
     ngx_linefeed(p);
 
-    (void) ngx_write_fd(log->file->fd, errstr, p - errstr);
+    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
-        || log->file->fd == ngx_stderr)
+        || wrote_stderr)
     {
         return;
     }
@@ -348,31 +369,93 @@ ngx_log_init(u_char *prefix)
 }
 
 
-ngx_log_t *
-ngx_log_create(ngx_cycle_t *cycle, ngx_str_t *name)
+ngx_int_t
+ngx_log_open_default(ngx_cycle_t *cycle)
 {
-    ngx_log_t  *log;
+    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;
+    }
 
-    log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t));
-    if (log == NULL) {
-        return NULL;
+    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, name);
+    log->file = ngx_conf_open_file(cycle, &error_log);
     if (log->file == NULL) {
-        return NULL;
+        return NGX_ERROR;
     }
 
-    return log;
+    return NGX_OK;
 }
 
 
-char *
+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++) {
@@ -428,32 +511,109 @@ ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log)
 static char *
 ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
-    ngx_str_t  *value, name;
+    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 (cf->cycle->new_log.file) {
-        return "is duplicate";
+        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 {
-        name = value[1];
+        new_log->file = ngx_conf_open_file(cf->cycle, &value[1]);
+        if (new_log->file == NULL) {
+            return NGX_CONF_ERROR;
+        }
     }
 
-    cf->cycle->new_log.file = ngx_conf_open_file(cf->cycle, &name);
-    if (cf->cycle->new_log.file == NULL) {
-        return NULL;
+    if (ngx_log_set_levels(cf, new_log) != NGX_CONF_OK) {
+        return NGX_CONF_ERROR;
     }
 
-    if (cf->args->nelts == 2) {
-        cf->cycle->new_log.log_level = NGX_LOG_ERR;
-        return NGX_CONF_OK;
+    if (*head != new_log) {
+        ngx_log_insert(*head, new_log);
     }
 
-    cf->cycle->new_log.log_level = 0;
+    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;
+    }
 
-    return ngx_log_set_levels(cf, &cf->cycle->new_log);
+    log->next = new_log;
 }

  Renamed: vendor/nginx-1.7.2/src/core/ngx_log.h (+11 -2) 95%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_log.h    2014-07-02 11:31:57 +0900 (3233647)
+++ vendor/nginx-1.7.2/src/core/ngx_log.h    2014-07-04 15:15:55 +0900 (c1a52c4)
@@ -43,6 +43,8 @@
 
 
 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 {
@@ -54,6 +56,9 @@ struct ngx_log_s {
     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
@@ -61,6 +66,8 @@ struct ngx_log_s {
      */
 
     char                *action;
+
+    ngx_log_t           *next;
 };
 
 
@@ -220,11 +227,13 @@ void ngx_cdecl ngx_log_debug_core(ngx_log_t *log, ngx_err_t err,
 /*********************************/
 
 ngx_log_t *ngx_log_init(u_char *prefix);
-ngx_log_t *ngx_log_create(ngx_cycle_t *cycle, ngx_str_t *name);
-char *ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log);
 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);
 
 
 /*

  Renamed: vendor/nginx-1.7.2/src/core/ngx_md5.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_md5.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_murmurhash.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_murmurhash.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_open_file_cache.c (+67 -1) 93%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_open_file_cache.c    2014-07-02 11:31:57 +0900 (c44ac96)
+++ vendor/nginx-1.7.2/src/core/ngx_open_file_cache.c    2014-07-04 15:15:55 +0900 (4df2134)
@@ -25,6 +25,10 @@ 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,
@@ -124,7 +128,7 @@ ngx_open_file_cache_cleanup(void *data)
 
     if (cache->current) {
         ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
-                      "%d items still leave in open file cache",
+                      "%ui items still leave in open file cache",
                       cache->current);
     }
 
@@ -517,10 +521,17 @@ ngx_openat_file_owner(ngx_fd_t at_fd, const u_char *name,
         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;
@@ -541,8 +552,63 @@ failed:
     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,

  Renamed: vendor/nginx-1.7.2/src/core/ngx_open_file_cache.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_output_chain.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_palloc.c (+5 -2) 99%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_palloc.c    2014-07-02 11:31:57 +0900 (efbc244)
+++ vendor/nginx-1.7.2/src/core/ngx_palloc.c    2014-07-04 15:15:55 +0900 (1f70f9e)
@@ -105,11 +105,14 @@ ngx_reset_pool(ngx_pool_t *pool)
         }
     }
 
-    pool->large = NULL;
-
     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;
 }
 
 

  Renamed: vendor/nginx-1.7.2/src/core/ngx_palloc.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_parse.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_parse.h (+0 -0) 100%
===================================================================

  Added: vendor/nginx-1.7.2/src/core/ngx_proxy_protocol.c (+91 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.7.2/src/core/ngx_proxy_protocol.c    2014-07-04 15:15:55 +0900 (59ef010)
@@ -0,0 +1,91 @@
+
+/*
+ * 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;
+}

  Added: vendor/nginx-1.7.2/src/core/ngx_proxy_protocol.h (+23 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.7.2/src/core/ngx_proxy_protocol.h    2014-07-04 15:15:55 +0900 (4f39125)
@@ -0,0 +1,23 @@
+
+/*
+ * 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_ */

  Renamed: vendor/nginx-1.7.2/src/core/ngx_queue.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_queue.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_radix_tree.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_radix_tree.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_rbtree.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_rbtree.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_regex.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_regex.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_resolver.c (+1080 -285) 59%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_resolver.c    2014-07-02 11:31:57 +0900 (d59d0c4)
+++ vendor/nginx-1.7.2/src/core/ngx_resolver.c    2014-07-04 15:15:55 +0900 (645738c)
@@ -26,7 +26,7 @@ typedef struct {
     u_char  nns_lo;
     u_char  nar_hi;
     u_char  nar_lo;
-} ngx_resolver_query_t;
+} ngx_resolver_hdr_t;
 
 
 typedef struct {
@@ -70,7 +70,8 @@ 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 nan, ngx_uint_t ans);
+    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,
@@ -88,10 +89,17 @@ 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 in_addr_t *ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src,
-    ngx_uint_t n);
+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)
@@ -134,6 +142,17 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
     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;
@@ -171,6 +190,25 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
             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];
@@ -220,6 +258,10 @@ ngx_resolver_cleanup(void *data)
 
         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);
         }
@@ -281,7 +323,11 @@ ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp)
             temp->state = NGX_OK;
             temp->naddrs = 1;
             temp->addrs = &temp->addr;
-            temp->addr = 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;
@@ -310,6 +356,10 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx)
 
     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);
 
@@ -411,18 +461,18 @@ done:
 }
 
 
-/* NGX_RESOLVE_A only */
-
 static ngx_int_t
 ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
 {
     uint32_t              hash;
-    in_addr_t             addr, *addrs;
     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);
@@ -439,22 +489,21 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
 
             ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
 
-            naddrs = rn->naddrs;
+            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) {
 
-                /* NGX_RESOLVE_A answer */
+                if (naddrs == 1 && rn->naddrs == 1) {
+                    addrs = NULL;
 
-                if (naddrs != 1) {
-                    addr = 0;
-                    addrs = ngx_resolver_rotate(r, rn->u.addrs, naddrs);
+                } else {
+                    addrs = ngx_resolver_export(r, rn, 1);
                     if (addrs == NULL) {
                         return NGX_ERROR;
                     }
-
-                } else {
-                    addr = rn->u.addr;
-                    addrs = NULL;
                 }
 
                 ctx->next = rn->waiting;
@@ -465,8 +514,19 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
                 do {
                     ctx->state = NGX_OK;
                     ctx->naddrs = naddrs;
-                    ctx->addrs = (naddrs == 1) ? &ctx->addr : addrs;
-                    ctx->addr = addr;
+
+                    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);
@@ -474,7 +534,8 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
                     ctx = next;
                 } while (ctx);
 
-                if (addrs) {
+                if (addrs != NULL) {
+                    ngx_resolver_free(r, addrs->sockaddr);
                     ngx_resolver_free(r, addrs);
                 }
 
@@ -524,16 +585,25 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
         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) {
+        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 {
@@ -552,6 +622,9 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
         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);
     }
@@ -575,6 +648,11 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *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;
     }
@@ -601,9 +679,10 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
 
     ngx_queue_insert_head(&r->name_resend_queue, &rn->queue);
 
+    rn->code = 0;
     rn->cnlen = 0;
-    rn->naddrs = 0;
     rn->valid = 0;
+    rn->ttl = NGX_MAX_UINT32_VALUE;
     rn->waiting = ctx;
 
     ctx->state = NGX_AGAIN;
@@ -630,16 +709,57 @@ 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;
 
-    ctx->addr = ntohl(ctx->addr);
+    switch (ctx->addr.sockaddr->sa_family) {
 
-    /* lock addr mutex */
+#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);
 
-    rn = ngx_resolver_lookup_addr(r, ctx->addr);
+        tree = &r->addr_rbtree;
+        resend_queue = &r->addr_resend_queue;
+        expire_queue = &r->addr_expire_queue;
+    }
 
     if (rn) {
 
@@ -651,7 +771,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
 
             rn->expire = ngx_time() + r->expire;
 
-            ngx_queue_insert_head(&r->addr_expire_queue, &rn->queue);
+            ngx_queue_insert_head(expire_queue, &rn->queue);
 
             name = ngx_resolver_dup(r, rn->name, rn->nlen);
             if (name == NULL) {
@@ -687,6 +807,9 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
 
         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));
@@ -694,16 +817,36 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
             goto failed;
         }
 
-        rn->node.key = ctx->addr;
+        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(&r->addr_rbtree, &rn->node);
+        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;
     }
@@ -720,19 +863,20 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
 
     ngx_add_timer(ctx->event, ctx->timeout);
 
-    if (ngx_queue_empty(&r->addr_resend_queue)) {
+    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(&r->addr_resend_queue, &rn->queue);
+    ngx_queue_insert_head(resend_queue, &rn->queue);
 
+    rn->code = 0;
     rn->cnlen = 0;
-    rn->naddrs = 0;
     rn->name = NULL;
     rn->nlen = 0;
     rn->valid = 0;
+    rn->ttl = NGX_MAX_UINT32_VALUE;
     rn->waiting = ctx;
 
     /* unlock addr mutex */
@@ -744,7 +888,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
 failed:
 
     if (rn) {
-        ngx_rbtree_delete(&r->addr_rbtree, &rn->node);
+        ngx_rbtree_delete(tree, &rn->node);
 
         if (rn->query) {
             ngx_resolver_free(r, rn->query);
@@ -769,12 +913,33 @@ 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);
 
@@ -786,7 +951,21 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
 
     if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
 
-        rn = ngx_resolver_lookup_addr(r, ctx->addr);
+        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;
@@ -804,17 +983,22 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
             }
         }
 
-        addr = ntohl(ctx->addr);
+        {
+            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 %ud.%ud.%ud.%ud resolving",
-                      (addr >> 24) & 0xff, (addr >> 16) & 0xff,
-                      (addr >> 8) & 0xff, addr & 0xff);
+            ngx_log_error(NGX_LOG_ALERT, r->log, 0,
+                          "could not cancel %V resolving", &addrtext);
+        }
     }
 
 done:
 
-    ngx_resolver_expire(r, &r->addr_rbtree, &r->addr_expire_queue);
+    ngx_resolver_expire(r, tree, expire_queue);
 
     /* unlock addr mutex */
 
@@ -896,16 +1080,33 @@ ngx_resolver_send_query(ngx_resolver_t *r, ngx_resolver_node_t *rn)
         uc->connection->read->resolver = 1;
     }
 
-    n = ngx_send(uc->connection, rn->query, rn->qlen);
+    if (rn->naddrs == (u_short) -1) {
+        n = ngx_send(uc->connection, rn->query, rn->qlen);
 
-    if (n == -1) {
-        return NGX_ERROR;
+        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 ((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;
 }
@@ -915,6 +1116,9 @@ 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;
@@ -934,16 +1138,36 @@ ngx_resolver_resend_handler(ngx_event_t *ev)
 
     /* unlock addr mutex */
 
-    if (ntimer == 0) {
+#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 == 0) {
-        timer = ntimer;
+    } else if (atimer) {
+        timer = ngx_min(timer, atimer);
+    }
+
+#if (NGX_HAVE_INET6)
 
-    } else {
-        timer = (atimer < ntimer) ? atimer : ntimer;
+    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));
     }
@@ -1021,39 +1245,42 @@ ngx_resolver_read_response(ngx_event_t *rev)
 static void
 ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
 {
-    char                  *err;
-    size_t                 len;
-    ngx_uint_t             i, times, ident, qident, flags, code, nqs, nan,
-                           qtype, qclass;
-    ngx_queue_t           *q;
-    ngx_resolver_qs_t     *qs;
-    ngx_resolver_node_t   *rn;
-    ngx_resolver_query_t  *query;
-
-    if ((size_t) n < sizeof(ngx_resolver_query_t)) {
+    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;
     }
 
-    query = (ngx_resolver_query_t *) buf;
+    response = (ngx_resolver_hdr_t *) buf;
 
-    ident = (query->ident_hi << 8) + query->ident_lo;
-    flags = (query->flags_hi << 8) + query->flags_lo;
-    nqs = (query->nqs_hi << 8) + query->nqs_lo;
-    nan = (query->nan_hi << 8) + query->nan_lo;
+    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,
-                   (query->nns_hi << 8) + query->nns_lo,
-                   (query->nar_hi << 8) + query->nar_lo);
+                   (response->nns_hi << 8) + response->nns_lo,
+                   (response->nar_hi << 8) + response->nar_lo);
 
-    if (!(flags & 0x8000)) {
+    /* 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 & 0x7f;
+    code = flags & 0xf;
 
     if (code == NGX_RESOLVE_FORMERR) {
 
@@ -1067,12 +1294,18 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
             qident = (rn->query[0] << 8) + rn->query[1];
 
             if (qident == ident) {
-                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;
+                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;
@@ -1087,22 +1320,21 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
         goto done;
     }
 
-    i = sizeof(ngx_resolver_query_t);
+    i = sizeof(ngx_resolver_hdr_t);
 
     while (i < (ngx_uint_t) n) {
         if (buf[i] == '\0') {
             goto found;
         }
 
-        len = buf[i];
-        i += 1 + len;
+        i += 1 + buf[i];
     }
 
     goto short_response;
 
 found:
 
-    if (i++ == 0) {
+    if (i++ == sizeof(ngx_resolver_hdr_t)) {
         err = "zero-length domain name in DNS response";
         goto done;
     }
@@ -1130,8 +1362,11 @@ found:
     switch (qtype) {
 
     case NGX_RESOLVE_A:
+#if (NGX_HAVE_INET6)
+    case NGX_RESOLVE_AAAA:
+#endif
 
-        ngx_resolver_process_a(r, buf, n, ident, code, nan,
+        ngx_resolver_process_a(r, buf, n, ident, code, qtype, nan,
                                i + sizeof(ngx_resolver_qs_t));
 
         break;
@@ -1152,7 +1387,7 @@ found:
 
 short_response:
 
-    err = "short dns response";
+    err = "short DNS response";
 
 done:
 
@@ -1160,6 +1395,14 @@ done:
 
     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,
@@ -1171,21 +1414,29 @@ dns_error:
 
 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 nan, ngx_uint_t ans)
+    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, *addrs;
+    in_addr_t            *addr;
     ngx_str_t             name;
-    ngx_uint_t            qtype, qident, naddrs, a, i, n, start;
+    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[12], &buf[last]) != NGX_OK) {
+    if (ngx_resolver_copy(r, &name, buf,
+                          buf + sizeof(ngx_resolver_hdr_t), buf + last)
+        != NGX_OK)
+    {
         return;
     }
 
@@ -1197,28 +1448,113 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
 
     rn = ngx_resolver_lookup_name(r, &name, hash);
 
-    if (rn == NULL || rn->query == NULL) {
+    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;
     }
 
-    qident = (rn->query[0] << 8) + rn->query[1];
+    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) {
-        code = 3; /* NXDOMAIN */
+
+#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;
 
@@ -1231,11 +1567,11 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
         /* unlock name mutex */
 
         while (next) {
-             ctx = next;
-             ctx->state = code;
-             next = ctx->next;
+            ctx = next;
+            ctx->state = code;
+            next = ctx->next;
 
-             ctx->handler(ctx);
+            ctx->handler(ctx);
         }
 
         return;
@@ -1243,11 +1579,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
 
     i = ans;
     naddrs = 0;
-    addr = 0;
-    addrs = NULL;
     cname = NULL;
-    qtype = 0;
-    ttl = 0;
 
     for (a = 0; a < nan; a++) {
 
@@ -1273,7 +1605,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
     test_length:
 
         if (i - start < 2) {
-            err = "invalid name in dns response";
+            err = "invalid name in DNS response";
             goto invalid;
         }
 
@@ -1285,150 +1617,299 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
 
         an = (ngx_resolver_an_t *) &buf[i];
 
-        qtype = (an->type_hi << 8) + an->type_lo;
+        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;
         }
 
-        if (qtype == NGX_RESOLVE_A) {
+        rn->ttl = ngx_min(rn->ttl, (uint32_t) ttl);
 
-            i += sizeof(ngx_resolver_an_t);
+        i += sizeof(ngx_resolver_an_t);
 
-            if (i + len > last) {
+        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;
             }
 
-            addr = htonl((buf[i] << 24) + (buf[i + 1] << 16)
-                         + (buf[i + 2] << 8) + (buf[i + 3]));
+            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++;
 
-            i += len;
+            break;
+#endif
 
-        } else if (qtype == NGX_RESOLVE_CNAME) {
-            cname = &buf[i] + sizeof(ngx_resolver_an_t);
-            i += sizeof(ngx_resolver_an_t) + len;
+        case NGX_RESOLVE_CNAME:
 
-        } else if (qtype == NGX_RESOLVE_DNAME) {
-            i += sizeof(ngx_resolver_an_t) + len;
+            cname = &buf[i];
+
+            break;
+
+        case NGX_RESOLVE_DNAME:
+
+            break;
+
+        default:
 
-        } else {
             ngx_log_error(r->log_level, r->log, 0,
-                          "unexpected qtype %ui", qtype);
+                          "unexpected RR type %ui", type);
         }
+
+        i += len;
     }
 
     ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
-                   "resolver naddrs:%ui cname:%p ttl:%d",
-                   naddrs, cname, ttl);
+                   "resolver naddrs:%ui cname:%p ttl:%uD",
+                   naddrs, cname, rn->ttl);
 
     if (naddrs) {
 
-        if (naddrs == 1) {
-            rn->u.addr = addr;
+        switch (qtype) {
 
-        } else {
+#if (NGX_HAVE_INET6)
+        case NGX_RESOLVE_AAAA:
 
-            addrs = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t));
-            if (addrs == NULL) {
-                return;
-            }
+            if (naddrs == 1) {
+                addr6 = &rn->u6.addr6;
+                rn->naddrs6 = 1;
 
-            n = 0;
-            i = ans;
+            } else {
+                addr6 = ngx_resolver_alloc(r, naddrs * sizeof(struct in6_addr));
+                if (addr6 == NULL) {
+                    goto failed;
+                }
 
-            for (a = 0; a < nan; a++) {
+                rn->u6.addrs6 = addr6;
+                rn->naddrs6 = (u_short) naddrs;
+            }
 
-                for ( ;; ) {
+#if (NGX_SUPPRESS_WARN)
+            addr = NULL;
+#endif
 
-                    if (buf[i] & 0xc0) {
-                        i += 2;
-                        goto ok;
-                    }
+            break;
+#endif
 
-                    if (buf[i] == 0) {
-                        i++;
-                        goto ok;
-                    }
+        default: /* NGX_RESOLVE_A */
+
+            if (naddrs == 1) {
+                addr = &rn->u.addr;
+                rn->naddrs = 1;
 
-                    i += 1 + buf[i];
+            } else {
+                addr = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t));
+                if (addr == NULL) {
+                    goto failed;
                 }
 
-            ok:
+                rn->u.addrs = addr;
+                rn->naddrs = (u_short) naddrs;
+            }
 
-                an = (ngx_resolver_an_t *) &buf[i];
+#if (NGX_HAVE_INET6 && NGX_SUPPRESS_WARN)
+            addr6 = NULL;
+#endif
+        }
 
-                qtype = (an->type_hi << 8) + an->type_lo;
-                len = (an->len_hi << 8) + an->len_lo;
+        n = 0;
+        i = ans;
 
-                i += sizeof(ngx_resolver_an_t);
+        for (a = 0; a < nan; a++) {
 
-                if (qtype == NGX_RESOLVE_A) {
+            for ( ;; ) {
 
-                    addrs[n++] = htonl((buf[i] << 24) + (buf[i + 1] << 16)
-                                       + (buf[i + 2] << 8) + (buf[i + 3]));
+                if (buf[i] & 0xc0) {
+                    i += 2;
+                    break;
+                }
 
-                    if (n == naddrs) {
-                        break;
-                    }
+                if (buf[i] == 0) {
+                    i++;
+                    break;
                 }
 
-                i += len;
+                i += 1 + buf[i];
             }
 
-            rn->u.addrs = addrs;
+            an = (ngx_resolver_an_t *) &buf[i];
 
-            addrs = ngx_resolver_dup(r, rn->u.addrs,
-                                     naddrs * sizeof(in_addr_t));
-            if (addrs == NULL) {
-                return;
-            }
-        }
+            type = (an->type_hi << 8) + an->type_lo;
+            len = (an->len_hi << 8) + an->len_lo;
 
-        rn->naddrs = (u_short) naddrs;
+            i += sizeof(ngx_resolver_an_t);
 
-        ngx_queue_remove(&rn->queue);
+            if (type == NGX_RESOLVE_A) {
 
-        rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
-        rn->expire = ngx_time() + r->expire;
+                addr[n] = htonl((buf[i] << 24) + (buf[i + 1] << 16)
+                                + (buf[i + 2] << 8) + (buf[i + 3]));
 
-        ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
+                if (++n == naddrs) {
 
-        next = rn->waiting;
-        rn->waiting = NULL;
+#if (NGX_HAVE_INET6)
+                    if (rn->naddrs6 == (u_short) -1) {
+                        goto next;
+                    }
+#endif
 
-        /* unlock name mutex */
+                    break;
+                }
+            }
 
-        while (next) {
-             ctx = next;
-             ctx->state = NGX_OK;
-             ctx->naddrs = naddrs;
-             ctx->addrs = (naddrs == 1) ? &ctx->addr : addrs;
-             ctx->addr = addr;
-             next = ctx->next;
+#if (NGX_HAVE_INET6)
+            else if (type == NGX_RESOLVE_AAAA) {
 
-             ctx->handler(ctx);
-        }
+                ngx_memcpy(addr6[n].s6_addr, &buf[i], 16);
 
-        if (naddrs > 1) {
-            ngx_resolver_free(r, addrs);
-        }
+                if (++n == naddrs) {
 
-        ngx_resolver_free(r, rn->query);
+                    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;
+    }
 
-    } else if (cname) {
+    if (cname) {
 
         /* CNAME only */
 
-        if (ngx_resolver_copy(r, &name, buf, cname, &buf[last]) != NGX_OK) {
-            return;
+        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,
@@ -1439,7 +1920,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
         rn->cnlen = (u_short) name.len;
         rn->u.cname = name.data;
 
-        rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
+        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);
@@ -1455,18 +1936,22 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
 
         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 responses, unknown query type: %ui",
-               qtype);
+                  "no A or CNAME types in DNS response");
     return;
 
 short_response:
 
-    err = "short dns response";
+    err = "short DNS response";
 
 invalid:
 
@@ -1478,9 +1963,9 @@ invalid:
 
 failed:
 
-    /* unlock name mutex */
+next:
 
-    ngx_resolver_free(r, name.data);
+    /* unlock name mutex */
 
     return;
 }
@@ -1492,47 +1977,123 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
 {
     char                 *err;
     size_t                len;
+    u_char                text[NGX_SOCKADDR_STRLEN];
     in_addr_t             addr;
     int32_t               ttl;
-    ngx_int_t             digit;
+    ngx_int_t             octet;
     ngx_str_t             name;
-    ngx_uint_t            i, mask, qident;
+    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[12], &buf[n]) != NGX_OK) {
-        goto invalid_in_addr_arpa;
+    if (ngx_resolver_copy(r, NULL, buf,
+                          buf + sizeof(ngx_resolver_hdr_t), buf + n)
+        != NGX_OK)
+    {
+        return;
     }
 
+    /* AF_INET */
+
     addr = 0;
-    i = 12;
+    i = sizeof(ngx_resolver_hdr_t);
 
     for (mask = 0; mask < 32; mask += 8) {
         len = buf[i++];
 
-        digit = ngx_atoi(&buf[i], len);
-        if (digit == NGX_ERROR || digit > 255) {
+        octet = ngx_atoi(&buf[i], len);
+        if (octet == NGX_ERROR || octet > 255) {
             goto invalid_in_addr_arpa;
         }
 
-        addr += digit << mask;
+        addr += octet << mask;
         i += len;
     }
 
-    if (ngx_strcmp(&buf[i], "\7in-addr\4arpa") != 0) {
-        goto invalid_in_addr_arpa;
+    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);
     }
 
-    /* lock addr mutex */
+    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
 
-    rn = ngx_resolver_lookup_addr(r, addr);
+    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 %ud.%ud.%ud.%ud",
-                      (addr >> 24) & 0xff, (addr >> 16) & 0xff,
-                      (addr >> 8) & 0xff, addr & 0xff);
+                      "unexpected response for %V", &name);
         goto failed;
     }
 
@@ -1540,14 +2101,13 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
 
     if (ident != qident) {
         ngx_log_error(r->log_level, r->log, 0,
-                    "wrong ident %ui response for %ud.%ud.%ud.%ud, expect %ui",
-                    ident, (addr >> 24) & 0xff, (addr >> 16) & 0xff,
-                    (addr >> 8) & 0xff, addr & 0xff, qident);
+                      "wrong ident %ui response for %V, expect %ui",
+                      ident, &name, qident);
         goto failed;
     }
 
     if (code == 0 && nan == 0) {
-        code = 3; /* NXDOMAIN */
+        code = NGX_RESOLVE_NXDOMAIN;
     }
 
     if (code) {
@@ -1556,42 +2116,49 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
 
         ngx_queue_remove(&rn->queue);
 
-        ngx_rbtree_delete(&r->addr_rbtree, &rn->node);
+        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 = next;
+            ctx->state = code;
+            next = ctx->next;
 
-             ctx->handler(ctx);
+            ctx->handler(ctx);
         }
 
         return;
     }
 
-    i += sizeof("\7in-addr\4arpa") + sizeof(ngx_resolver_qs_t);
+    i += sizeof(ngx_resolver_qs_t);
 
-    if (i + 2 + sizeof(ngx_resolver_an_t) > (ngx_uint_t) n) {
+    if (i + 2 + sizeof(ngx_resolver_an_t) >= n) {
         goto short_response;
     }
 
-    /* compression pointer to "XX.XX.XX.XX.in-addr.arpa */
+    /* compression pointer to *.arpa */
 
-    if (buf[i] != 0xc0 || buf[i + 1] != 0x0c) {
-        err = "invalid in-addr.arpa name in DNS response";
+    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;
     }
@@ -1599,16 +2166,16 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
     ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
                   "resolver qt:%ui cl:%ui len:%uz",
                   (an->type_hi << 8) + an->type_lo,
-                  (an->class_hi << 8) + an->class_lo, len);
+                  class, len);
 
     i += 2 + sizeof(ngx_resolver_an_t);
 
-    if (i + len > (ngx_uint_t) n) {
+    if (i + len > n) {
         goto short_response;
     }
 
-    if (ngx_resolver_copy(r, &name, buf, &buf[i], &buf[n]) != NGX_OK) {
-        return;
+    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);
@@ -1634,7 +2201,7 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
     rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
     rn->expire = ngx_time() + r->expire;
 
-    ngx_queue_insert_head(&r->addr_expire_queue, &rn->queue);
+    ngx_queue_insert_head(expire_queue, &rn->queue);
 
     next = rn->waiting;
     rn->waiting = NULL;
@@ -1642,24 +2209,18 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
     /* unlock addr mutex */
 
     while (next) {
-         ctx = next;
-         ctx->state = NGX_OK;
-         ctx->name = name;
-         next = ctx->next;
+        ctx = next;
+        ctx->state = NGX_OK;
+        ctx->name = name;
+        next = ctx->next;
 
-         ctx->handler(ctx);
+        ctx->handler(ctx);
     }
 
     ngx_resolver_free(r, name.data);
 
     return;
 
-invalid_in_addr_arpa:
-
-    ngx_log_error(r->log_level, r->log, 0,
-                  "invalid in-addr.arpa name in DNS response");
-    return;
-
 short_response:
 
     err = "short DNS response";
@@ -1752,6 +2313,52 @@ ngx_resolver_lookup_addr(ngx_resolver_t *r, in_addr_t addr)
 }
 
 
+#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)
@@ -1793,20 +2400,74 @@ ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp,
 }
 
 
+#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;
-    ngx_resolver_qs_t     *qs;
-    ngx_resolver_query_t  *query;
+    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_query_t) + nlen + sizeof(ngx_resolver_qs_t);
+    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;
     }
@@ -1814,12 +2475,18 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
     rn->qlen = (u_short) len;
     rn->query = p;
 
-    query = (ngx_resolver_query_t *) 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\" %i", &ctx->name, ident & 0xffff);
+                   "resolve: \"%V\" A %i", &ctx->name, ident & 0xffff);
 
     query->ident_hi = (u_char) ((ident >> 8) & 0xff);
     query->ident_lo = (u_char) (ident & 0xff);
@@ -1833,14 +2500,14 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
     query->nns_hi = 0; query->nns_lo = 0;
     query->nar_hi = 0; query->nar_lo = 0;
 
-    p += sizeof(ngx_resolver_query_t) + nlen;
+    p += sizeof(ngx_resolver_hdr_t) + nlen;
 
     qs = (ngx_resolver_qs_t *) p;
 
     /* query type */
-    qs->type_hi = 0; qs->type_lo = (u_char) ctx->type;
+    qs->type_hi = 0; qs->type_lo = NGX_RESOLVE_A;
 
-    /* IP query class */
+    /* IN query class */
     qs->class_hi = 0; qs->class_lo = 1;
 
     /* convert "www.example.com" to "\3www\7example\3com\0" */
@@ -1876,24 +2543,66 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
 
     *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;
 }
 
 
-/* AF_INET only */
-
 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;
-    ngx_int_t              n;
-    ngx_uint_t             ident;
-    ngx_resolver_query_t  *query;
+    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) {
 
-    len = sizeof(ngx_resolver_query_t)
-          + sizeof(".255.255.255.255.in-addr.arpa.") - 1
-          + sizeof(ngx_resolver_qs_t);
+#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) {
@@ -1901,7 +2610,7 @@ ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
     }
 
     rn->query = p;
-    query = (ngx_resolver_query_t *) p;
+    query = (ngx_resolver_hdr_t *) p;
 
     ident = ngx_random();
 
@@ -1917,20 +2626,43 @@ ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
     query->nns_hi = 0; query->nns_lo = 0;
     query->nar_hi = 0; query->nar_lo = 0;
 
-    p += sizeof(ngx_resolver_query_t);
+    p += sizeof(ngx_resolver_hdr_t);
+
+    switch (ctx->addr.sockaddr->sa_family) {
 
-    for (n = 0; n < 32; n += 8) {
-        d = ngx_sprintf(&p[1], "%ud", (ctx->addr >> n) & 0xff);
-        *p = (u_char) (d - &p[1]);
-        p = d;
+#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", IP query class */
-    ngx_memcpy(p, "\7in-addr\4arpa\0\0\14\0\1", 18);
+    /* query type "PTR", IN query class */
+    p = ngx_cpymem(p, "\0\14\0\1", 4);
 
-    rn->qlen = (u_short)
-                  (p + sizeof("\7in-addr\4arpa") + sizeof(ngx_resolver_qs_t)
-                   - rn->query);
+    rn->qlen = (u_short) (p - rn->query);
 
     return NGX_OK;
 }
@@ -2012,7 +2744,7 @@ done:
             n = *src++;
 
         } else {
-            ngx_memcpy(dst, src, n);
+            ngx_strlow(dst, src, n);
             dst += n;
             src += n;
 
@@ -2061,10 +2793,16 @@ ngx_resolver_free_node(ngx_resolver_t *r, ngx_resolver_node_t *rn)
         ngx_resolver_free_locked(r, rn->u.cname);
     }
 
-    if (rn->naddrs > 1) {
+    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 */
@@ -2136,27 +2874,84 @@ ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size)
 }
 
 
-static in_addr_t *
-ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src, ngx_uint_t n)
+static ngx_addr_t *
+ngx_resolver_export(ngx_resolver_t *r, ngx_resolver_node_t *rn,
+    ngx_uint_t rotate)
 {
-    void        *dst, *p;
-    ngx_uint_t   j;
+    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
 
-    dst = ngx_resolver_alloc(r, n * sizeof(in_addr_t));
+    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 dst;
+        return NULL;
     }
 
-    j = ngx_random() % n;
+    sockaddr = ngx_resolver_calloc(r, n * NGX_SOCKADDRLEN);
+    if (sockaddr == NULL) {
+        ngx_resolver_free(r, dst);
+        return NULL;
+    }
 
-    if (j == 0) {
-        ngx_memcpy(dst, src, n * sizeof(in_addr_t));
-        return dst;
+    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);
     }
 
-    p = ngx_cpymem(dst, &src[j], (n - j) * sizeof(in_addr_t));
-    ngx_memcpy(p, src, j * sizeof(in_addr_t));
+#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;
 }
@@ -2221,7 +3016,7 @@ ngx_udp_connect(ngx_udp_connection_t *uc)
 
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &uc->log, 0, "UDP socket %d", s);
 
-    if (s == -1) {
+    if (s == (ngx_socket_t) -1) {
         ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno,
                       ngx_socket_n " failed");
         return NGX_ERROR;
@@ -2242,14 +3037,7 @@ ngx_udp_connect(ngx_udp_connection_t *uc)
         ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno,
                       ngx_nonblocking_n " failed");
 
-        ngx_free_connection(c);
-
-        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;
+        goto failed;
     }
 
     rev = c->read;
@@ -2274,7 +3062,7 @@ ngx_udp_connect(ngx_udp_connection_t *uc)
 #endif
 
     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, &uc->log, 0,
-                   "connect to %V, fd:%d #%d", &uc->server, s, c->number);
+                   "connect to %V, fd:%d #%uA", &uc->server, s, c->number);
 
     rc = connect(s, uc->sockaddr, uc->socklen);
 
@@ -2284,7 +3072,7 @@ ngx_udp_connect(ngx_udp_connection_t *uc)
         ngx_log_error(NGX_LOG_CRIT, &uc->log, ngx_socket_errno,
                       "connect() failed");
 
-        return NGX_ERROR;
+        goto failed;
     }
 
     /* UDP sockets are always ready to write */
@@ -2298,16 +3086,23 @@ ngx_udp_connect(ngx_udp_connection_t *uc)
                     /* eventport event type has no meaning: oneshot only */
 
         if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
-            return NGX_ERROR;
+            goto failed;
         }
 
     } else {
         /* rtsig */
 
         if (ngx_add_conn(c) == NGX_ERROR) {
-            return NGX_ERROR;
+            goto failed;
         }
     }
 
     return NGX_OK;
+
+failed:
+
+    ngx_close_connection(c);
+    uc->connection = NULL;
+
+    return NGX_ERROR;
 }

  Renamed: vendor/nginx-1.7.2/src/core/ngx_resolver.h (+33 -3) 80%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_resolver.h    2014-07-02 11:31:57 +0900 (ae34ca5)
+++ vendor/nginx-1.7.2/src/core/ngx_resolver.h    2014-07-04 15:15:55 +0900 (264c8c4)
@@ -18,6 +18,9 @@
 #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
@@ -54,10 +57,18 @@ typedef struct {
     /* 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;
@@ -65,11 +76,22 @@ typedef struct {
         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;
@@ -100,6 +122,14 @@ typedef struct {
     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;
@@ -117,12 +147,12 @@ struct ngx_resolver_ctx_s {
     ngx_int_t                 ident;
 
     ngx_int_t                 state;
-    ngx_int_t                 type;
     ngx_str_t                 name;
 
     ngx_uint_t                naddrs;
-    in_addr_t                *addrs;
-    in_addr_t                 addr;
+    ngx_addr_t               *addrs;
+    ngx_addr_t                addr;
+    struct sockaddr_in        sin;
 
     ngx_resolver_handler_pt   handler;
     void                     *data;

  Renamed: vendor/nginx-1.7.2/src/core/ngx_sha1.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_shmtx.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_shmtx.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_slab.c (+66 -3) 90%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_slab.c    2014-07-02 11:31:57 +0900 (ae9d6f3)
+++ vendor/nginx-1.7.2/src/core/ngx_slab.c    2014-07-04 15:15:55 +0900 (be3e540)
@@ -129,6 +129,9 @@ ngx_slab_init(ngx_slab_pool_t *pool)
         pool->pages->slab = pages;
     }
 
+    pool->last = pool->pages + pages;
+
+    pool->log_nomem = 1;
     pool->log_ctx = &pool->zero;
     pool->zero = '\0';
 }
@@ -440,7 +443,8 @@ ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
         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 & ~(ngx_pagesize - 1));
+        bitmap = (uintptr_t *)
+                             ((uintptr_t) p & ~((uintptr_t) ngx_pagesize - 1));
 
         if (bitmap[n] & m) {
 
@@ -624,6 +628,8 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
         if (page->slab >= pages) {
 
             if (page->slab > pages) {
+                page[page->slab - 1].prev = (uintptr_t) &page[pages];
+
                 page[pages].slab = page->slab - pages;
                 page[pages].next = page->next;
                 page[pages].prev = page->prev;
@@ -657,7 +663,10 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
         }
     }
 
-    ngx_slab_error(pool, NGX_LOG_CRIT, "ngx_slab_alloc() failed: no memory");
+    if (pool->log_nomem) {
+        ngx_slab_error(pool, NGX_LOG_CRIT,
+                       "ngx_slab_alloc() failed: no memory");
+    }
 
     return NULL;
 }
@@ -667,7 +676,8 @@ 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;
+    ngx_uint_t        type;
+    ngx_slab_page_t  *prev, *join;
 
     page->slab = pages--;
 
@@ -681,6 +691,59 @@ ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
         page->next->prev = page->prev;
     }
 
+    join = page + page->slab;
+
+    if (join < pool->last) {
+        type = join->prev & NGX_SLAB_PAGE_MASK;
+
+        if (type == NGX_SLAB_PAGE) {
+
+            if (join->next != NULL) {
+                pages += join->slab;
+                page->slab += join->slab;
+
+                prev = (ngx_slab_page_t *) (join->prev & ~NGX_SLAB_PAGE_MASK);
+                prev->next = join->next;
+                join->next->prev = join->prev;
+
+                join->slab = NGX_SLAB_PAGE_FREE;
+                join->next = NULL;
+                join->prev = NGX_SLAB_PAGE;
+            }
+        }
+    }
+
+    if (page > pool->pages) {
+        join = page - 1;
+        type = join->prev & NGX_SLAB_PAGE_MASK;
+
+        if (type == NGX_SLAB_PAGE) {
+
+            if (join->slab == NGX_SLAB_PAGE_FREE) {
+                join = (ngx_slab_page_t *) (join->prev & ~NGX_SLAB_PAGE_MASK);
+            }
+
+            if (join->next != NULL) {
+                pages += join->slab;
+                join->slab += page->slab;
+
+                prev = (ngx_slab_page_t *) (join->prev & ~NGX_SLAB_PAGE_MASK);
+                prev->next = join->next;
+                join->next->prev = join->prev;
+
+                page->slab = NGX_SLAB_PAGE_FREE;
+                page->next = NULL;
+                page->prev = NGX_SLAB_PAGE;
+
+                page = join;
+            }
+        }
+    }
+
+    if (pages) {
+        page[pages].prev = (uintptr_t) page;
+    }
+
     page->prev = (uintptr_t) &pool->free;
     page->next = pool->free.next;
 

  Renamed: vendor/nginx-1.7.2/src/core/ngx_slab.h (+3 -0) 94%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_slab.h    2014-07-02 11:31:57 +0900 (c5e420b)
+++ vendor/nginx-1.7.2/src/core/ngx_slab.h    2014-07-04 15:15:55 +0900 (1ee65d5)
@@ -29,6 +29,7 @@ typedef struct {
     size_t            min_shift;
 
     ngx_slab_page_t  *pages;
+    ngx_slab_page_t  *last;
     ngx_slab_page_t   free;
 
     u_char           *start;
@@ -39,6 +40,8 @@ typedef struct {
     u_char           *log_ctx;
     u_char            zero;
 
+    unsigned          log_nomem:1;
+
     void             *data;
     void             *addr;
 } ngx_slab_pool_t;

  Renamed: vendor/nginx-1.7.2/src/core/ngx_spinlock.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/core/ngx_string.c (+78 -13) 95%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_string.c    2014-07-02 11:31:57 +0900 (3b392f7)
+++ vendor/nginx-1.7.2/src/core/ngx_string.c    2014-07-04 15:15:55 +0900 (4e27917)
@@ -11,6 +11,8 @@
 
 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);
 
@@ -486,7 +488,7 @@ ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64, u_char zero,
 
     if (hexadecimal == 0) {
 
-        if (ui64 <= NGX_MAX_UINT32_VALUE) {
+        if (ui64 <= (uint64_t) NGX_MAX_UINT32_VALUE) {
 
             /*
              * To divide 64-bit numbers and to find remainders
@@ -853,6 +855,46 @@ 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_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;
@@ -1060,38 +1102,61 @@ ngx_hex_dump(u_char *dst, u_char *src, size_t len)
 void
 ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src)
 {
-    u_char         *d, *s;
-    size_t          len;
     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++ = basis64[(s[0] >> 2) & 0x3f];
-        *d++ = basis64[((s[0] & 3) << 4) | (s[1] >> 4)];
-        *d++ = basis64[((s[1] & 0x0f) << 2) | (s[2] >> 6)];
-        *d++ = basis64[s[2] & 0x3f];
+        *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++ = basis64[(s[0] >> 2) & 0x3f];
+        *d++ = basis[(s[0] >> 2) & 0x3f];
 
         if (len == 1) {
-            *d++ = basis64[(s[0] & 3) << 4];
-            *d++ = '=';
+            *d++ = basis[(s[0] & 3) << 4];
+            if (padding) {
+                *d++ = '=';
+            }
 
         } else {
-            *d++ = basis64[((s[0] & 3) << 4) | (s[1] >> 4)];
-            *d++ = basis64[(s[1] & 0x0f) << 2];
+            *d++ = basis[((s[0] & 3) << 4) | (s[1] >> 4)];
+            *d++ = basis[(s[1] & 0x0f) << 2];
         }
 
-        *d++ = '=';
+        if (padding) {
+            *d++ = '=';
+        }
     }
 
     dst->len = d - dst->data;

  Renamed: vendor/nginx-1.7.2/src/core/ngx_string.h (+2 -0) 98%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_string.h    2014-07-02 11:31:57 +0900 (92d246e)
+++ vendor/nginx-1.7.2/src/core/ngx_string.h    2014-07-04 15:15:55 +0900 (712e7d0)
@@ -167,6 +167,7 @@ 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);
@@ -182,6 +183,7 @@ u_char *ngx_hex_dump(u_char *dst, u_char *src, size_t len);
 #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);
 

  Added: vendor/nginx-1.7.2/src/core/ngx_syslog.c (+346 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.7.2/src/core/ngx_syslog.c    2014-07-04 15:15:55 +0900 (e6d40f4)
@@ -0,0 +1,346 @@
+
+/*
+ * 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;
+
+    /* UDP sockets are always ready to write */
+    peer->conn.write->ready = 1;
+
+    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");
+    }
+}

  Added: vendor/nginx-1.7.2/src/core/ngx_syslog.h (+30 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.7.2/src/core/ngx_syslog.h    2014-07-04 15:15:55 +0900 (92d47d5)
@@ -0,0 +1,30 @@
+
+/*
+ * 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_ */

  Renamed: vendor/nginx-1.7.2/src/core/ngx_times.c (+19 -2) 92%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_times.c    2014-07-02 11:31:57 +0900 (77490fa)
+++ vendor/nginx-1.7.2/src/core/ngx_times.c    2014-07-04 15:15:55 +0900 (595c122)
@@ -29,6 +29,7 @@ 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)
 
@@ -50,6 +51,8 @@ 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" };
@@ -63,6 +66,7 @@ ngx_time_init(void)
     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];
 
@@ -73,7 +77,7 @@ ngx_time_init(void)
 void
 ngx_time_update(void)
 {
-    u_char          *p0, *p1, *p2, *p3;
+    u_char          *p0, *p1, *p2, *p3, *p4;
     ngx_tm_t         tm, gmt;
     time_t           sec;
     ngx_uint_t       msec;
@@ -166,6 +170,11 @@ ngx_time_update(void)
                        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();
 
@@ -174,6 +183,7 @@ ngx_time_update(void)
     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);
 }
@@ -184,7 +194,7 @@ ngx_time_update(void)
 void
 ngx_time_sigsafe_update(void)
 {
-    u_char          *p;
+    u_char          *p, *p2;
     ngx_tm_t         tm;
     time_t           sec;
     ngx_time_t      *tp;
@@ -224,9 +234,16 @@ ngx_time_sigsafe_update(void)
                        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);
 }

  Renamed: vendor/nginx-1.7.2/src/core/ngx_times.h (+1 -0) 95%
===================================================================
--- vendor/nginx-1.4.7/src/core/ngx_times.h    2014-07-02 11:31:57 +0900 (c4b26a2)
+++ vendor/nginx-1.7.2/src/core/ngx_times.h    2014-07-04 15:15:55 +0900 (94aedcd)
@@ -40,6 +40,7 @@ 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,

  Renamed: vendor/nginx-1.7.2/src/event/modules/ngx_aio_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/modules/ngx_devpoll_module.c (+2 -2) 99%
===================================================================
--- vendor/nginx-1.4.7/src/event/modules/ngx_devpoll_module.c    2014-07-02 11:31:57 +0900 (6fdd002)
+++ vendor/nginx-1.7.2/src/event/modules/ngx_devpoll_module.c    2014-07-04 15:15:55 +0900 (0506103)
@@ -425,7 +425,7 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
 
             case -1:
                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
-                    "ioctl(DP_ISPOLLED) failed for socket %d, event",
+                    "ioctl(DP_ISPOLLED) failed for socket %d, event %04Xd",
                     fd, revents);
                 break;
 
@@ -449,7 +449,7 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
                     != (ssize_t) sizeof(struct pollfd))
                 {
                     ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
-                                  "write(/dev/poll) for %d failed, fd");
+                                  "write(/dev/poll) for %d failed", fd);
                 }
 
                 if (close(fd) == -1) {

  Renamed: vendor/nginx-1.7.2/src/event/modules/ngx_epoll_module.c (+17 -9) 97%
===================================================================
--- vendor/nginx-1.4.7/src/event/modules/ngx_epoll_module.c    2014-07-02 11:31:57 +0900 (ee77d8e)
+++ vendor/nginx-1.7.2/src/event/modules/ngx_epoll_module.c    2014-07-04 15:15:55 +0900 (a098c1c)
@@ -25,6 +25,8 @@
 #define EPOLLERR       0x008
 #define EPOLLHUP       0x010
 
+#define EPOLLRDHUP     0x2000
+
 #define EPOLLET        0x80000000
 #define EPOLLONESHOT   0x40000000
 
@@ -191,10 +193,6 @@ ngx_module_t  ngx_epoll_module = {
  * 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
@@ -225,7 +223,11 @@ ngx_epoll_aio_init(ngx_cycle_t *cycle, ngx_epoll_conf_t *epcf)
     int                 n;
     struct epoll_event  ee;
 
+#if (NGX_HAVE_SYS_EVENTFD_H)
+    ngx_eventfd = eventfd(0, 0);
+#else
     ngx_eventfd = syscall(SYS_eventfd, 0);
+#endif
 
     if (ngx_eventfd == -1) {
         ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
@@ -396,13 +398,13 @@ ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
     if (event == NGX_READ_EVENT) {
         e = c->write;
         prev = EPOLLOUT;
-#if (NGX_READ_EVENT != EPOLLIN)
-        events = EPOLLIN;
+#if (NGX_READ_EVENT != EPOLLIN|EPOLLRDHUP)
+        events = EPOLLIN|EPOLLRDHUP;
 #endif
 
     } else {
         e = c->read;
-        prev = EPOLLIN;
+        prev = EPOLLIN|EPOLLRDHUP;
 #if (NGX_WRITE_EVENT != EPOLLOUT)
         events = EPOLLOUT;
 #endif
@@ -466,7 +468,7 @@ ngx_epoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
 
     } else {
         e = c->read;
-        prev = EPOLLIN;
+        prev = EPOLLIN|EPOLLRDHUP;
     }
 
     if (e->active) {
@@ -501,7 +503,7 @@ ngx_epoll_add_connection(ngx_connection_t *c)
 {
     struct epoll_event  ee;
 
-    ee.events = EPOLLIN|EPOLLOUT|EPOLLET;
+    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,
@@ -666,6 +668,12 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
 
         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;
 

  Renamed: vendor/nginx-1.7.2/src/event/modules/ngx_eventport_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/modules/ngx_kqueue_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/modules/ngx_poll_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/modules/ngx_rtsig_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/modules/ngx_select_module.c (+1 -1) 99%
===================================================================
--- vendor/nginx-1.4.7/src/event/modules/ngx_select_module.c    2014-07-02 11:31:57 +0900 (ed71368)
+++ vendor/nginx-1.7.2/src/event/modules/ngx_select_module.c    2014-07-04 15:15:55 +0900 (5169055)
@@ -288,7 +288,7 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
 
         ngx_log_error(level, cycle->log, err, "select() failed");
 
-        if (err == EBADF) {
+        if (err == NGX_EBADF) {
             ngx_select_repair_fd_sets(cycle);
         }
 

  Renamed: vendor/nginx-1.7.2/src/event/modules/ngx_win32_select_module.c (+2 -2) 98%
===================================================================
--- vendor/nginx-1.4.7/src/event/modules/ngx_win32_select_module.c    2014-07-02 11:31:57 +0900 (0a02ffc)
+++ vendor/nginx-1.7.2/src/event/modules/ngx_win32_select_module.c    2014-07-04 15:15:55 +0900 (eb5382d)
@@ -148,8 +148,8 @@ ngx_select_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
         return NGX_ERROR;
     }
 
-    if ((event == NGX_READ_EVENT) && (max_read >= FD_SETSIZE)
-        || (event == NGX_WRITE_EVENT) && (max_write >= FD_SETSIZE))
+    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 "

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event.c (+0 -1) 99%
===================================================================
--- vendor/nginx-1.4.7/src/event/ngx_event.c    2014-07-02 11:31:57 +0900 (c4c6120)
+++ vendor/nginx-1.7.2/src/event/ngx_event.c    2014-07-04 15:15:55 +0900 (e2857f0)
@@ -56,7 +56,6 @@ 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;
-ngx_file_t            ngx_accept_mutex_lock_file;
 
 
 #if (NGX_STAT_STUB)

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event.h (+7 -6) 98%
===================================================================
--- vendor/nginx-1.4.7/src/event/ngx_event.h    2014-07-02 11:31:57 +0900 (93c457c)
+++ vendor/nginx-1.7.2/src/event/ngx_event.h    2014-07-04 15:15:55 +0900 (530c948)
@@ -69,13 +69,9 @@ struct ngx_event_s {
 
     unsigned         delayed:1;
 
-    unsigned         read_discarded:1;
-
-    unsigned         unexpected_eof:1;
-
     unsigned         deferred_accept:1;
 
-    /* the pending eof reported by kqueue or in aio chain operation */
+    /* the pending eof reported by kqueue, epoll or in aio chain operation */
     unsigned         pending_eof:1;
 
 #if !(NGX_THREADS)
@@ -353,6 +349,11 @@ extern ngx_event_actions_t   ngx_event_actions;
 #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
@@ -396,7 +397,7 @@ extern ngx_event_actions_t   ngx_event_actions;
 
 #elif (NGX_HAVE_EPOLL)
 
-#define NGX_READ_EVENT     EPOLLIN
+#define NGX_READ_EVENT     (EPOLLIN|EPOLLRDHUP)
 #define NGX_WRITE_EVENT    EPOLLOUT
 
 #define NGX_LEVEL_EVENT    0

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_accept.c (+16 -6) 94%
===================================================================
--- vendor/nginx-1.4.7/src/event/ngx_event_accept.c    2014-07-02 11:31:57 +0900 (6087d60)
+++ vendor/nginx-1.7.2/src/event/ngx_event_accept.c    2014-07-04 15:15:55 +0900 (575ee4b)
@@ -70,7 +70,7 @@ ngx_event_accept(ngx_event_t *ev)
         s = accept(lc->fd, (struct sockaddr *) sa, &socklen);
 #endif
 
-        if (s == -1) {
+        if (s == (ngx_socket_t) -1) {
             err = ngx_socket_errno;
 
             if (err == NGX_EAGAIN) {
@@ -212,6 +212,7 @@ ngx_event_accept(ngx_event_t *ev)
         c->socklen = socklen;
         c->listening = ls;
         c->local_sockaddr = ls->sockaddr;
+        c->local_socklen = ls->socklen;
 
         c->unexpected_eof = 1;
 
@@ -275,7 +276,8 @@ ngx_event_accept(ngx_event_t *ev)
                 return;
             }
 
-            c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->addr_text.data,
+            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);
@@ -286,9 +288,11 @@ ngx_event_accept(ngx_event_t *ev)
 #if (NGX_DEBUG)
         {
 
+        ngx_str_t             addr;
         struct sockaddr_in   *sin;
         ngx_cidr_t           *cidr;
         ngx_uint_t            i;
+        u_char                text[NGX_SOCKADDR_STRLEN];
 #if (NGX_HAVE_INET6)
         struct sockaddr_in6  *sin6;
         ngx_uint_t            n;
@@ -296,7 +300,7 @@ ngx_event_accept(ngx_event_t *ev)
 
         cidr = ecf->debug_connection.elts;
         for (i = 0; i < ecf->debug_connection.nelts; i++) {
-            if (cidr[i].family != c->sockaddr->sa_family) {
+            if (cidr[i].family != (ngx_uint_t) c->sockaddr->sa_family) {
                 goto next;
             }
 
@@ -338,11 +342,17 @@ ngx_event_accept(ngx_event_t *ev)
             continue;
         }
 
+        if (log->log_level & NGX_LOG_DEBUG_EVENT) {
+            addr.data = text;
+            addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text,
+                                     NGX_SOCKADDR_STRLEN, 1);
+
+            ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0,
+                           "*%uA accept: %V fd:%d", c->number, &addr, s);
         }
-#endif
 
-        ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0,
-                       "*%d accept: %V fd:%d", c->number, &c->addr_text, s);
+        }
+#endif
 
         if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
             if (ngx_add_conn(c) == NGX_ERROR) {

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_busy_lock.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_busy_lock.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_connect.c (+2 -2) 98%
===================================================================
--- vendor/nginx-1.4.7/src/event/ngx_event_connect.c    2014-07-02 11:31:57 +0900 (e6ae656)
+++ vendor/nginx-1.7.2/src/event/ngx_event_connect.c    2014-07-04 15:15:55 +0900 (5fcabcf)
@@ -31,7 +31,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
 
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0, "socket %d", s);
 
-    if (s == -1) {
+    if (s == (ngx_socket_t) -1) {
         ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
                       ngx_socket_n " failed");
         return NGX_ERROR;
@@ -122,7 +122,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
     }
 
     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0,
-                   "connect to %V, fd:%d #%d", pc->name, s, c->number);
+                   "connect to %V, fd:%d #%uA", pc->name, s, c->number);
 
     rc = connect(s, pc->sockaddr, pc->socklen);
 

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_connect.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_mutex.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_openssl.c (+533 -13) 81%
===================================================================
--- vendor/nginx-1.4.7/src/event/ngx_event_openssl.c    2014-07-02 11:31:57 +0900 (915e604)
+++ vendor/nginx-1.7.2/src/event/ngx_event_openssl.c    2014-07-04 15:15:55 +0900 (0c5ecda)
@@ -15,7 +15,7 @@ typedef struct {
 } ngx_openssl_conf_t;
 
 
-static int ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
+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);
@@ -38,6 +38,16 @@ static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
 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
+
+#if OPENSSL_VERSION_NUMBER < 0x10002001L
+static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *str);
+#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);
@@ -82,6 +92,7 @@ ngx_module_t  ngx_openssl_module = {
 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;
 
@@ -139,6 +150,14 @@ ngx_ssl_init(ngx_log_t *log)
         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) {
@@ -175,6 +194,8 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
         return NGX_ERROR;
     }
 
+    ssl->buffer_size = NGX_SSL_BUFSIZE;
+
     /* client side options */
 
     SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_SESS_ID_BUG);
@@ -185,8 +206,10 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
     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);
@@ -278,6 +301,8 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
     {
         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
                       "SSL_CTX_set_ex_data() failed");
+        X509_free(x509);
+        BIO_free(bio);
         return NGX_ERROR;
     }
 
@@ -342,7 +367,7 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
 {
     STACK_OF(X509_NAME)  *list;
 
-    SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_http_ssl_verify_callback);
+    SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_ssl_verify_callback);
 
     SSL_CTX_set_verify_depth(ssl->ctx, depth);
 
@@ -363,6 +388,13 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
         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) {
@@ -407,6 +439,13 @@ ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
         return NGX_ERROR;
     }
 
+    /*
+     * SSL_CTX_load_verify_locations() may leave errors in the error queue
+     * while returning success
+     */
+
+    ERR_clear_error();
+
     return NGX_OK;
 }
 
@@ -457,7 +496,7 @@ ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
 
 
 static int
-ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
+ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
 {
 #if (NGX_DEBUG)
     char              *subject, *issuer;
@@ -503,6 +542,7 @@ ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
 static void
 ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
 {
+    BIO               *rbio, *wbio;
     ngx_connection_t  *c;
 
     if (where & SSL_CB_HANDSHAKE_START) {
@@ -513,11 +553,37 @@ ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
             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(SSL *ssl, int is_export, int key_length)
+ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export,
+    int key_length)
 {
     static RSA  *key;
 
@@ -666,6 +732,7 @@ ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
     }
 
     sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
+    sc->buffer_size = ssl->buffer_size;
 
     sc->connection = SSL_new(ssl->ctx);
 
@@ -1162,7 +1229,7 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
     buf = c->ssl->buf;
 
     if (buf == NULL) {
-        buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE);
+        buf = ngx_create_temp_buf(c->pool, c->ssl->buffer_size);
         if (buf == NULL) {
             return NGX_CHAIN_ERROR;
         }
@@ -1171,14 +1238,14 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
     }
 
     if (buf->start == NULL) {
-        buf->start = ngx_palloc(c->pool, NGX_SSL_BUFSIZE);
+        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 + NGX_SSL_BUFSIZE;
+        buf->end = buf->start + c->ssl->buffer_size;
     }
 
     send = buf->last - buf->pos;
@@ -1664,6 +1731,8 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
 {
     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;
@@ -1709,8 +1778,6 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
         }
     }
 
-    SSL_CTX_set_timeout(ssl->ctx, (long) timeout);
-
     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);
@@ -1741,13 +1808,13 @@ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
         return NGX_OK;
     }
 
+    shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
+
     if (shm_zone->shm.exists) {
-        shm_zone->data = data;
+        shm_zone->data = shpool->data;
         return NGX_OK;
     }
 
-    shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
-
     cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t));
     if (cache == NULL) {
         return NGX_ERROR;
@@ -1771,6 +1838,8 @@ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
     ngx_sprintf(shpool->log_ctx, " in SSL session shared cache \"%V\"%Z",
                 &shm_zone->shm.name);
 
+    shpool->log_nomem = 0;
+
     return NGX_OK;
 }
 
@@ -1923,7 +1992,7 @@ failed:
     ngx_shmtx_unlock(&shpool->mutex);
 
     ngx_log_error(NGX_LOG_ALERT, c->log, 0,
-                  "could not add new SSL session to the session cache");
+                  "could not allocate new session%s", shpool->log_ctx);
 
     return 0;
 }
@@ -2200,6 +2269,218 @@ ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
 }
 
 
+#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_EVENT, 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_EVENT, 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_EVENT, 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)
 {
@@ -2210,6 +2491,175 @@ ngx_ssl_cleanup_ctx(void *data)
 
 
 ngx_int_t
+ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name)
+{
+    X509   *cert;
+
+    cert = SSL_get_peer_certificate(c->ssl->connection);
+    if (cert == NULL) {
+        return NGX_ERROR;
+    }
+
+#if OPENSSL_VERSION_NUMBER >= 0x10002001L
+
+    /* X509_check_host() is only available in OpenSSL 1.0.2+ */
+
+    if (name->len == 0) {
+        goto failed;
+    }
+
+    if (X509_check_host(cert, name->data, name->len, 0) != 1) {
+        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                       "X509_check_host(): no match");
+        goto failed;
+    }
+
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                   "X509_check_host(): match");
+
+    goto found;
+
+#else
+    {
+    int                      n, i;
+    X509_NAME               *sname;
+    ASN1_STRING             *str;
+    X509_NAME_ENTRY         *entry;
+    GENERAL_NAME            *altname;
+    STACK_OF(GENERAL_NAME)  *altnames;
+
+    /*
+     * As per RFC6125 and RFC2818, we check subjectAltName extension,
+     * and if it's not present - commonName in Subject is checked.
+     */
+
+    altnames = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
+
+    if (altnames) {
+        n = sk_GENERAL_NAME_num(altnames);
+
+        for (i = 0; i < n; i++) {
+            altname = sk_GENERAL_NAME_value(altnames, i);
+
+            if (altname->type != GEN_DNS) {
+                continue;
+            }
+
+            str = altname->d.dNSName;
+
+            ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                           "SSL subjectAltName: \"%*s\"",
+                           ASN1_STRING_length(str), ASN1_STRING_data(str));
+
+            if (ngx_ssl_check_name(name, str) == NGX_OK) {
+                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                               "SSL subjectAltName: match");
+                GENERAL_NAMES_free(altnames);
+                goto found;
+            }
+        }
+
+        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                       "SSL subjectAltName: no match");
+
+        GENERAL_NAMES_free(altnames);
+        goto failed;
+    }
+
+    /*
+     * If there is no subjectAltName extension, check commonName
+     * in Subject.  While RFC2818 requires to only check "most specific"
+     * CN, both Apache and OpenSSL check all CNs, and so do we.
+     */
+
+    sname = X509_get_subject_name(cert);
+
+    if (sname == NULL) {
+        goto failed;
+    }
+
+    i = -1;
+    for ( ;; ) {
+        i = X509_NAME_get_index_by_NID(sname, NID_commonName, i);
+
+        if (i < 0) {
+            break;
+        }
+
+        entry = X509_NAME_get_entry(sname, i);
+        str = X509_NAME_ENTRY_get_data(entry);
+
+        ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                       "SSL commonName: \"%*s\"",
+                       ASN1_STRING_length(str), ASN1_STRING_data(str));
+
+        if (ngx_ssl_check_name(name, str) == NGX_OK) {
+            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                           "SSL commonName: match");
+            goto found;
+        }
+    }
+
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                   "SSL commonName: no match");
+    }
+#endif
+
+failed:
+
+    X509_free(cert);
+    return NGX_ERROR;
+
+found:
+
+    X509_free(cert);
+    return NGX_OK;
+}
+
+
+#if OPENSSL_VERSION_NUMBER < 0x10002001L
+
+static ngx_int_t
+ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *pattern)
+{
+    u_char  *s, *p, *end;
+    size_t   slen, plen;
+
+    s = name->data;
+    slen = name->len;
+
+    p = ASN1_STRING_data(pattern);
+    plen = ASN1_STRING_length(pattern);
+
+    if (slen == plen && ngx_strncasecmp(s, p, plen) == 0) {
+        return NGX_OK;
+    }
+
+    if (plen > 2 && p[0] == '*' && p[1] == '.') {
+        plen -= 1;
+        p += 1;
+
+        end = s + slen;
+        s = ngx_strlchr(s, end, '.');
+
+        if (s == NULL) {
+            return NGX_ERROR;
+        }
+
+        slen = end - s;
+
+        if (plen == slen && ngx_strncasecmp(s, p, plen) == 0) {
+            return NGX_OK;
+        }
+    }
+
+    return NGX_ERROR;
+}
+
+#endif
+
+
+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);
@@ -2254,6 +2704,42 @@ 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)
+{
+    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_server_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
+{
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+
+    const char  *servername;
+
+    servername = SSL_get_servername(c->ssl->connection,
+                                    TLSEXT_NAMETYPE_host_name);
+    if (servername) {
+        s->data = (u_char *) servername;
+        s->len = ngx_strlen(servername);
+        return NGX_OK;
+    }
+
+#endif
+
+    s->len = 0;
+    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;
@@ -2471,6 +2957,40 @@ ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
 
 
 ngx_int_t
+ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
+{
+    X509          *cert;
+    unsigned int   len;
+    u_char         buf[EVP_MAX_MD_SIZE];
+
+    s->len = 0;
+
+    cert = SSL_get_peer_certificate(c->ssl->connection);
+    if (cert == NULL) {
+        return NGX_OK;
+    }
+
+    if (!X509_digest(cert, EVP_sha1(), buf, &len)) {
+        X509_free(cert);
+        return NGX_ERROR;
+    }
+
+    s->len = 2 * len;
+    s->data = ngx_pnalloc(pool, 2 * len);
+    if (s->data == NULL) {
+        X509_free(cert);
+        return NGX_ERROR;
+    }
+
+    ngx_hex_dump(s->data, buf, len);
+
+    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;

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_openssl.h (+26 -1) 86%
===================================================================
--- vendor/nginx-1.4.7/src/event/ngx_event_openssl.h    2014-07-02 11:31:57 +0900 (bf81d25)
+++ vendor/nginx-1.7.2/src/event/ngx_event_openssl.h    2014-07-04 15:15:55 +0900 (d632eb2)
@@ -29,6 +29,7 @@
 typedef struct {
     SSL_CTX                    *ctx;
     ngx_log_t                  *log;
+    size_t                      buffer_size;
 } ngx_ssl_t;
 
 
@@ -37,6 +38,7 @@ typedef struct {
 
     ngx_int_t                   last;
     ngx_buf_t                  *buf;
+    size_t                      buffer_size;
 
     ngx_connection_handler_pt   handler;
 
@@ -48,6 +50,7 @@ typedef struct {
     unsigned                    buffer:1;
     unsigned                    no_wait_shutdown:1;
     unsigned                    no_send_shutdown:1;
+    unsigned                    handshake_buffer_set:1;
 } ngx_ssl_connection_t;
 
 
@@ -82,6 +85,16 @@ typedef struct {
 } 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
@@ -109,11 +122,14 @@ 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(SSL *ssl, int is_export, int key_length);
+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);
@@ -134,6 +150,8 @@ ngx_int_t ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session);
      || n == X509_V_ERR_CERT_UNTRUSTED                                        \
      || n == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)
 
+ngx_int_t ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name);
+
 
 ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool,
     ngx_str_t *s);
@@ -141,6 +159,10 @@ 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_server_name(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,
@@ -151,6 +173,8 @@ ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool,
     ngx_str_t *s);
 ngx_int_t ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool,
     ngx_str_t *s);
+ngx_int_t ngx_ssl_get_fingerprint(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);
 
@@ -171,6 +195,7 @@ 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;
 

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_openssl_stapling.c (+37 -23) 96%
===================================================================
--- vendor/nginx-1.4.7/src/event/ngx_event_openssl_stapling.c    2014-07-02 11:31:57 +0900 (77baeb9)
+++ vendor/nginx-1.7.2/src/event/ngx_event_openssl_stapling.c    2014-07-04 15:15:55 +0900 (69340b3)
@@ -792,7 +792,6 @@ ngx_ssl_ocsp_request(ngx_ssl_ocsp_ctx_t *ctx)
         }
 
         resolve->name = ctx->host;
-        resolve->type = NGX_RESOLVE_A;
         resolve->handler = ngx_ssl_ocsp_resolve_handler;
         resolve->data = ctx;
         resolve->timeout = ctx->resolver_timeout;
@@ -816,13 +815,14 @@ 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;
-    ngx_uint_t           i;
-    struct sockaddr_in  *sin;
+    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_ALERT, ctx->log, 0,
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
                    "ssl ocsp resolve handler");
 
     if (resolve->state) {
@@ -835,15 +835,19 @@ ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve)
 
 #if (NGX_DEBUG)
     {
-    in_addr_t   addr;
+    u_char     text[NGX_SOCKADDR_STRLEN];
+    ngx_str_t  addr;
+
+    addr.data = text;
 
     for (i = 0; i < resolve->naddrs; i++) {
-        addr = ntohl(resolve->addrs[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);
 
-        ngx_log_debug4(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
-                       "name was resolved to %ud.%ud.%ud.%ud",
-                       (addr >> 24) & 0xff, (addr >> 16) & 0xff,
-                       (addr >> 8) & 0xff, addr & 0xff);
     }
     }
 #endif
@@ -859,26 +863,34 @@ ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve)
 
     for (i = 0; i < resolve->naddrs; i++) {
 
-        sin = ngx_pcalloc(ctx->pool, sizeof(struct sockaddr_in));
-        if (sin == NULL) {
+        socklen = resolve->addrs[i].socklen;
+
+        sockaddr = ngx_palloc(ctx->pool, socklen);
+        if (sockaddr == NULL) {
             goto failed;
         }
 
-        sin->sin_family = AF_INET;
-        sin->sin_port = port;
-        sin->sin_addr.s_addr = resolve->addrs[i];
+        ngx_memcpy(sockaddr, resolve->addrs[i].sockaddr, socklen);
 
-        ctx->addrs[i].sockaddr = (struct sockaddr *) sin;
-        ctx->addrs[i].socklen = sizeof(struct sockaddr_in);
+        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;
+        }
 
-        len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
+        ctx->addrs[i].sockaddr = sockaddr;
+        ctx->addrs[i].socklen = socklen;
 
-        p = ngx_pnalloc(ctx->pool, len);
+        p = ngx_pnalloc(ctx->pool, NGX_SOCKADDR_STRLEN);
         if (p == NULL) {
             goto failed;
         }
 
-        len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1);
+        len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1);
 
         ctx->addrs[i].name.len = len;
         ctx->addrs[i].name.data = p;
@@ -1183,6 +1195,8 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx)
     b->last = p;
     ctx->request = b;
 
+    OCSP_REQUEST_free(ocsp);
+
     return NGX_OK;
 
 failed:

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_pipe.c (+15 -30) 96%
===================================================================
--- vendor/nginx-1.4.7/src/event/ngx_event_pipe.c    2014-07-02 11:31:57 +0900 (476d56e)
+++ vendor/nginx-1.7.2/src/event/ngx_event_pipe.c    2014-07-04 15:15:55 +0900 (eed807d)
@@ -57,7 +57,7 @@ ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write)
         do_write = 1;
     }
 
-    if (p->upstream->fd != -1) {
+    if (p->upstream->fd != (ngx_socket_t) -1) {
         rev = p->upstream->read;
 
         flags = (rev->eof || rev->error) ? NGX_CLOSE_EVENT : 0;
@@ -74,7 +74,9 @@ ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write)
         }
     }
 
-    if (p->downstream->fd != -1 && p->downstream->data == p->output_ctx) {
+    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;
@@ -220,8 +222,8 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
             {
 
                 /*
-                 * if it is allowed, then save some bufs from r->in
-                 * to a temporary file, and add them to a r->out chain
+                 * 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);
@@ -454,7 +456,7 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
     size_t             bsize;
     ngx_int_t          rc;
     ngx_uint_t         flush, flushed, prev_last_shadow;
-    ngx_chain_t       *out, **ll, *cl, file;
+    ngx_chain_t       *out, **ll, *cl;
     ngx_connection_t  *downstream;
 
     downstream = p->downstream;
@@ -514,13 +516,10 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
             }
 
             if (p->cacheable && p->buf_to_file) {
+                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
+                               "pipe write chain");
 
-                file.buf = p->buf_to_file;
-                file.next = NULL;
-
-                if (ngx_write_chain_to_temp_file(p->temp_file, &file)
-                    == NGX_ERROR)
-                {
+                if (ngx_event_pipe_write_chain_to_temp_file(p) == NGX_ABORT) {
                     return NGX_ABORT;
                 }
             }
@@ -858,19 +857,13 @@ ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
         return NGX_OK;
     }
 
-    if (p->free) {
-        cl = p->free;
-        b = cl->buf;
-        p->free = cl->next;
-        ngx_free_chain(p->pool, cl);
-
-    } else {
-        b = ngx_alloc_buf(p->pool);
-        if (b == NULL) {
-            return NGX_ERROR;
-        }
+    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;
@@ -878,14 +871,6 @@ ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
     b->recycled = 1;
     buf->shadow = b;
 
-    cl = ngx_alloc_chain_link(p->pool);
-    if (cl == NULL) {
-        return NGX_ERROR;
-    }
-
-    cl->buf = b;
-    cl->next = NULL;
-
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d", b->num);
 
     if (p->in) {

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_pipe.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_posted.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_posted.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_timer.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/event/ngx_event_timer.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_access_module.c (+115 -35) 79%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_access_module.c    2014-07-02 11:31:57 +0900 (70a4262)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_access_module.c    2014-07-04 15:15:55 +0900 (c553e46)
@@ -26,11 +26,22 @@ typedef struct {
 
 #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;
 
 
@@ -41,6 +52,10 @@ static ngx_int_t ngx_http_access_inet(ngx_http_request_t *r,
 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);
@@ -144,6 +159,19 @@ ngx_http_access_handler(ngx_http_request_t *r)
             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
     }
 
@@ -221,6 +249,29 @@ ngx_http_access_inet6(ngx_http_request_t *r, ngx_http_access_loc_conf_t *alcf,
 #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)
 {
@@ -246,13 +297,16 @@ 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;
+    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;
+    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));
@@ -263,7 +317,19 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     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,
@@ -277,11 +343,28 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         }
     }
 
-    switch (cidr.family) {
+    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)
-    case AF_INET6:
-    case 0: /* all */
+    if (cidr.family == AF_INET6 || all) {
 
         if (alcf->rules6 == NULL) {
             alcf->rules6 = ngx_array_create(cf->pool, 4,
@@ -299,33 +382,28 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         rule6->mask = cidr.u.in6.mask;
         rule6->addr = cidr.u.in6.addr;
         rule6->deny = (value[0].data[0] == 'd') ? 1 : 0;
-
-        if (!all) {
-            break;
-        }
-
-        /* "all" passes through */
+    }
 #endif
 
-    default: /* AF_INET */
+#if (NGX_HAVE_UNIX_DOMAIN)
+    if (cidr.family == AF_UNIX || all) {
 
-        if (alcf->rules == NULL) {
-            alcf->rules = ngx_array_create(cf->pool, 4,
-                                           sizeof(ngx_http_access_rule_t));
-            if (alcf->rules == NULL) {
+        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 = ngx_array_push(alcf->rules);
-        if (rule == NULL) {
+        rule_un = ngx_array_push(alcf->rules_un);
+        if (rule_un == 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;
+        rule_un->deny = (value[0].data[0] == 'd') ? 1 : 0;
     }
+#endif
 
     return NGX_CONF_OK;
 }
@@ -351,20 +429,22 @@ 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)
-
-    if (conf->rules == NULL && conf->rules6 == NULL) {
+        && 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;
-    }
-
-#else
-
-    if (conf->rules == NULL) {
-        conf->rules = prev->rules;
-    }
-
 #endif
+#if (NGX_HAVE_UNIX_DOMAIN)
+        conf->rules_un = prev->rules_un;
+#endif
+    }
 
     return NGX_CONF_OK;
 }

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_addition_filter_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_auth_basic_module.c (+1 -1) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_auth_basic_module.c    2014-07-02 11:31:57 +0900 (e8709e5)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_auth_basic_module.c    2014-07-04 15:15:55 +0900 (8ec5329)
@@ -137,7 +137,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
 
     if (rc == NGX_DECLINED) {
 
-        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+        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);

  Added: vendor/nginx-1.7.2/src/http/modules/ngx_http_auth_request_module.c (+444 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_auth_request_module.c    2014-07-04 15:15:55 +0900 (b4307be)
@@ -0,0 +1,444 @@
+
+/*
+ * 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;
+}

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_autoindex_module.c (+2 -1) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_autoindex_module.c    2014-07-02 11:31:57 +0900 (1eecfbe)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_autoindex_module.c    2014-07-04 15:15:55 +0900 (f694df0)
@@ -233,6 +233,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
     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);
 
@@ -357,7 +358,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
 
     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);
+                      ngx_close_dir_n " \"%V\" failed", &path);
     }
 
     escape_html = ngx_escape_html(NULL, r->uri.data, r->uri.len);

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_browser_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_charset_filter_module.c (+20 -16) 98%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_charset_filter_module.c    2014-07-02 11:31:57 +0900 (27a00d0)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_charset_filter_module.c    2014-07-04 15:15:55 +0900 (4ea9818)
@@ -128,7 +128,7 @@ ngx_str_t  ngx_http_charset_default_types[] = {
     ngx_string("text/xml"),
     ngx_string("text/plain"),
     ngx_string("text/vnd.wap.wml"),
-    ngx_string("application/x-javascript"),
+    ngx_string("application/javascript"),
     ngx_string("application/rss+xml"),
     ngx_null_string
 };
@@ -272,12 +272,27 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
         return ngx_http_next_header_filter(r);
     }
 
+    if (source_charset == charset) {
+        r->headers_out.content_type.len = r->headers_out.content_type_len;
+
+        ngx_http_set_charset(r, &dst);
+
+        return ngx_http_next_header_filter(r);
+    }
+
+    /* source_charset != charset */
+
+    if (r->headers_out.content_encoding
+        && r->headers_out.content_encoding->value.len)
+    {
+        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))
+    if (charsets[source_charset].tables == NULL
+        || charsets[source_charset].tables[charset] == NULL)
     {
         goto no_charset_map;
     }
@@ -286,11 +301,7 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
 
     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);
+    return ngx_http_charset_ctx(r, charsets, charset, source_charset);
 
 no_charset_map:
 
@@ -311,13 +322,6 @@ ngx_http_destination_charset(ngx_http_request_t *r, ngx_str_t *name)
     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;
     }

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_chunked_filter_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_dav_module.c (+1 -3) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_dav_module.c    2014-07-02 11:31:57 +0900 (a97c60e)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_dav_module.c    2014-07-04 15:15:55 +0900 (e7f9e9a)
@@ -10,8 +10,6 @@
 #include <ngx_http.h>
 
 
-#define NGX_HTTP_DAV_COPY_BLOCK      65536
-
 #define NGX_HTTP_DAV_OFF             2
 
 
@@ -606,7 +604,7 @@ destination_done:
 
     duri.len = last - p;
     duri.data = p;
-    flags = 0;
+    flags = NGX_HTTP_LOG_UNSAFE;
 
     if (ngx_http_parse_unsafe_uri(r, &duri, &args, &flags) != NGX_OK) {
         goto invalid_destination;

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_degradation_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_empty_gif_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_fastcgi_module.c (+251 -36) 93%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_fastcgi_module.c    2014-07-02 11:31:57 +0900 (e2427b4)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_fastcgi_module.c    2014-07-04 15:15:55 +0900 (80cd1a2)
@@ -138,6 +138,8 @@ 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);
@@ -185,6 +187,7 @@ static ngx_conf_bitmask_t  ngx_http_fastcgi_next_upstream_masks[] = {
     { 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 },
@@ -232,6 +235,13 @@ static ngx_command_t  ngx_http_fastcgi_commands[] = {
       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,
@@ -395,6 +405,13 @@ static ngx_command_t  ngx_http_fastcgi_commands[] = {
       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"),
@@ -553,7 +570,8 @@ static ngx_str_t  ngx_http_fastcgi_hide_headers[] = {
 #if (NGX_HTTP_CACHE)
 
 static ngx_keyval_t  ngx_http_fastcgi_cache_headers[] = {
-    { ngx_string("HTTP_IF_MODIFIED_SINCE"), ngx_string("") },
+    { 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("") },
@@ -578,13 +596,6 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
     ngx_http_fastcgi_ctx_t       *f;
     ngx_http_fastcgi_loc_conf_t  *flcf;
 
-    if (r->subrequest_in_memory) {
-        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
-                      "ngx_http_fastcgi_module does not support "
-                      "subrequest in memory");
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
-    }
-
     if (ngx_http_upstream_create(r) != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -621,7 +632,7 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
     u->finalize_request = ngx_http_fastcgi_finalize_request;
     r->state = 0;
 
-    u->buffering = 1;
+    u->buffering = flcf->upstream.buffering;
 
     u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
     if (u->pipe == NULL) {
@@ -632,6 +643,8 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
     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);
 
@@ -1582,7 +1595,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
                     ngx_str_set(&u->headers_in.status_line, "200 OK");
                 }
 
-                if (u->state) {
+                if (u->state && u->state->status == 0) {
                     u->state->status = u->headers_in.status_n;
                 }
 
@@ -1825,19 +1838,13 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
             break;
         }
 
-        if (p->free) {
-            cl = p->free;
-            b = cl->buf;
-            p->free = cl->next;
-            ngx_free_chain(p->pool, cl);
-
-        } else {
-            b = ngx_alloc_buf(p->pool);
-            if (b == NULL) {
-                return NGX_ERROR;
-            }
+        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;
@@ -1850,14 +1857,6 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
         *prev = b;
         prev = &b->shadow;
 
-        cl = ngx_alloc_chain_link(p->pool);
-        if (cl == NULL) {
-            return NGX_ERROR;
-        }
-
-        cl->buf = b;
-        cl->next = NULL;
-
         if (p->in) {
             *p->last_in = cl;
         } else {
@@ -1925,6 +1924,222 @@ 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)
+{
+    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)
 {
@@ -2126,6 +2341,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
     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;
@@ -2136,6 +2352,8 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
     /* "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;
@@ -2357,12 +2575,6 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_ptr_value(conf->upstream.no_cache,
                              prev->upstream.no_cache, NULL);
 
-    if (conf->upstream.no_cache && conf->upstream.cache_bypass == NULL) {
-        ngx_log_error(NGX_LOG_WARN, cf->log, 0,
-             "\"fastcgi_no_cache\" functionality has been changed in 0.8.46, "
-             "now it should be used together with \"fastcgi_cache_bypass\"");
-    }
-
     ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
                              prev->upstream.cache_valid, NULL);
 
@@ -2376,6 +2588,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     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,
@@ -2551,7 +2766,7 @@ ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
 
             s->key = h->key;
             s->value = h->value;
-            s->skip_empty = 0;
+            s->skip_empty = 1;
 
         next:
 

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_flv_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_geo_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_geoip_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_gunzip_filter_module.c (+9 -5) 97%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_gunzip_filter_module.c    2014-07-02 11:31:57 +0900 (d4e41e4)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_gunzip_filter_module.c    2014-07-04 15:15:55 +0900 (adadc9d)
@@ -199,7 +199,7 @@ ngx_http_gunzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
         }
     }
 
-    if (ctx->nomem) {
+    if (ctx->nomem || in == NULL) {
 
         /* flush busy buffers */
 
@@ -422,7 +422,7 @@ ngx_http_gunzip_filter_inflate(ngx_http_request_t *r,
     rc = inflate(&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,
+        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                       "inflate() failed: %d, %d", ctx->flush, rc);
         return NGX_ERROR;
     }
@@ -500,9 +500,13 @@ ngx_http_gunzip_filter_inflate(ngx_http_request_t *r,
         return NGX_OK;
     }
 
-    if (rc == Z_STREAM_END && ctx->flush == Z_FINISH
-        && ctx->zstream.avail_in == 0)
-    {
+    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;

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_gzip_filter_module.c (+5 -3) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_gzip_filter_module.c    2014-07-02 11:31:57 +0900 (35dd07e)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_gzip_filter_module.c    2014-07-04 15:15:55 +0900 (ea1f1d0)
@@ -368,9 +368,11 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *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) {
+    if (ctx->nomem || in == NULL) {
 
         /* flush busy buffers */
 
@@ -620,8 +622,6 @@ ngx_http_gzip_filter_deflate_start(ngx_http_request_t *r,
         return NGX_ERROR;
     }
 
-    r->connection->buffered |= NGX_HTTP_GZIP_BUFFERED;
-
     ctx->last_out = &ctx->out;
     ctx->crc32 = crc32(0L, Z_NULL, 0);
     ctx->flush = Z_NO_FLUSH;
@@ -854,6 +854,8 @@ ngx_http_gzip_filter_deflate(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
         *ctx->last_out = cl;
         ctx->last_out = &cl->next;
 
+        r->connection->buffered &= ~NGX_HTTP_GZIP_BUFFERED;
+
         return NGX_OK;
     }
 

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_gzip_static_module.c (+1 -3) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_gzip_static_module.c    2014-07-02 11:31:57 +0900 (6e77761)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_gzip_static_module.c    2014-07-04 15:15:55 +0900 (4d54090)
@@ -38,7 +38,7 @@ static ngx_conf_enum_t  ngx_http_gzip_static[] = {
 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_FLAG,
+      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),
@@ -246,8 +246,6 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
     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));

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_headers_filter_module.c (+4 -0) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_headers_filter_module.c    2014-07-02 11:31:57 +0900 (0dfe810)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_headers_filter_module.c    2014-07-04 15:15:55 +0900 (e33e7ce)
@@ -339,6 +339,10 @@ ngx_http_add_cache_control(ngx_http_request_t *r, ngx_http_header_val_t *hv,
 {
     ngx_table_elt_t  *cc, **ccp;
 
+    if (value->len == 0) {
+        return NGX_OK;
+    }
+
     ccp = r->headers_out.cache_control.elts;
 
     if (ccp == NULL) {

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_image_filter_module.c (+8 -2) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_image_filter_module.c    2014-07-02 11:31:57 +0900 (c6c3b74)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_image_filter_module.c    2014-07-04 15:15:55 +0900 (c983b97)
@@ -478,7 +478,12 @@ ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in)
                        "image buf: %uz", size);
 
         rest = ctx->image + ctx->length - p;
-        size = (rest < size) ? rest : size;
+
+        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;
@@ -567,7 +572,8 @@ ngx_http_image_json(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
     ngx_http_clean_header(r);
 
     r->headers_out.status = NGX_HTTP_OK;
-    ngx_str_set(&r->headers_out.content_type, "text/plain");
+    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) {

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_index_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_limit_conn_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_limit_req_module.c (+5 -1) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_limit_req_module.c    2014-07-02 11:31:57 +0900 (90434c9)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_limit_req_module.c    2014-07-04 15:15:55 +0900 (74f7fda)
@@ -451,6 +451,8 @@ ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit, ngx_uint_t hash,
 
         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;
         }
     }
@@ -674,6 +676,8 @@ ngx_http_limit_req_init_zone(ngx_shm_zone_t *shm_zone, void *data)
     ngx_sprintf(ctx->shpool->log_ctx, " in limit_req zone \"%V\"%Z",
                 &shm_zone->shm.name);
 
+    ctx->shpool->log_nomem = 0;
+
     return NGX_OK;
 }
 
@@ -912,7 +916,7 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
             continue;
         }
 
-        if (ngx_strncmp(value[i].data, "nodelay", 7) == 0) {
+        if (ngx_strcmp(value[i].data, "nodelay") == 0) {
             nodelay = 1;
             continue;
         }

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_log_module.c (+118 -15) 92%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_log_module.c    2014-07-02 11:31:57 +0900 (7eb29b3)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_log_module.c    2014-07-04 15:15:55 +0900 (bc660cd)
@@ -66,7 +66,9 @@ typedef struct {
     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_complex_value_t   *filter;
 } ngx_http_log_t;
 
 
@@ -239,7 +241,9 @@ static ngx_int_t
 ngx_http_log_handler(ngx_http_request_t *r)
 {
     u_char                   *line, *p;
-    size_t                    len;
+    size_t                    len, size;
+    ssize_t                   n;
+    ngx_str_t                 val;
     ngx_uint_t                i, l;
     ngx_http_log_t           *log;
     ngx_http_log_op_t        *op;
@@ -258,6 +262,16 @@ ngx_http_log_handler(ngx_http_request_t *r)
     log = lcf->logs->elts;
     for (l = 0; l < lcf->logs->nelts; l++) {
 
+        if (log[l].filter) {
+            if (ngx_http_complex_value(r, log[l].filter, &val) != NGX_OK) {
+                return NGX_ERROR;
+            }
+
+            if (val.len == 0 || (val.len == 1 && val.data[0] == '0')) {
+                continue;
+            }
+        }
+
         if (ngx_time() == log[l].disk_full_time) {
 
             /*
@@ -282,6 +296,16 @@ ngx_http_log_handler(ngx_http_request_t *r)
             }
         }
 
+        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;
@@ -320,6 +344,8 @@ ngx_http_log_handler(ngx_http_request_t *r)
             }
         }
 
+    alloc_line:
+
         line = ngx_pnalloc(r->pool, len);
         if (line == NULL) {
             return NGX_ERROR;
@@ -327,10 +353,33 @@ ngx_http_log_handler(ngx_http_request_t *r)
 
         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);
@@ -1060,15 +1109,13 @@ ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
         return NGX_CONF_ERROR;
     }
 
+    ngx_memzero(log, sizeof(ngx_http_log_t));
+
     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;
-
     lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
     fmt = lmcf->formats.elts;
 
@@ -1085,16 +1132,18 @@ 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_http_log_buf_t         *buffer;
-    ngx_http_log_fmt_t         *fmt;
-    ngx_http_log_main_conf_t   *lmcf;
-    ngx_http_script_compile_t   sc;
+    ssize_t                            size;
+    ngx_int_t                          gzip;
+    ngx_uint_t                         i, n;
+    ngx_msec_t                         flush;
+    ngx_str_t                         *value, name, s, filter;
+    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;
+    ngx_http_compile_complex_value_t   ccv;
 
     value = cf->args->elts;
 
@@ -1125,6 +1174,23 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     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) {
@@ -1158,6 +1224,8 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         }
     }
 
+process_formats:
+
     if (cf->args->nelts >= 3) {
         name = value[2];
 
@@ -1186,9 +1254,21 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         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;
+    filter.len = 0;
 
     for (i = 3; i < cf->args->nelts; i++) {
 
@@ -1255,6 +1335,12 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 #endif
         }
 
+        if (ngx_strncmp(value[i].data, "if=", 3) == 0) {
+            filter.len = value[i].len - 3;
+            filter.data = value[i].data + 3;
+            continue;
+        }
+
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                            "invalid parameter \"%V\"", &value[i]);
         return NGX_CONF_ERROR;
@@ -1324,6 +1410,23 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         log->file->data = buffer;
     }
 
+    if (filter.len) {
+        log->filter = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
+        if (log->filter == NULL) {
+            return NGX_CONF_ERROR;
+        }
+
+        ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+
+        ccv.cf = cf;
+        ccv.value = &filter;
+        ccv.complex_value = log->filter;
+
+        if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+            return NGX_CONF_ERROR;
+        }
+    }
+
     return NGX_CONF_OK;
 }
 

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_map_module.c (+3 -3) 98%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_map_module.c    2014-07-02 11:31:57 +0900 (13c8b97)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_map_module.c    2014-07-04 15:15:55 +0900 (3245e04)
@@ -131,7 +131,7 @@ ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
     }
 
     if (!value->valid) {
-        value = ngx_http_get_flushed_variable(r, (ngx_uint_t) value->data);
+        value = ngx_http_get_flushed_variable(r, (uintptr_t) value->data);
 
         if (value == NULL || value->not_found) {
             value = &ngx_http_variable_null_value;
@@ -414,7 +414,7 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
         var = ctx->var_values.elts;
 
         for (i = 0; i < ctx->var_values.nelts; i++) {
-            if (index == (ngx_int_t) var[i].data) {
+            if (index == (intptr_t) var[i].data) {
                 var = &var[i];
                 goto found;
             }
@@ -429,7 +429,7 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
         var->no_cacheable = 0;
         var->not_found = 0;
         var->len = 0;
-        var->data = (u_char *) index;
+        var->data = (u_char *) (intptr_t) index;
 
         goto found;
     }

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_memcached_module.c (+21 -10) 97%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_memcached_module.c    2014-07-02 11:31:57 +0900 (278b1ed)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_memcached_module.c    2014-07-04 15:15:55 +0900 (aaa047e)
@@ -197,7 +197,6 @@ ngx_http_memcached_handler(ngx_http_request_t *r)
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    ctx->rest = NGX_HTTP_MEMCACHED_END;
     ctx->request = r;
 
     ngx_http_set_ctx(r, ctx, ngx_http_memcached_module);
@@ -309,10 +308,15 @@ ngx_http_memcached_process_header(ngx_http_request_t *r)
 
 found:
 
-    *p = '\0';
-
-    line.len = p - u->buffer.pos - 1;
     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);
@@ -387,10 +391,9 @@ found:
     length:
 
         start = p;
+        p = line.data + line.len;
 
-        while (*p && *p++ != CR) { /* void */ }
-
-        u->headers_in.content_length_n = ngx_atoof(start, p - start - 1);
+        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\" "
@@ -401,7 +404,7 @@ found:
 
         u->headers_in.status_n = 200;
         u->state->status = 200;
-        u->buffer.pos = p + 1;
+        u->buffer.pos = p + sizeof(CRLF) - 1;
 
         return NGX_OK;
     }
@@ -410,8 +413,10 @@ found:
         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;
@@ -435,7 +440,13 @@ ngx_http_memcached_filter_init(void *data)
 
     u = ctx->request->upstream;
 
-    u->length += NGX_HTTP_MEMCACHED_END;
+    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;
 }
@@ -509,7 +520,7 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
         return NGX_OK;
     }
 
-    last += u->length - NGX_HTTP_MEMCACHED_END;
+    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,

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_mp4_module.c (+669 -197) 80%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_mp4_module.c    2014-07-02 11:31:57 +0900 (20ef51a)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_mp4_module.c    2014-07-04 15:15:55 +0900 (8f439ba)
@@ -27,14 +27,15 @@
 #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_CHUNK   18
+#define NGX_HTTP_MP4_STSC_START   18
 #define NGX_HTTP_MP4_STSC_DATA    19
-#define NGX_HTTP_MP4_STSZ_ATOM    20
-#define NGX_HTTP_MP4_STSZ_DATA    21
-#define NGX_HTTP_MP4_STCO_ATOM    22
-#define NGX_HTTP_MP4_STCO_DATA    23
-#define NGX_HTTP_MP4_CO64_ATOM    24
-#define NGX_HTTP_MP4_CO64_DATA    25
+#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
 
@@ -62,10 +63,15 @@ typedef struct {
     uint32_t              chunks;
 
     ngx_uint_t            start_sample;
+    ngx_uint_t            end_sample;
     ngx_uint_t            start_chunk;
-    ngx_uint_t            chunk_samples;
-    uint64_t              chunk_samples_size;
+    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;
@@ -95,7 +101,8 @@ typedef struct {
     ngx_buf_t             ctts_atom_buf;
     ngx_buf_t             ctts_data_buf;
     ngx_buf_t             stsc_atom_buf;
-    ngx_buf_t             stsc_chunk_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;
@@ -104,7 +111,8 @@ typedef struct {
     ngx_buf_t             co64_atom_buf;
     ngx_buf_t             co64_data_buf;
 
-    ngx_mp4_stsc_entry_t  stsc_chunk_entry;
+    ngx_mp4_stsc_entry_t  stsc_start_chunk_entry;
+    ngx_mp4_stsc_entry_t  stsc_end_chunk_entry;
 } ngx_http_mp4_trak_t;
 
 
@@ -121,6 +129,7 @@ typedef struct {
     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;
@@ -157,7 +166,11 @@ typedef struct {
 #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 += n; mp4->offset += n
+
+
+#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)                              \
@@ -202,6 +215,8 @@ typedef struct {
     &((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);
@@ -213,7 +228,7 @@ static ngx_int_t ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4,
 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 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,
@@ -252,18 +267,26 @@ 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,
@@ -280,10 +303,12 @@ 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"),
@@ -395,8 +420,8 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
 {
     u_char                    *last;
     size_t                     root;
-    ngx_int_t                  rc, start;
-    ngx_uint_t                 level;
+    ngx_int_t                  rc, start, end;
+    ngx_uint_t                 level, length;
     ngx_str_t                  path, value;
     ngx_log_t                 *log;
     ngx_buf_t                 *b;
@@ -501,6 +526,7 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
     r->allow_ranges = 1;
 
     start = -1;
+    length = 0;
     r->headers_out.content_length_n = of.size;
     mp4 = NULL;
     b = NULL;
@@ -518,47 +544,72 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
             ngx_set_errno(0);
             start = (int) (strtod((char *) value.data, NULL) * 1000);
 
-            if (ngx_errno == 0 && start >= 0) {
-                r->allow_ranges = 0;
+            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;
+                }
 
-                mp4 = ngx_pcalloc(r->pool, sizeof(ngx_http_mp4_file_t));
-                if (mp4 == NULL) {
-                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
+                if (end > start) {
+                    length = end - start;
                 }
+            }
+        }
+    }
 
-                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->request = r;
+    if (start >= 0) {
+        r->single_range = 1;
 
-                switch (ngx_http_mp4_process(mp4)) {
+        mp4 = ngx_pcalloc(r->pool, sizeof(ngx_http_mp4_file_t));
+        if (mp4 == NULL) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
 
-                case NGX_DECLINED:
-                    if (mp4->buffer) {
-                        ngx_pfree(r->pool, mp4->buffer);
-                    }
+        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;
 
-                    ngx_pfree(r->pool, mp4);
-                    mp4 = NULL;
+        switch (ngx_http_mp4_process(mp4)) {
 
-                    break;
+        case NGX_DECLINED:
+            if (mp4->buffer) {
+                ngx_pfree(r->pool, mp4->buffer);
+            }
 
-                case NGX_OK:
-                    r->headers_out.content_length_n = mp4->content_length;
-                    break;
+            ngx_pfree(r->pool, mp4);
+            mp4 = NULL;
 
-                default: /* NGX_ERROR */
-                    if (mp4->buffer) {
-                        ngx_pfree(r->pool, mp4->buffer);
-                    }
+            break;
 
-                    ngx_pfree(r->pool, mp4);
+        case NGX_OK:
+            r->headers_out.content_length_n = mp4->content_length;
+            break;
 
-                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
-                }
+        default: /* NGX_ERROR */
+            if (mp4->buffer) {
+                ngx_pfree(r->pool, mp4->buffer);
             }
+
+            ngx_pfree(r->pool, mp4);
+
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
     }
 
@@ -638,15 +689,15 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
 static ngx_int_t
 ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
 {
-    off_t                  start_offset, adjustment;
+    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_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
-                   "mp4 start:%ui", mp4->start);
+    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);
 
@@ -688,6 +739,7 @@ ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
     }
 
     start_offset = mp4->end;
+    end_offset = 0;
     trak = mp4->trak.elts;
 
     for (i = 0; i < mp4->trak.nelts; i++) {
@@ -735,6 +787,10 @@ ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
             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;
 
@@ -746,6 +802,10 @@ ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
         }
     }
 
+    if (end_offset < start_offset) {
+        end_offset = start_offset;
+    }
+
     mp4->moov_size += 8;
 
     ngx_mp4_set_32value(mp4->moov_atom_header, mp4->moov_size);
@@ -762,7 +822,7 @@ ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
     }
 
     adjustment = mp4->ftyp_size + mp4->moov_size
-                 + ngx_http_mp4_update_mdat_atom(mp4, start_offset)
+                 + ngx_http_mp4_update_mdat_atom(mp4, start_offset, end_offset)
                  - start_offset;
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
@@ -948,7 +1008,7 @@ ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 ftyp atom");
 
     if (atom_data_size > 1024
-        || ngx_mp4_atom_data(mp4) + atom_data_size > mp4->buffer_end)
+        || 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",
@@ -1006,7 +1066,7 @@ ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
 
     no_mdat = (mp4->mdat_atom.buf == NULL);
 
-    if (no_mdat && mp4->start == 0) {
+    if (no_mdat && mp4->start == 0 && mp4->length == 0) {
         /*
          * send original file if moov atom resides before
          * mdat atom and client requests integral file
@@ -1105,7 +1165,8 @@ 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)
+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;
@@ -1113,15 +1174,16 @@ ngx_http_mp4_update_mdat_atom(ngx_http_mp4_file_t *mp4, off_t start_offset)
     uint64_t    atom_size;
     ngx_buf_t  *atom;
 
-    atom_data_size = mp4->mdat_data.buf->file_last - start_offset;
+    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 > 0xffffffff) {
+    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),
@@ -1196,7 +1258,7 @@ 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;
+    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;
@@ -1239,7 +1301,24 @@ ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
                    "mvhd timescale:%uD, duration:%uL, time:%.3fs",
                    timescale, duration, (double) duration / timescale);
 
-    duration -= (uint64_t) mp4->start * timescale / 1000;
+    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",
@@ -1296,7 +1375,7 @@ ngx_http_mp4_read_trak_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
 
     trak->out[NGX_HTTP_MP4_TRAK_ATOM].buf = atom;
 
-    atom_end = mp4->buffer_pos + atom_data_size;
+    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);
@@ -1386,7 +1465,7 @@ 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;
+    uint64_t                duration, start_time, length_time;
     ngx_buf_t              *atom;
     ngx_http_mp4_trak_t    *trak;
     ngx_mp4_tkhd_atom_t    *tkhd_atom;
@@ -1426,7 +1505,23 @@ ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
                    "tkhd duration:%uL, time:%.3fs",
                    duration, (double) duration / mp4->timescale);
 
-    duration -= (uint64_t) mp4->start * mp4->timescale / 1000;
+    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",
@@ -1529,7 +1624,7 @@ 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;
+    uint64_t                duration, start_time, length_time;
     ngx_buf_t              *atom;
     ngx_http_mp4_trak_t    *trak;
     ngx_mp4_mdhd_atom_t    *mdhd_atom;
@@ -1571,7 +1666,23 @@ ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
                    "mdhd timescale:%uD, duration:%uL, time:%.3fs",
                    timescale, duration, (double) duration / timescale);
 
-    duration -= (uint64_t) mp4->start * timescale / 1000;
+    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",
@@ -1944,13 +2055,9 @@ 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;
-    uint32_t               entries, count, duration;
-    uint64_t               start_time;
-    ngx_buf_t             *atom, *data;
-    ngx_uint_t             start_sample;
-    ngx_mp4_stts_atom_t   *stts_atom;
-    ngx_mp4_stts_entry_t  *entry, *end;
+    size_t                atom_size;
+    ngx_buf_t            *atom, *data;
+    ngx_mp4_stts_atom_t  *stts_atom;
 
     /*
      * mdia.minf.stbl.stts updating requires trak->timescale
@@ -1969,12 +2076,60 @@ ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4,
         return NGX_ERROR;
     }
 
-    entries = trak->time_to_sample_entries;
-    start_time = (uint64_t) mp4->start * trak->timescale / 1000;
+    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 start_time:%uL", start_time);
+                   "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;
@@ -1983,13 +2138,13 @@ ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4,
         count = ngx_mp4_get_32value(entry->count);
         duration = ngx_mp4_get_32value(entry->duration);
 
-        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
-                       "count:%uD, duration:%uD", count, 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);
-            count -= (uint32_t) (start_time / duration);
-            ngx_mp4_set_32value(entry->count, count);
+            rest = (uint32_t) (start_time / duration);
             goto found;
         }
 
@@ -1999,27 +2154,44 @@ ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4,
         entry++;
     }
 
-    ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
-                  "start time is out mp4 stts samples in \"%s\"",
-                  mp4->file.name.data);
+    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;
+        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:
 
-    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
-                   "start_sample:%ui, new count:%uD", start_sample, count);
+    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;
 
-    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);
 
-    data->pos = (u_char *) entry;
-    atom_size = sizeof(ngx_mp4_stts_atom_t) + (data->last - data->pos);
-    trak->size += atom_size;
+    } 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;
 
-    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, entries);
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
+                       "end_sample:%ui, new count:%uD",
+                       trak->end_sample, rest);
+    }
 
     return NGX_OK;
 }
@@ -2101,7 +2273,7 @@ ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4,
     ngx_http_mp4_trak_t *trak)
 {
     size_t                     atom_size;
-    uint32_t                   entries, sample, start_sample, *entry, *end;
+    uint32_t                   sample, start_sample, *entry, *end;
     ngx_buf_t                 *atom, *data;
     ngx_http_mp4_stss_atom_t  *stss_atom;
 
@@ -2120,18 +2292,79 @@ ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4,
         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 */
-    start_sample = trak->start_sample + 1;
-    entries = trak->sync_samples_entries;
 
+    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_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
-                       "start:%uD, sync:%uD", start_sample, sample);
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
+                       "sync:%uD", sample);
 
         if (sample >= start_sample) {
             goto found;
@@ -2141,35 +2374,19 @@ ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4,
         entry++;
     }
 
-    ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
-                  "start sample is out of mp4 stss atom in \"%s\"",
-                  mp4->file.name.data);
-
-    return NGX_ERROR;
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
+                   "sample is out of mp4 stss atom");
 
 found:
 
-    data->pos = (u_char *) entry;
-
-    start_sample = trak->start_sample;
+    if (start) {
+        data->pos = (u_char *) entry;
+        trak->sync_samples_entries = entries;
 
-    while (entry < end) {
-        sample = ngx_mp4_get_32value(entry);
-        sample -= start_sample;
-        ngx_mp4_set_32value(entry, sample);
-        entry++;
+    } else {
+        data->last = (u_char *) entry;
+        trak->sync_samples_entries -= entries;
     }
-
-    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, entries);
-
-    return NGX_OK;
 }
 
 
@@ -2253,11 +2470,9 @@ static void
 ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4,
     ngx_http_mp4_trak_t *trak)
 {
-    size_t                 atom_size;
-    uint32_t               entries, count, start_sample;
-    ngx_buf_t             *atom, *data;
-    ngx_mp4_ctts_atom_t   *ctts_atom;
-    ngx_mp4_ctts_entry_t  *entry, *end;
+    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
@@ -2274,8 +2489,61 @@ ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4,
         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 */
-    start_sample = trak->start_sample + 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;
@@ -2284,12 +2552,11 @@ ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4,
         count = ngx_mp4_get_32value(entry->count);
 
         ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
-                       "start:%uD, count:%uD, offset:%uD",
+                       "sample:%uD, count:%uD, offset:%uD",
                        start_sample, count, ngx_mp4_get_32value(entry->offset));
 
          if (start_sample <= count) {
-             count -= (start_sample - 1);
-             ngx_mp4_set_32value(entry->count, count);
+             rest = start_sample - 1;
              goto found;
          }
 
@@ -2298,24 +2565,25 @@ ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4,
          entry++;
     }
 
-    trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf = NULL;
-    trak->out[NGX_HTTP_MP4_CTTS_DATA].buf = NULL;
+    if (start) {
+        data->pos = (u_char *) end;
+        trak->composition_offset_entries = 0;
+    }
 
     return;
 
 found:
 
-    data->pos = (u_char *) entry;
-    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;
+    if (start) {
+        ngx_mp4_set_32value(entry->count, count - rest);
+        data->pos = (u_char *) entry;
+        trak->composition_offset_entries = entries;
 
-    ngx_mp4_set_32value(ctts_atom->size, atom_size);
-    ngx_mp4_set_32value(ctts_atom->entries, entries);
-
-    return;
+    } else {
+        ngx_mp4_set_32value(entry->count, rest);
+        data->last = (u_char *) (entry + 1);
+        trak->composition_offset_entries -= entries - 1;
+    }
 }
 
 
@@ -2394,11 +2662,10 @@ ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4,
     ngx_http_mp4_trak_t *trak)
 {
     size_t                 atom_size;
-    uint32_t               start_sample, entries, chunk, samples, id,
-                           next_chunk, n;
-    ngx_buf_t             *atom, *data, *buf;
+    uint32_t               chunk;
+    ngx_buf_t             *atom, *data;
     ngx_mp4_stsc_atom_t   *stsc_atom;
-    ngx_mp4_stsc_entry_t  *entry, *first, *end;
+    ngx_mp4_stsc_entry_t  *entry, *end;
 
     /*
      * mdia.minf.stbl.stsc updating requires trak->start_sample
@@ -2425,15 +2692,97 @@ ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4,
         return NGX_ERROR;
     }
 
-    start_sample = (uint32_t) trak->start_sample;
+    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) {
@@ -2441,18 +2790,19 @@ ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4,
         next_chunk = ngx_mp4_get_32value(entry->chunk);
 
         ngx_log_debug5(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
-                       "start_sample:%uD, chunk:%uD, chunks:%uD, "
+                       "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) {
+        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);
@@ -2460,18 +2810,18 @@ ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4,
         entry++;
     }
 
-    next_chunk = trak->chunks;
+    next_chunk = trak->chunks + 1;
 
     ngx_log_debug4(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
-                   "start_sample:%uD, chunk:%uD, chunks:%uD, samples:%uD",
+                   "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,
-                      "start time is out mp4 stsc chunks in \"%s\"",
-                      mp4->file.name.data);
+                      "%s time is out mp4 stsc chunks in \"%s\"",
+                      start ? "start" : "end", mp4->file.name.data);
         return NGX_ERROR;
     }
 
@@ -2487,59 +2837,91 @@ found:
         return NGX_ERROR;
     }
 
-    trak->start_chunk = chunk - 1;
+    target_chunk = chunk - 1;
+    target_chunk += start_sample / samples;
+    chunk_samples = start_sample % samples;
 
-    trak->start_chunk += start_sample / samples;
-    trak->chunk_samples = start_sample % samples;
+    if (start) {
+        data->pos = (u_char *) entry;
 
-    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
-                   "start chunk:%ui, samples:%uD",
-                   trak->start_chunk, trak->chunk_samples);
+        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;
 
-    data->pos = (u_char *) entry;
-    atom_size = sizeof(ngx_mp4_stsc_atom_t) + (data->last - data->pos);
+        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;
 
-    ngx_mp4_set_32value(entry->chunk, 1);
+        } else {
+            data->last = (u_char *) entry;
+            trak->sample_to_chunk_entries -= entries;
+            trak->end_chunk_samples = prev_samples;
+        }
 
-    if (trak->chunk_samples && next_chunk - trak->start_chunk == 2) {
+        if (chunk_samples) {
+            trak->end_chunk = target_chunk + 1;
+            trak->end_chunk_samples = chunk_samples;
 
-        /* last chunk in the entry */
+        } else {
+            trak->end_chunk = target_chunk;
+        }
 
-        ngx_mp4_set_32value(entry->samples, samples - trak->chunk_samples);
+        samples = chunk_samples;
+        next_chunk = chunk + 1;
 
-    } else if (trak->chunk_samples) {
+        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);
+    }
 
-        first = &trak->stsc_chunk_entry;
+    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 - trak->chunk_samples);
+        ngx_mp4_set_32value(first->samples, samples);
         ngx_mp4_set_32value(first->id, id);
 
-        buf = &trak->stsc_chunk_buf;
+        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_CHUNK].buf = buf;
+        trak->out[NGX_HTTP_MP4_STSC_START].buf = buf;
 
-        ngx_mp4_set_32value(entry->chunk, 2);
+        ngx_mp4_set_32value(entry->chunk, trak->start_chunk + 2);
 
-        entries++;
-        atom_size += sizeof(ngx_mp4_stsc_entry_t);
-    }
+        trak->sample_to_chunk_entries++;
 
-    while (++entry < end) {
-        chunk = ngx_mp4_get_32value(entry->chunk);
-        chunk -= trak->start_chunk;
-        ngx_mp4_set_32value(entry->chunk, chunk);
-    }
+    } else if (chunk_samples) {
 
-    trak->size += atom_size;
+        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);
 
-    atom = trak->out[NGX_HTTP_MP4_STSC_ATOM].buf;
-    stsc_atom = (ngx_mp4_stsc_atom_t *) atom->pos;
+        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);
 
-    ngx_mp4_set_32value(stsc_atom->size, atom_size);
-    ngx_mp4_set_32value(stsc_atom->entries, entries);
+        trak->out[NGX_HTTP_MP4_STSC_END].buf = buf;
+
+        trak->sample_to_chunk_entries++;
+    }
 
     return NGX_OK;
 }
@@ -2635,7 +3017,7 @@ 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;
+    uint32_t             *pos, *end, entries;
     ngx_buf_t            *atom, *data;
     ngx_mp4_stsz_atom_t  *stsz_atom;
 
@@ -2651,22 +3033,47 @@ ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4,
     data = trak->out[NGX_HTTP_MP4_STSZ_DATA].buf;
 
     if (data) {
-        if (trak->start_sample > trak->sample_sizes_entries) {
+        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->chunk_samples; pos < end; pos++) {
-            trak->chunk_samples_size += ngx_mp4_get_32value(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->chunk_samples_size);
+                       "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;
@@ -2675,8 +3082,7 @@ ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4,
         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,
-                            trak->sample_sizes_entries - trak->start_sample);
+        ngx_mp4_set_32value(stsz_atom->entries, entries);
     }
 
     return NGX_OK;
@@ -2757,6 +3163,7 @@ 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;
 
@@ -2786,21 +3193,53 @@ ngx_http_mp4_update_stco_atom(ngx_http_mp4_file_t *mp4,
     }
 
     data->pos += trak->start_chunk * sizeof(uint32_t);
-    atom_size = sizeof(ngx_mp4_stco_atom_t) + (data->last - data->pos);
-    trak->size += atom_size;
 
     trak->start_offset = ngx_mp4_get_32value(data->pos);
-    trak->start_offset += trak->chunk_samples_size;
+    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:%uD", trak->start_offset);
+                   "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, trak->chunks - trak->start_chunk);
+    ngx_mp4_set_32value(stco_atom->entries, entries);
 
     return NGX_OK;
 }
@@ -2908,6 +3347,7 @@ 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;
 
@@ -2937,21 +3377,53 @@ ngx_http_mp4_update_co64_atom(ngx_http_mp4_file_t *mp4,
     }
 
     data->pos += trak->start_chunk * sizeof(uint64_t);
-    atom_size = sizeof(ngx_mp4_co64_atom_t) + (data->last - data->pos);
-    trak->size += atom_size;
 
     trak->start_offset = ngx_mp4_get_64value(data->pos);
-    trak->start_offset += trak->chunk_samples_size;
+    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:%uL", trak->start_offset);
+                   "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, trak->chunks - trak->start_chunk);
+    ngx_mp4_set_32value(co64_atom->entries, entries);
 
     return NGX_OK;
 }

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_not_modified_filter_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_proxy_module.c (+185 -64) 94%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_proxy_module.c    2014-07-02 11:31:57 +0900 (5e62caa)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_proxy_module.c    2014-07-04 15:15:55 +0900 (61af3df)
@@ -76,6 +76,15 @@ typedef struct {
 
     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;
+    ngx_uint_t                     ssl_verify_depth;
+    ngx_str_t                      ssl_trusted_certificate;
+    ngx_str_t                      ssl_crl;
+#endif
 } ngx_http_proxy_loc_conf_t;
 
 
@@ -178,6 +187,7 @@ static ngx_conf_bitmask_t  ngx_http_proxy_next_upstream_masks[] = {
     { 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 },
@@ -185,6 +195,20 @@ static ngx_conf_bitmask_t  ngx_http_proxy_next_upstream_masks[] = {
 };
 
 
+#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 },
@@ -444,6 +468,13 @@ static ngx_command_t  ngx_http_proxy_commands[] = {
       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"),
@@ -511,6 +542,62 @@ static ngx_command_t  ngx_http_proxy_commands[] = {
       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 },
+
+    { ngx_string("proxy_ssl_name"),
+      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_proxy_loc_conf_t, upstream.ssl_name),
+      NULL },
+
+    { ngx_string("proxy_ssl_server_name"),
+      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_server_name),
+      NULL },
+
+    { ngx_string("proxy_ssl_verify"),
+      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_verify),
+      NULL },
+
+    { ngx_string("proxy_ssl_verify_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_proxy_loc_conf_t, ssl_verify_depth),
+      NULL },
+
+    { ngx_string("proxy_ssl_trusted_certificate"),
+      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_trusted_certificate),
+      NULL },
+
+    { ngx_string("proxy_ssl_crl"),
+      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_crl),
+      NULL },
+
 #endif
 
       ngx_null_command
@@ -587,7 +674,8 @@ static ngx_keyval_t  ngx_http_proxy_cache_headers[] = {
     { ngx_string("Keep-Alive"), ngx_string("") },
     { ngx_string("Expect"), ngx_string("") },
     { ngx_string("Upgrade"), ngx_string("") },
-    { ngx_string("If-Modified-Since"), 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("") },
@@ -993,6 +1081,8 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
 
     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) {
@@ -1204,7 +1294,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
     }
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http proxy header:\n\"%*s\"",
+                   "http proxy header:%N\"%*s\"",
                    (size_t) (b->last - b->pos), b->pos);
 
     if (plcf->body_set == NULL && plcf->upstream.pass_request_body) {
@@ -1317,7 +1407,7 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
         return NGX_OK;
     }
 
-    if (u->state) {
+    if (u->state && u->state->status == 0) {
         u->state->status = ctx->status.code;
     }
 
@@ -1539,7 +1629,7 @@ ngx_http_proxy_input_filter_init(void *data)
         u->pipe->length = 3; /* "0" LF LF */
 
         u->input_filter = ngx_http_proxy_non_buffered_chunked_filter;
-        u->length = -1;
+        u->length = 1;
 
     } else if (u->headers_in.content_length_n == 0) {
         /* empty body: special case as filter won't be called */
@@ -1570,19 +1660,13 @@ ngx_http_proxy_copy_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
         return NGX_OK;
     }
 
-    if (p->free) {
-        cl = p->free;
-        b = cl->buf;
-        p->free = cl->next;
-        ngx_free_chain(p->pool, cl);
-
-    } else {
-        b = ngx_alloc_buf(p->pool);
-        if (b == NULL) {
-            return NGX_ERROR;
-        }
+    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;
@@ -1590,14 +1674,6 @@ ngx_http_proxy_copy_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
     b->recycled = 1;
     buf->shadow = b;
 
-    cl = ngx_alloc_chain_link(p->pool);
-    if (cl == NULL) {
-        return NGX_ERROR;
-    }
-
-    cl->buf = b;
-    cl->next = NULL;
-
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d", b->num);
 
     if (p->in) {
@@ -1662,19 +1738,13 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
 
             /* a chunk has been parsed successfully */
 
-            if (p->free) {
-                cl = p->free;
-                b = cl->buf;
-                p->free = cl->next;
-                ngx_free_chain(p->pool, cl);
-
-            } else {
-                b = ngx_alloc_buf(p->pool);
-                if (b == NULL) {
-                    return NGX_ERROR;
-                }
+            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;
@@ -1687,14 +1757,6 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
             *prev = b;
             prev = &b->shadow;
 
-            cl = ngx_alloc_chain_link(p->pool);
-            if (cl == NULL) {
-                return NGX_ERROR;
-            }
-
-            cl->buf = b;
-            cl->next = NULL;
-
             if (p->in) {
                 *p->last_in = cl;
             } else {
@@ -1709,7 +1771,7 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
 
             if (buf->last - buf->pos >= ctx->chunked.size) {
 
-                buf->pos += ctx->chunked.size;
+                buf->pos += (size_t) ctx->chunked.size;
                 b->last = buf->pos;
                 ctx->chunked.size = 0;
 
@@ -1872,7 +1934,7 @@ ngx_http_proxy_non_buffered_chunked_filter(void *data, ssize_t bytes)
             b->tag = u->output.tag;
 
             if (buf->last - buf->pos >= ctx->chunked.size) {
-                buf->pos += ctx->chunked.size;
+                buf->pos += (size_t) ctx->chunked.size;
                 b->last = buf->pos;
                 ctx->chunked.size = 0;
 
@@ -2077,7 +2139,7 @@ ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,
     v->no_cacheable = 0;
     v->not_found = 0;
 
-    v->data = ngx_pnalloc(r->connection->pool, NGX_OFF_T_LEN);
+    v->data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN);
 
     if (v->data == NULL) {
         return NGX_ERROR;
@@ -2303,7 +2365,7 @@ ngx_http_proxy_rewrite(ngx_http_request_t *r, ngx_table_elt_t *h, size_t prefix,
 
     if (replacement->len > len) {
 
-        data = ngx_pnalloc(r->pool, new_len);
+        data = ngx_pnalloc(r->pool, new_len + 1);
         if (data == NULL) {
             return NGX_ERROR;
         }
@@ -2312,7 +2374,7 @@ ngx_http_proxy_rewrite(ngx_http_request_t *r, ngx_table_elt_t *h, size_t prefix,
         p = ngx_copy(p, replacement->data, replacement->len);
 
         ngx_memcpy(p, h->value.data + prefix + len,
-                   h->value.len - len - prefix);
+                   h->value.len - len - prefix + 1);
 
         h->value.data = data;
 
@@ -2321,7 +2383,7 @@ ngx_http_proxy_rewrite(ngx_http_request_t *r, ngx_table_elt_t *h, size_t prefix,
                      replacement->len);
 
         ngx_memmove(p, h->value.data + prefix + len,
-                    h->value.len - len - prefix);
+                    h->value.len - len - prefix + 1);
     }
 
     h->value.len = new_len;
@@ -2373,6 +2435,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
      *     conf->upstream.location = NULL;
      *     conf->upstream.store_lengths = NULL;
      *     conf->upstream.store_values = NULL;
+     *     conf->upstream.ssl_name = NULL;
      *
      *     conf->method = { 0, NULL };
      *     conf->headers_source = NULL;
@@ -2383,6 +2446,11 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
      *     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->ssl_trusted_certificate = { 0, NULL };
+     *     conf->ssl_crl = { 0, NULL };
      */
 
     conf->upstream.store = NGX_CONF_UNSET;
@@ -2414,14 +2482,19 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
     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;
+    conf->upstream.ssl_server_name = NGX_CONF_UNSET;
+    conf->upstream.ssl_verify = NGX_CONF_UNSET;
+    conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
 #endif
 
     /* "proxy_cyclic_temp_file" is disabled */
@@ -2657,12 +2730,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_ptr_value(conf->upstream.no_cache,
                              prev->upstream.no_cache, NULL);
 
-    if (conf->upstream.no_cache && conf->upstream.cache_bypass == NULL) {
-        ngx_log_error(NGX_LOG_WARN, cf->log, 0,
-             "\"proxy_no_cache\" functionality has been changed in 0.8.46, "
-             "now it should be used together with \"proxy_cache_bypass\"");
-    }
-
     ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
                              prev->upstream.cache_valid, NULL);
 
@@ -2676,6 +2743,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     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, "");
@@ -2696,8 +2766,36 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
                               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->upstream.ssl_name == NULL) {
+        conf->upstream.ssl_name = prev->upstream.ssl_name;
+    }
+
+    ngx_conf_merge_value(conf->upstream.ssl_server_name,
+                              prev->upstream.ssl_server_name, 0);
+    ngx_conf_merge_value(conf->upstream.ssl_verify,
+                              prev->upstream.ssl_verify, 0);
+    ngx_conf_merge_uint_value(conf->ssl_verify_depth,
+                              prev->ssl_verify_depth, 1);
+    ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
+                              prev->ssl_trusted_certificate, "");
+    ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
+
+    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);
@@ -3143,9 +3241,7 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         }
 
 #if (NGX_HTTP_SSL)
-        if (ngx_http_proxy_set_ssl(cf, plcf) != NGX_OK) {
-            return NGX_CONF_ERROR;
-        }
+        plcf->ssl = 1;
 #endif
 
         return NGX_CONF_OK;
@@ -3158,9 +3254,7 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     } else if (ngx_strncasecmp(url->data, (u_char *) "https://", 8) == 0) {
 
 #if (NGX_HTTP_SSL)
-        if (ngx_http_proxy_set_ssl(cf, plcf) != NGX_OK) {
-            return NGX_CONF_ERROR;
-        }
+        plcf->ssl = 1;
 
         add = 8;
         port = 443;
@@ -3742,10 +3836,7 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf)
 
     plcf->upstream.ssl->log = cf->log;
 
-    if (ngx_ssl_create(plcf->upstream.ssl,
-                       NGX_SSL_SSLv2|NGX_SSL_SSLv3|NGX_SSL_TLSv1
-                                    |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2,
-                       NULL)
+    if (ngx_ssl_create(plcf->upstream.ssl, plcf->ssl_protocols, NULL)
         != NGX_OK)
     {
         return NGX_ERROR;
@@ -3759,6 +3850,36 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf)
     cln->handler = ngx_ssl_cleanup_ctx;
     cln->data = plcf->upstream.ssl;
 
+    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;
+    }
+
+    if (plcf->upstream.ssl_verify) {
+        if (plcf->ssl_trusted_certificate.len == 0) {
+            ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+                      "no proxy_ssl_trusted_certificate for proxy_ssl_verify");
+            return NGX_ERROR;
+        }
+
+        if (ngx_ssl_trusted_certificate(cf, plcf->upstream.ssl,
+                                        &plcf->ssl_trusted_certificate,
+                                        plcf->ssl_verify_depth)
+            != NGX_OK)
+        {
+            return NGX_ERROR;
+        }
+
+        if (ngx_ssl_crl(cf, plcf->upstream.ssl, &plcf->ssl_crl) != NGX_OK) {
+            return NGX_ERROR;
+        }
+    }
+
     return NGX_OK;
 }
 

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_random_index_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_range_filter_module.c (+13 -6) 98%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_range_filter_module.c    2014-07-02 11:31:57 +0900 (82c202d)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_range_filter_module.c    2014-07-04 15:15:55 +0900 (6a65e48)
@@ -22,7 +22,7 @@
  * ... data ...
  *
  *
- * the mutlipart format:
+ * the multipart format:
  *
  * "HTTP/1.0 206 Partial Content" CRLF
  * ... header ...
@@ -148,6 +148,7 @@ 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;
 
@@ -227,7 +228,9 @@ parse:
         return NGX_ERROR;
     }
 
-    switch (ngx_http_range_parse(r, ctx, clcf->max_ranges)) {
+    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);
@@ -432,7 +435,9 @@ ngx_http_range_multipart_header(ngx_http_request_t *r,
           + r->headers_out.content_type.len
           + sizeof(CRLF "Content-Range: bytes ") - 1;
 
-    if (r->headers_out.charset.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;
     }
 
@@ -451,7 +456,9 @@ ngx_http_range_multipart_header(ngx_http_request_t *r,
      * "Content-Range: bytes "
      */
 
-    if (r->headers_out.charset.len) {
+    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
@@ -461,8 +468,6 @@ ngx_http_range_multipart_header(ngx_http_request_t *r,
                                            &r->headers_out.charset)
                                    - ctx->boundary_header.data;
 
-        r->headers_out.charset.len = 0;
-
     } else if (r->headers_out.content_type.len) {
         ctx->boundary_header.len = ngx_sprintf(ctx->boundary_header.data,
                                            CRLF "--%0muA" CRLF
@@ -501,6 +506,8 @@ ngx_http_range_multipart_header(ngx_http_request_t *r,
 
     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;

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_realip_module.c (+20 -1) 95%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_realip_module.c    2014-07-02 11:31:57 +0900 (ed9c5f9)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_realip_module.c    2014-07-04 15:15:55 +0900 (7a62118)
@@ -13,6 +13,7 @@
 #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 {
@@ -156,6 +157,18 @@ ngx_http_realip_handler(ngx_http_request_t *r)
 
         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;
@@ -230,7 +243,8 @@ ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr)
 
     c = r->connection;
 
-    len = ngx_sock_ntop(addr->sockaddr, text, NGX_SOCKADDR_STRLEN, 0);
+    len = ngx_sock_ntop(addr->sockaddr, addr->socklen, text,
+                        NGX_SOCKADDR_STRLEN, 0);
     if (len == 0) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -342,6 +356,11 @@ ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         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];

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_referer_module.c (+132 -74) 81%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_referer_module.c    2014-07-02 11:31:57 +0900 (d8a014c)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_referer_module.c    2014-07-04 15:15:55 +0900 (b417eb2)
@@ -12,22 +12,18 @@
 
 #define NGX_HTTP_REFERER_NO_URI_PART  ((void *) 4)
 
-#if !(NGX_PCRE)
-
-#define ngx_regex_t          void
-
-#endif
-
 
 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;
 
@@ -41,10 +37,14 @@ 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 char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
-    ngx_str_t *value, ngx_str_t *uri);
-static char *ngx_http_add_regex_referer(ngx_conf_t *cf,
-    ngx_http_referer_conf_t *rlcf, ngx_str_t *name, ngx_regex_t *regex);
+static 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);
 
@@ -117,6 +117,10 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
     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);
 
@@ -125,6 +129,7 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
         && rlcf->hash.wc_tail == NULL
 #if (NGX_PCRE)
         && rlcf->regex == NULL
+        && rlcf->server_name_regex == NULL
 #endif
        )
     {
@@ -147,10 +152,12 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
 
         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;
         }
     }
@@ -171,12 +178,12 @@ valid_scheme:
             break;
         }
 
-        buf[i] = ngx_tolower(*p);
-        key = ngx_hash(key, buf[i++]);
-
         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);
@@ -187,11 +194,26 @@ valid_scheme:
 
 #if (NGX_PCRE)
 
-    if (rlcf->regex) {
-        ngx_int_t  rc;
-        ngx_str_t  referer;
+    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 */
+    }
 
-        referer.len = len - 7;
+    if (rlcf->regex) {
+        referer.len = len;
         referer.data = ref;
 
         rc = ngx_regex_exec_array(rlcf->regex, &referer, r->connection->log);
@@ -251,8 +273,17 @@ ngx_http_referer_create_conf(ngx_conf_t *cf)
         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;
@@ -270,13 +301,18 @@ 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_hash_init_t  hash;
+    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);
@@ -288,6 +324,33 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
         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
@@ -366,6 +429,8 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
 
 #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) {
@@ -389,15 +454,12 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     u_char                    *p;
     ngx_str_t                 *value, uri, name;
-    ngx_uint_t                 i, n;
+    ngx_uint_t                 i;
     ngx_http_variable_t       *var;
-    ngx_http_server_name_t    *sn;
-    ngx_http_core_srv_conf_t  *cscf;
 
     ngx_str_set(&name, "invalid_referer");
 
-    var = ngx_http_add_variable(cf, &name,
-                                NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOHASH);
+    var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
     if (var == NULL) {
         return NGX_CONF_ERROR;
     }
@@ -437,48 +499,21 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
             continue;
         }
 
-        ngx_str_null(&uri);
-
         if (ngx_strcmp(value[i].data, "server_names") == 0) {
-
-            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_referer(cf, rlcf, &sn[n].name,
-                                                   sn[n].regex->regex)
-                        != NGX_OK)
-                    {
-                        return NGX_CONF_ERROR;
-                    }
-
-                    continue;
-                }
-#endif
-
-                if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name, &uri)
-                    != NGX_OK)
-                {
-                    return NGX_CONF_ERROR;
-                }
-            }
-
+            rlcf->server_names = 1;
             continue;
         }
 
         if (value[i].data[0] == '~') {
-            if (ngx_http_add_regex_referer(cf, rlcf, &value[i], NULL) != NGX_OK)
-            {
+            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) {
@@ -496,20 +531,20 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 }
 
 
-static char *
+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->len == 0) {
+    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_CONF_ERROR;
+            return NGX_ERROR;
         }
 
         *u = *uri;
@@ -518,7 +553,7 @@ ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
     rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY);
 
     if (rc == NGX_OK) {
-        return NGX_CONF_OK;
+        return NGX_OK;
     }
 
     if (rc == NGX_DECLINED) {
@@ -531,13 +566,13 @@ ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
                            "conflicting parameter \"%V\"", value);
     }
 
-    return NGX_CONF_ERROR;
+    return NGX_ERROR;
 }
 
 
-static char *
+static ngx_int_t
 ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
-    ngx_str_t *name, ngx_regex_t *regex)
+    ngx_str_t *name)
 {
 #if (NGX_PCRE)
     ngx_regex_elt_t      *re;
@@ -546,26 +581,19 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
 
     if (name->len == 1) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty regex in \"%V\"", name);
-        return NGX_CONF_ERROR;
+        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_CONF_ERROR;
+            return NGX_ERROR;
         }
     }
 
     re = ngx_array_push(rlcf->regex);
     if (re == NULL) {
-        return NGX_CONF_ERROR;
-    }
-
-    if (regex) {
-        re->regex = regex;
-        re->name = name->data;
-
-        return NGX_CONF_OK;
+        return NGX_ERROR;
     }
 
     name->len--;
@@ -581,13 +609,13 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
 
     if (ngx_regex_compile(&rc) != NGX_OK) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
-        return NGX_CONF_ERROR;
+        return NGX_ERROR;
     }
 
     re->regex = rc.regex;
     re->name = name->data;
 
-    return NGX_CONF_OK;
+    return NGX_OK;
 
 #else
 
@@ -595,12 +623,42 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
                        "the using of the regex \"%V\" requires PCRE library",
                        name);
 
-    return NGX_CONF_ERROR;
+    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)
 {

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_rewrite_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_scgi_module.c (+18 -12) 98%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_scgi_module.c    2014-07-02 11:31:57 +0900 (49cc96d)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_scgi_module.c    2014-07-04 15:15:55 +0900 (884cb50)
@@ -65,6 +65,7 @@ static ngx_conf_bitmask_t ngx_http_scgi_next_upstream_masks[] = {
     { 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 },
@@ -261,6 +262,13 @@ static ngx_command_t ngx_http_scgi_commands[] = {
       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"),
@@ -368,7 +376,8 @@ static ngx_str_t ngx_http_scgi_hide_headers[] = {
 #if (NGX_HTTP_CACHE)
 
 static ngx_keyval_t  ngx_http_scgi_cache_headers[] = {
-    { ngx_string("HTTP_IF_MODIFIED_SINCE"), ngx_string("") },
+    { 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("") },
@@ -393,13 +402,6 @@ ngx_http_scgi_handler(ngx_http_request_t *r)
     ngx_http_upstream_t       *u;
     ngx_http_scgi_loc_conf_t  *scf;
 
-    if (r->subrequest_in_memory) {
-        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
-                      "ngx_http_scgi_module does not support "
-                      "subrequests in memory");
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
-    }
-
     if (ngx_http_upstream_create(r) != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -883,7 +885,7 @@ ngx_http_scgi_process_status_line(ngx_http_request_t *r)
         return ngx_http_scgi_process_header(r);
     }
 
-    if (u->state) {
+    if (u->state && u->state->status == 0) {
         u->state->status = status->code;
     }
 
@@ -1011,7 +1013,7 @@ ngx_http_scgi_process_header(ngx_http_request_t *r)
                 ngx_str_set(&u->headers_in.status_line, "200 OK");
             }
 
-            if (u->state) {
+            if (u->state && u->state->status == 0) {
                 u->state->status = u->headers_in.status_n;
             }
 
@@ -1099,6 +1101,7 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t *cf)
     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;
@@ -1339,6 +1342,9 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     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,
@@ -1500,7 +1506,7 @@ ngx_http_scgi_merge_params(ngx_conf_t *cf, ngx_http_scgi_loc_conf_t *conf,
 
             s->key = h->key;
             s->value = h->value;
-            s->skip_empty = 0;
+            s->skip_empty = 1;
 
         next:
 
@@ -1728,7 +1734,7 @@ ngx_http_scgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     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.variables = ngx_http_script_variables_count(&value[1]);
     sc.complete_lengths = 1;
     sc.complete_values = 1;
 

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_secure_link_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_split_clients_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_ssi_filter_module.c (+22 -20) 98%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_ssi_filter_module.c    2014-07-02 11:31:57 +0900 (eb286cc)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_ssi_filter_module.c    2014-07-04 15:15:55 +0900 (aeb1376)
@@ -21,6 +21,7 @@ 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;
 
@@ -162,6 +163,13 @@ static ngx_command_t  ngx_http_ssi_filter_commands[] = {
       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
 };
 
@@ -205,6 +213,7 @@ 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;
 
 
@@ -351,7 +360,7 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
     ctx->params.nalloc = NGX_HTTP_SSI_PARAMS_N;
     ctx->params.pool = r->pool;
 
-    ngx_str_set(&ctx->timefmt, "%A, %d-%b-%Y %H:%M:%S %Z");
+    ctx->timefmt = ngx_http_ssi_timefmt;
     ngx_str_set(&ctx->errmsg,
                 "[an error occurred while processing the directive]");
 
@@ -359,9 +368,12 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
 
     if (r == r->main) {
         ngx_http_clear_content_length(r);
-        ngx_http_clear_last_modified(r);
         ngx_http_clear_accept_ranges(r);
         ngx_http_clear_etag(r);
+
+        if (!slcf->last_modified) {
+            ngx_http_clear_last_modified(r);
+        }
     }
 
     return ngx_http_next_header_filter(r);
@@ -1971,8 +1983,6 @@ static ngx_int_t
 ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
     ngx_str_t **params)
 {
-    u_char                      *dst, *src;
-    size_t                       len;
     ngx_int_t                    rc, key;
     ngx_str_t                   *uri, *file, *wait, *set, *stub, args;
     ngx_buf_t                   *b;
@@ -2043,18 +2053,6 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
         return rc;
     }
 
-    dst = uri->data;
-    src = uri->data;
-
-    ngx_unescape_uri(&dst, &src, uri->len, NGX_UNESCAPE_URI);
-
-    len = (uri->data + uri->len) - src;
-    if (len) {
-        dst = ngx_movemem(dst, src, len);
-    }
-
-    uri->len = dst - uri->data;
-
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "ssi include: \"%V\"", uri);
 
@@ -2723,6 +2721,7 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
 {
     ngx_http_ssi_ctx_t  *ctx;
     ngx_time_t          *tp;
+    ngx_str_t           *timefmt;
     struct tm            tm;
     char                 buf[NGX_HTTP_SSI_DATE_LEN];
 
@@ -2734,9 +2733,10 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
 
     ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
 
-    if (ctx == NULL
-        || (ctx->timefmt.len == sizeof("%s") - 1
-            && ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's'))
+    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) {
@@ -2755,7 +2755,7 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
     }
 
     v->len = strftime(buf, NGX_HTTP_SSI_DATE_LEN,
-                      (char *) ctx->timefmt.data, &tm);
+                      (char *) timefmt->data, &tm);
     if (v->len == 0) {
         return NGX_ERROR;
     }
@@ -2878,6 +2878,7 @@ ngx_http_ssi_create_loc_conf(ngx_conf_t *cf)
     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;
@@ -2896,6 +2897,7 @@ ngx_http_ssi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     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);

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_ssi_filter_module.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_ssl_module.c (+127 -3) 85%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_ssl_module.c    2014-07-02 11:31:57 +0900 (a6c803d)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_ssl_module.c    2014-07-04 15:15:55 +0900 (730204c)
@@ -17,6 +17,14 @@ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
 #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,
@@ -111,6 +119,13 @@ static ngx_command_t  ngx_http_ssl_commands[] = {
       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,
@@ -119,7 +134,7 @@ static ngx_command_t  ngx_http_ssl_commands[] = {
       &ngx_http_ssl_verify },
 
     { ngx_string("ssl_verify_depth"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
+      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),
@@ -153,6 +168,20 @@ static ngx_command_t  ngx_http_ssl_commands[] = {
       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,
@@ -241,6 +270,12 @@ static ngx_http_variable_t  ngx_http_ssl_vars[] = {
     { 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_server_name"), NULL, ngx_http_ssl_variable,
+      (uintptr_t) ngx_ssl_get_server_name, 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 },
 
@@ -257,6 +292,9 @@ static ngx_http_variable_t  ngx_http_ssl_vars[] = {
     { ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
       (uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
 
+    { ngx_string("ssl_client_fingerprint"), NULL, ngx_http_ssl_variable,
+      (uintptr_t) ngx_ssl_get_fingerprint, 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 },
 
@@ -267,9 +305,65 @@ static ngx_http_variable_t  ngx_http_ssl_vars[] = {
 static ngx_str_t ngx_http_ssl_sess_id_ctx = ngx_string("HTTP");
 
 
-#ifdef TLSEXT_TYPE_next_proto_neg
+#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
 
-#define NGX_HTTP_NPN_ADVERTISE  "\x08http/1.1"
+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,
@@ -417,10 +511,13 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
 
     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;
 
@@ -457,6 +554,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
                          (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);
 
@@ -534,6 +634,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
 
 #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);
@@ -561,8 +665,11 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
         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) {
@@ -622,6 +729,23 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
         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,

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_ssl_module.h (+5 -0) 90%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_ssl_module.h    2014-07-02 11:31:57 +0900 (c4c576e)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_ssl_module.h    2014-07-04 15:15:55 +0900 (ec2c62f)
@@ -26,6 +26,8 @@ typedef struct {
     ngx_uint_t                      verify;
     ngx_uint_t                      verify_depth;
 
+    size_t                          buffer_size;
+
     ssize_t                         builtin_session_cache;
 
     time_t                          session_timeout;
@@ -42,6 +44,9 @@ typedef struct {
 
     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;

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_static_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_stub_status_module.c (+3 -0) 97%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_stub_status_module.c    2014-07-02 11:31:57 +0900 (83a35cd)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_stub_status_module.c    2014-07-04 15:15:55 +0900 (b5ecd6d)
@@ -98,7 +98,9 @@ static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
         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;
@@ -145,6 +147,7 @@ static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
     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);
 

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_sub_filter_module.c (+127 -91) 79%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_sub_filter_module.c    2014-07-02 11:31:57 +0900 (6ba57df)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_sub_filter_module.c    2014-07-04 15:15:55 +0900 (3ba59d6)
@@ -17,6 +17,7 @@ typedef struct {
     ngx_hash_t                 types;
 
     ngx_flag_t                 once;
+    ngx_flag_t                 last_modified;
 
     ngx_array_t               *types_keys;
 } ngx_http_sub_loc_conf_t;
@@ -89,6 +90,13 @@ static ngx_command_t  ngx_http_sub_filter_commands[] = {
       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
 };
 
@@ -167,8 +175,11 @@ ngx_http_sub_header_filter(ngx_http_request_t *r)
 
     if (r == r->main) {
         ngx_http_clear_content_length(r);
-        ngx_http_clear_last_modified(r);
         ngx_http_clear_etag(r);
+
+        if (!slcf->last_modified) {
+            ngx_http_clear_last_modified(r);
+        }
     }
 
     return ngx_http_next_header_filter(r);
@@ -250,66 +261,43 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
                 return rc;
             }
 
-            if (ctx->copy_start != ctx->copy_end) {
+            if (ctx->saved.len) {
 
                 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                                "saved: \"%V\"", &ctx->saved);
 
-                if (ctx->saved.len) {
+                cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
+                if (cl == NULL) {
+                    return NGX_ERROR;
+                }
 
-                    if (ctx->free) {
-                        cl = ctx->free;
-                        ctx->free = ctx->free->next;
-                        b = cl->buf;
-                        ngx_memzero(b, sizeof(ngx_buf_t));
+                b = cl->buf;
 
-                    } else {
-                        b = ngx_calloc_buf(r->pool);
-                        if (b == NULL) {
-                            return NGX_ERROR;
-                        }
+                ngx_memzero(b, sizeof(ngx_buf_t));
 
-                        cl = ngx_alloc_chain_link(r->pool);
-                        if (cl == NULL) {
-                            return NGX_ERROR;
-                        }
+                b->pos = ngx_pnalloc(r->pool, ctx->saved.len);
+                if (b->pos == NULL) {
+                    return NGX_ERROR;
+                }
 
-                        cl->buf = b;
-                    }
+                ngx_memcpy(b->pos, ctx->saved.data, ctx->saved.len);
+                b->last = b->pos + ctx->saved.len;
+                b->memory = 1;
 
-                    b->pos = ngx_pnalloc(r->pool, ctx->saved.len);
-                    if (b->pos == NULL) {
-                        return NGX_ERROR;
-                    }
+                *ctx->last_out = cl;
+                ctx->last_out = &cl->next;
 
-                    ngx_memcpy(b->pos, ctx->saved.data, ctx->saved.len);
-                    b->last = b->pos + ctx->saved.len;
-                    b->memory = 1;
+                ctx->saved.len = 0;
+            }
 
-                    *ctx->last_out = cl;
-                    ctx->last_out = &cl->next;
+            if (ctx->copy_start != ctx->copy_end) {
 
-                    ctx->saved.len = 0;
+                cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
+                if (cl == NULL) {
+                    return NGX_ERROR;
                 }
 
-                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;
-                }
+                b = cl->buf;
 
                 ngx_memcpy(b, ctx->buf, sizeof(ngx_buf_t));
 
@@ -317,6 +305,7 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
                 b->last = ctx->copy_end;
                 b->shadow = NULL;
                 b->last_buf = 0;
+                b->last_in_chain = 0;
                 b->recycled = 0;
 
                 if (b->in_file) {
@@ -324,7 +313,6 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
                     b->file_pos += b->pos - ctx->buf->pos;
                 }
 
-                cl->next = NULL;
                 *ctx->last_out = cl;
                 ctx->last_out = &cl->next;
             }
@@ -338,6 +326,11 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
                 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;
             }
@@ -345,16 +338,15 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
 
             /* rc == NGX_OK */
 
-            b = ngx_calloc_buf(r->pool);
-            if (b == NULL) {
-                return NGX_ERROR;
-            }
-
-            cl = ngx_alloc_chain_link(r->pool);
+            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) {
@@ -375,8 +367,6 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
                 b->sync = 1;
             }
 
-            cl->buf = b;
-            cl->next = NULL;
             *ctx->last_out = cl;
             ctx->last_out = &cl->next;
 
@@ -385,36 +375,50 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
             continue;
         }
 
-        if (ctx->buf->last_buf || ngx_buf_in_memory(ctx->buf)) {
+        if (ctx->looked.len
+            && (ctx->buf->last_buf || ctx->buf->last_in_chain))
+        {
+            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 || ctx->buf->sync
+            || 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;
+                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;
 
-                cl->next = NULL;
                 *ctx->last_out = cl;
                 ctx->last_out = &cl->next;
             }
 
             b->last_buf = ctx->buf->last_buf;
+            b->last_in_chain = ctx->buf->last_in_chain;
+            b->flush = ctx->buf->flush;
             b->shadow = ctx->buf;
 
             b->recycled = ctx->buf->recycled;
@@ -507,7 +511,7 @@ 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;
+    size_t                 looked, i;
     ngx_http_sub_state_e   state;
 
     if (ctx->once) {
@@ -578,13 +582,11 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
             looked++;
 
             if (looked == ctx->match.len) {
-                if ((size_t) (p - ctx->pos) < looked) {
-                    ctx->saved.len = 0;
-                }
 
                 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) {
@@ -594,18 +596,53 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
                 return NGX_OK;
             }
 
-        } else if (ch == ctx->match.data[0]) {
-            copy_end = p;
-            ctx->looked.data[0] = *p;
-            looked = 1;
-
         } else {
-            copy_end = p;
-            looked = 0;
-            state = sub_start_state;
+            /*
+             * 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;
@@ -666,14 +703,12 @@ ngx_http_sub_create_conf(ngx_conf_t *cf)
      * set by ngx_pcalloc():
      *
      *     conf->match = { 0, NULL };
-     *     conf->sub = { 0, NULL };
-     *     conf->sub_lengths = NULL;
-     *     conf->sub_values = NULL;
      *     conf->types = { NULL };
      *     conf->types_keys = NULL;
      */
 
     slcf->once = NGX_CONF_UNSET;
+    slcf->last_modified = NGX_CONF_UNSET;
 
     return slcf;
 }
@@ -687,6 +722,7 @@ ngx_http_sub_merge_conf(ngx_conf_t *cf, void *parent, void *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;

  Added: vendor/nginx-1.7.2/src/http/modules/ngx_http_upstream_hash_module.c (+631 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_upstream_hash_module.c    2014-07-04 15:15:55 +0900 (777e180)
@@ -0,0 +1,631 @@
+
+/*
+ * Copyright (C) Roman Arutyunyan
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+
+typedef struct {
+    uint32_t                            hash;
+    ngx_str_t                          *server;
+} ngx_http_upstream_chash_point_t;
+
+
+typedef struct {
+    ngx_uint_t                          number;
+    ngx_http_upstream_chash_point_t     point[1];
+} ngx_http_upstream_chash_points_t;
+
+
+typedef struct {
+    ngx_http_complex_value_t            key;
+    ngx_http_upstream_chash_points_t   *points;
+} ngx_http_upstream_hash_srv_conf_t;
+
+
+typedef struct {
+    /* the round robin data must be first */
+    ngx_http_upstream_rr_peer_data_t    rrp;
+    ngx_http_upstream_hash_srv_conf_t  *conf;
+    ngx_str_t                           key;
+    ngx_uint_t                          tries;
+    ngx_uint_t                          rehash;
+    uint32_t                            hash;
+    ngx_event_get_peer_pt               get_rr_peer;
+} ngx_http_upstream_hash_peer_data_t;
+
+
+static ngx_int_t ngx_http_upstream_init_hash(ngx_conf_t *cf,
+    ngx_http_upstream_srv_conf_t *us);
+static ngx_int_t ngx_http_upstream_init_hash_peer(ngx_http_request_t *r,
+    ngx_http_upstream_srv_conf_t *us);
+static ngx_int_t ngx_http_upstream_get_hash_peer(ngx_peer_connection_t *pc,
+    void *data);
+
+static ngx_int_t ngx_http_upstream_init_chash(ngx_conf_t *cf,
+    ngx_http_upstream_srv_conf_t *us);
+static void ngx_http_upstream_add_chash_point(
+    ngx_http_upstream_chash_points_t *points, uint32_t hash, ngx_str_t *server);
+static ngx_uint_t ngx_http_upstream_find_chash_point(
+    ngx_http_upstream_chash_points_t *points, uint32_t hash);
+static ngx_int_t ngx_http_upstream_init_chash_peer(ngx_http_request_t *r,
+    ngx_http_upstream_srv_conf_t *us);
+static ngx_int_t ngx_http_upstream_get_chash_peer(ngx_peer_connection_t *pc,
+    void *data);
+
+static void *ngx_http_upstream_hash_create_conf(ngx_conf_t *cf);
+static char *ngx_http_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd,
+    void *conf);
+
+
+static ngx_command_t  ngx_http_upstream_hash_commands[] = {
+
+    { ngx_string("hash"),
+      NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
+      ngx_http_upstream_hash,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      0,
+      NULL },
+
+      ngx_null_command
+};
+
+
+static ngx_http_module_t  ngx_http_upstream_hash_module_ctx = {
+    NULL,                                  /* preconfiguration */
+    NULL,                                  /* postconfiguration */
+
+    NULL,                                  /* create main configuration */
+    NULL,                                  /* init main configuration */
+
+    ngx_http_upstream_hash_create_conf,    /* create server configuration */
+    NULL,                                  /* merge server configuration */
+
+    NULL,                                  /* create location configuration */
+    NULL                                   /* merge location configuration */
+};
+
+
+ngx_module_t  ngx_http_upstream_hash_module = {
+    NGX_MODULE_V1,
+    &ngx_http_upstream_hash_module_ctx,    /* module context */
+    ngx_http_upstream_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 ngx_int_t
+ngx_http_upstream_init_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_hash_peer;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_upstream_init_hash_peer(ngx_http_request_t *r,
+    ngx_http_upstream_srv_conf_t *us)
+{
+    ngx_http_upstream_hash_srv_conf_t   *hcf;
+    ngx_http_upstream_hash_peer_data_t  *hp;
+
+    hp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_hash_peer_data_t));
+    if (hp == NULL) {
+        return NGX_ERROR;
+    }
+
+    r->upstream->peer.data = &hp->rrp;
+
+    if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    r->upstream->peer.get = ngx_http_upstream_get_hash_peer;
+
+    hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module);
+
+    if (ngx_http_complex_value(r, &hcf->key, &hp->key) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "upstream hash key:\"%V\"", &hp->key);
+
+    hp->conf = hcf;
+    hp->tries = 0;
+    hp->rehash = 0;
+    hp->hash = 0;
+    hp->get_rr_peer = ngx_http_upstream_get_round_robin_peer;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_upstream_get_hash_peer(ngx_peer_connection_t *pc, void *data)
+{
+    ngx_http_upstream_hash_peer_data_t  *hp = data;
+
+    time_t                        now;
+    u_char                        buf[NGX_INT_T_LEN];
+    size_t                        size;
+    uint32_t                      hash;
+    ngx_int_t                     w;
+    uintptr_t                     m;
+    ngx_uint_t                    i, n, p;
+    ngx_http_upstream_rr_peer_t  *peer;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
+                   "get hash peer, try: %ui", pc->tries);
+
+    if (hp->tries > 20 || hp->rrp.peers->single) {
+        return hp->get_rr_peer(pc, &hp->rrp);
+    }
+
+    now = ngx_time();
+
+    pc->cached = 0;
+    pc->connection = NULL;
+
+    for ( ;; ) {
+
+        /*
+         * Hash expression is compatible with Cache::Memcached:
+         * ((crc32([REHASH] KEY) >> 16) & 0x7fff) + PREV_HASH
+         * with REHASH omitted at the first iteration.
+         */
+
+        ngx_crc32_init(hash);
+
+        if (hp->rehash > 0) {
+            size = ngx_sprintf(buf, "%ui", hp->rehash) - buf;
+            ngx_crc32_update(&hash, buf, size);
+        }
+
+        ngx_crc32_update(&hash, hp->key.data, hp->key.len);
+        ngx_crc32_final(hash);
+
+        hash = (hash >> 16) & 0x7fff;
+
+        hp->hash += hash;
+        hp->rehash++;
+
+        if (!hp->rrp.peers->weighted) {
+            p = hp->hash % hp->rrp.peers->number;
+
+        } else {
+            w = hp->hash % hp->rrp.peers->total_weight;
+
+            for (i = 0; i < hp->rrp.peers->number; i++) {
+                w -= hp->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 (hp->rrp.tried[n] & m) {
+            goto next;
+        }
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
+                       "get hash peer, value:%uD, peer:%ui", hp->hash, p);
+
+        peer = &hp->rrp.peers->peer[p];
+
+        if (peer->down) {
+            goto next;
+        }
+
+        if (peer->max_fails
+            && peer->fails >= peer->max_fails
+            && now - peer->checked <= peer->fail_timeout)
+        {
+            goto next;
+        }
+
+        break;
+
+    next:
+
+        if (++hp->tries > 20) {
+            return hp->get_rr_peer(pc, &hp->rrp);
+        }
+    }
+
+    hp->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;
+    }
+
+    hp->rrp.tried[n] |= m;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_upstream_init_chash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
+{
+    u_char                             *host, *port, c;
+    size_t                              host_len, port_len, size;
+    uint32_t                            hash, base_hash, prev_hash;
+    ngx_str_t                          *server;
+    ngx_uint_t                          npoints, i, j;
+    ngx_http_upstream_rr_peer_t        *peer;
+    ngx_http_upstream_rr_peers_t       *peers;
+    ngx_http_upstream_chash_points_t   *points;
+    ngx_http_upstream_hash_srv_conf_t  *hcf;
+
+    if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    us->peer.init = ngx_http_upstream_init_chash_peer;
+
+    peers = us->peer.data;
+    npoints = peers->total_weight * 160;
+
+    size = sizeof(ngx_http_upstream_chash_points_t)
+           + sizeof(ngx_http_upstream_chash_point_t) * (npoints - 1);
+
+    points = ngx_palloc(cf->pool, size);
+    if (points == NULL) {
+        return NGX_ERROR;
+    }
+
+    points->number = 0;
+
+    for (i = 0; i < peers->number; i++) {
+        peer = &peers->peer[i];
+        server = &peer->server;
+
+        /*
+         * Hash expression is compatible with Cache::Memcached::Fast:
+         * crc32(HOST \0 PORT PREV_HASH).
+         */
+
+        if (server->len >= 5
+            && ngx_strncasecmp(server->data, (u_char *) "unix:", 5) == 0)
+        {
+            host = server->data + 5;
+            host_len = server->len - 5;
+            port = NULL;
+            port_len = 0;
+            goto done;
+        }
+
+        for (j = 0; j < server->len; j++) {
+            c = server->data[server->len - j - 1];
+
+            if (c == ':') {
+                host = server->data;
+                host_len = server->len - j - 1;
+                port = server->data + server->len - j;
+                port_len = j;
+                goto done;
+            }
+
+            if (c < '0' || c > '9') {
+                break;
+            }
+        }
+
+        host = server->data;
+        host_len = server->len;
+        port = NULL;
+        port_len = 0;
+
+    done:
+
+        ngx_crc32_init(base_hash);
+        ngx_crc32_update(&base_hash, host, host_len);
+        ngx_crc32_update(&base_hash, (u_char *) "", 1);
+        ngx_crc32_update(&base_hash, port, port_len);
+
+        prev_hash = 0;
+        npoints = peer->weight * 160;
+
+        for (j = 0; j < npoints; j++) {
+            hash = base_hash;
+
+            ngx_crc32_update(&hash, (u_char *) &prev_hash, sizeof(uint32_t));
+            ngx_crc32_final(hash);
+
+            ngx_http_upstream_add_chash_point(points, hash, &peer->server);
+
+            prev_hash = hash;
+        }
+    }
+
+    hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module);
+    hcf->points = points;
+
+    return NGX_OK;
+}
+
+
+static void
+ngx_http_upstream_add_chash_point(ngx_http_upstream_chash_points_t *points,
+    uint32_t hash, ngx_str_t *server)
+{
+    size_t                            size;
+    ngx_uint_t                        i;
+    ngx_http_upstream_chash_point_t  *point;
+
+    i = ngx_http_upstream_find_chash_point(points, hash);
+    point = &points->point[i];
+
+    if (point->hash == hash) {
+        return;
+    }
+
+    size = (points->number - i) * sizeof(ngx_http_upstream_chash_point_t);
+
+    ngx_memmove(point + 1, point, size);
+
+    points->number++;
+    point->hash = hash;
+    point->server = server;
+}
+
+
+static ngx_uint_t
+ngx_http_upstream_find_chash_point(ngx_http_upstream_chash_points_t *points,
+    uint32_t hash)
+{
+    ngx_uint_t                        i, j, k;
+    ngx_http_upstream_chash_point_t  *point;
+
+    /* find first point >= hash */
+
+    point = &points->point[0];
+
+    i = 0;
+    j = points->number;
+
+    while (i < j) {
+        k = (i + j) / 2;
+
+        if (hash > point[k].hash) {
+            i = k + 1;
+
+        } else if (hash < point[k].hash) {
+            j = k;
+
+        } else {
+            return k;
+        }
+    }
+
+    return i;
+}
+
+
+static ngx_int_t
+ngx_http_upstream_init_chash_peer(ngx_http_request_t *r,
+    ngx_http_upstream_srv_conf_t *us)
+{
+    uint32_t                             hash;
+    ngx_http_upstream_hash_srv_conf_t   *hcf;
+    ngx_http_upstream_hash_peer_data_t  *hp;
+
+    if (ngx_http_upstream_init_hash_peer(r, us) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    r->upstream->peer.get = ngx_http_upstream_get_chash_peer;
+
+    hp = r->upstream->peer.data;
+    hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module);
+
+    hash = ngx_crc32_long(hp->key.data, hp->key.len);
+    hp->hash = ngx_http_upstream_find_chash_point(hcf->points, hash);
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_upstream_get_chash_peer(ngx_peer_connection_t *pc, void *data)
+{
+    ngx_http_upstream_hash_peer_data_t  *hp = data;
+
+    time_t                              now;
+    intptr_t                            m;
+    ngx_str_t                          *server;
+    ngx_int_t                           total;
+    ngx_uint_t                          i, n;
+    ngx_http_upstream_rr_peer_t        *peer, *best;
+    ngx_http_upstream_chash_point_t    *point;
+    ngx_http_upstream_chash_points_t   *points;
+    ngx_http_upstream_hash_srv_conf_t  *hcf;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
+                   "get consistent hash peer, try: %ui", pc->tries);
+
+    pc->cached = 0;
+    pc->connection = NULL;
+
+    now = ngx_time();
+    hcf = hp->conf;
+
+    points = hcf->points;
+    point = &points->point[0];
+
+    for ( ;; ) {
+        server = point[hp->hash % points->number].server;
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
+                       "consistent hash peer:%uD, server:\"%V\"",
+                       hp->hash, server);
+
+        best = NULL;
+        total = 0;
+
+        for (i = 0; i < hp->rrp.peers->number; i++) {
+
+            n = i / (8 * sizeof(uintptr_t));
+            m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
+
+            if (hp->rrp.tried[n] & m) {
+                continue;
+            }
+
+            peer = &hp->rrp.peers->peer[i];
+
+            if (peer->down) {
+                continue;
+            }
+
+            if (peer->server.len != server->len
+                || ngx_strncmp(peer->server.data, server->data, server->len)
+                   != 0)
+            {
+                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) {
+            best->current_weight -= total;
+
+            i = best - &hp->rrp.peers->peer[0];
+
+            hp->rrp.current = i;
+
+            n = i / (8 * sizeof(uintptr_t));
+            m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
+
+            hp->rrp.tried[n] |= m;
+
+            if (now - best->checked > best->fail_timeout) {
+                best->checked = now;
+            }
+
+            pc->sockaddr = best->sockaddr;
+            pc->socklen = best->socklen;
+            pc->name = &best->name;
+
+            return NGX_OK;
+        }
+
+        hp->hash++;
+        hp->tries++;
+
+        if (hp->tries >= points->number) {
+            return NGX_BUSY;
+        }
+    }
+}
+
+
+static void *
+ngx_http_upstream_hash_create_conf(ngx_conf_t *cf)
+{
+    ngx_http_upstream_hash_srv_conf_t  *conf;
+
+    conf = ngx_palloc(cf->pool, sizeof(ngx_http_upstream_hash_srv_conf_t));
+    if (conf == NULL) {
+        return NULL;
+    }
+
+    conf->points = NULL;
+
+    return conf;
+}
+
+
+static char *
+ngx_http_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+    ngx_http_upstream_hash_srv_conf_t  *hcf = conf;
+
+    ngx_str_t                         *value;
+    ngx_http_upstream_srv_conf_t      *uscf;
+    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 = &hcf->key;
+
+    if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
+    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->flags = NGX_HTTP_UPSTREAM_CREATE
+                  |NGX_HTTP_UPSTREAM_WEIGHT
+                  |NGX_HTTP_UPSTREAM_MAX_FAILS
+                  |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
+                  |NGX_HTTP_UPSTREAM_DOWN;
+
+    if (cf->args->nelts == 2) {
+        uscf->peer.init_upstream = ngx_http_upstream_init_hash;
+
+    } else if (ngx_strcmp(value[2].data, "consistent") == 0) {
+        uscf->peer.init_upstream = ngx_http_upstream_init_chash;
+
+    } else {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "invalid parameter \"%V\"", &value[2]);
+        return NGX_CONF_ERROR;
+    }
+
+    return NGX_CONF_OK;
+}

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_upstream_ip_hash_module.c (+30 -20) 88%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_upstream_ip_hash_module.c    2014-07-02 11:31:57 +0900 (29c74fd)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_upstream_ip_hash_module.c    2014-07-04 15:15:55 +0900 (148d73a)
@@ -174,7 +174,7 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
 
     for ( ;; ) {
 
-        for (i = 0; i < iphp->addrlen; i++) {
+        for (i = 0; i < (ngx_uint_t) iphp->addrlen; i++) {
             hash = (hash * 113 + iphp->addr[i]) % 6271;
         }
 
@@ -197,35 +197,41 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
         n = p / (8 * sizeof(uintptr_t));
         m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
 
-        if (!(iphp->rrp.tried[n] & m)) {
+        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);
+        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];
+        peer = &iphp->rrp.peers->peer[p];
 
-            /* ngx_lock_mutex(iphp->rrp.peers->mutex); */
+        /* ngx_lock_mutex(iphp->rrp.peers->mutex); */
 
-            if (!peer->down) {
+        if (peer->down) {
+            goto next_try;
+        }
 
-                if (peer->max_fails == 0 || peer->fails < peer->max_fails) {
-                    break;
-                }
+        if (peer->max_fails
+            && peer->fails >= peer->max_fails
+            && now - peer->checked <= peer->fail_timeout)
+        {
+            goto next_try;
+        }
 
-                if (now - peer->checked > peer->fail_timeout) {
-                    peer->checked = now;
-                    break;
-                }
-            }
+        break;
 
-            iphp->rrp.tried[n] |= m;
+    next_try:
 
-            /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
+        iphp->rrp.tried[n] |= m;
 
-            pc->tries--;
-        }
+        /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
+
+        pc->tries--;
 
-        if (++iphp->tries >= 20) {
+    next:
+
+        if (++iphp->tries > 20) {
             return iphp->get_rr_peer(pc, &iphp->rrp);
         }
     }
@@ -236,6 +242,10 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
     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;

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_upstream_keepalive_module.c (+2 -5) 98%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_upstream_keepalive_module.c    2014-07-02 11:31:57 +0900 (eed1174)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_upstream_keepalive_module.c    2014-07-04 15:15:55 +0900 (d07ed9e)
@@ -81,7 +81,7 @@ static ngx_command_t  ngx_http_upstream_keepalive_commands[] = {
     { ngx_string("keepalive"),
       NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
       ngx_http_upstream_keepalive,
-      0,
+      NGX_HTTP_SRV_CONF_OFFSET,
       0,
       NULL },
 
@@ -481,7 +481,7 @@ 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;
+    ngx_http_upstream_keepalive_srv_conf_t  *kcf = conf;
 
     ngx_int_t    n;
     ngx_str_t   *value;
@@ -489,9 +489,6 @@ ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
 
-    kcf = ngx_http_conf_upstream_srv_conf(uscf,
-                                          ngx_http_upstream_keepalive_module);
-
     if (kcf->original_init_upstream) {
         return "is duplicate";
     }

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_upstream_least_conn_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_userid_filter_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_uwsgi_module.c (+300 -19) 85%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_uwsgi_module.c    2014-07-02 11:31:57 +0900 (623ee49)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_uwsgi_module.c    2014-07-04 15:15:55 +0900 (1d515cd)
@@ -34,6 +34,15 @@ typedef struct {
 
     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;
+    ngx_uint_t                 ssl_verify_depth;
+    ngx_str_t                  ssl_trusted_certificate;
+    ngx_str_t                  ssl_crl;
+#endif
 } ngx_http_uwsgi_loc_conf_t;
 
 
@@ -66,6 +75,11 @@ 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
@@ -78,6 +92,7 @@ static ngx_conf_bitmask_t ngx_http_uwsgi_next_upstream_masks[] = {
     { 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 },
@@ -85,6 +100,20 @@ static ngx_conf_bitmask_t ngx_http_uwsgi_next_upstream_masks[] = {
 };
 
 
+#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;
 
 
@@ -288,6 +317,13 @@ static ngx_command_t ngx_http_uwsgi_commands[] = {
       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"),
@@ -353,6 +389,73 @@ static ngx_command_t ngx_http_uwsgi_commands[] = {
       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 },
+
+    { ngx_string("uwsgi_ssl_name"),
+      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_uwsgi_loc_conf_t, upstream.ssl_name),
+      NULL },
+
+    { ngx_string("uwsgi_ssl_server_name"),
+      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_server_name),
+      NULL },
+
+    { ngx_string("uwsgi_ssl_verify"),
+      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_verify),
+      NULL },
+
+    { ngx_string("uwsgi_ssl_verify_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_uwsgi_loc_conf_t, ssl_verify_depth),
+      NULL },
+
+    { ngx_string("uwsgi_ssl_trusted_certificate"),
+      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_trusted_certificate),
+      NULL },
+
+    { ngx_string("uwsgi_ssl_crl"),
+      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_crl),
+      NULL },
+
+#endif
+
       ngx_null_command
 };
 
@@ -401,7 +504,8 @@ static ngx_str_t ngx_http_uwsgi_hide_headers[] = {
 #if (NGX_HTTP_CACHE)
 
 static ngx_keyval_t  ngx_http_uwsgi_cache_headers[] = {
-    { ngx_string("HTTP_IF_MODIFIED_SINCE"), ngx_string("") },
+    { 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("") },
@@ -426,13 +530,6 @@ ngx_http_uwsgi_handler(ngx_http_request_t *r)
     ngx_http_upstream_t        *u;
     ngx_http_uwsgi_loc_conf_t  *uwcf;
 
-    if (r->subrequest_in_memory) {
-        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
-                      "ngx_http_uwsgi_module does not support "
-                      "subrequests in memory");
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
-    }
-
     if (ngx_http_upstream_create(r) != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -446,15 +543,29 @@ ngx_http_uwsgi_handler(ngx_http_request_t *r)
 
     uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
 
-    if (uwcf->uwsgi_lengths) {
+    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 = r->upstream;
-
-    ngx_str_set(&u->schema, "uwsgi://");
     u->output.tag = (ngx_buf_tag_t) &ngx_http_uwsgi_module;
 
     u->conf = &uwcf->upstream;
@@ -492,6 +603,7 @@ ngx_http_uwsgi_handler(ngx_http_request_t *r)
 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;
 
@@ -504,6 +616,41 @@ ngx_http_uwsgi_eval(ngx_http_request_t *r, ngx_http_uwsgi_loc_conf_t * uwcf)
         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) {
@@ -515,8 +662,6 @@ ngx_http_uwsgi_eval(ngx_http_request_t *r, ngx_http_uwsgi_loc_conf_t * uwcf)
         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;
@@ -917,7 +1062,7 @@ ngx_http_uwsgi_process_status_line(ngx_http_request_t *r)
         return ngx_http_uwsgi_process_header(r);
     }
 
-    if (u->state) {
+    if (u->state && u->state->status == 0) {
         u->state->status = status->code;
     }
 
@@ -1045,7 +1190,7 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
                 ngx_str_set(&u->headers_in.status_line, "200 OK");
             }
 
-            if (u->state) {
+            if (u->state && u->state->status == 0) {
                 u->state->status = u->headers_in.status_n;
             }
 
@@ -1136,6 +1281,7 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
     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;
@@ -1143,6 +1289,13 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
 
     conf->upstream.intercept_errors = NGX_CONF_UNSET;
 
+#if (NGX_HTTP_SSL)
+    conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
+    conf->upstream.ssl_server_name = NGX_CONF_UNSET;
+    conf->upstream.ssl_verify = NGX_CONF_UNSET;
+    conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
+#endif
+
     /* "uwsgi_cyclic_temp_file" is disabled */
     conf->upstream.cyclic_temp_file = 0;
 
@@ -1376,6 +1529,9 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     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,
@@ -1386,6 +1542,43 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     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->upstream.ssl_name == NULL) {
+        conf->upstream.ssl_name = prev->upstream.ssl_name;
+    }
+
+    ngx_conf_merge_value(conf->upstream.ssl_server_name,
+                              prev->upstream.ssl_server_name, 0);
+    ngx_conf_merge_value(conf->upstream.ssl_verify,
+                              prev->upstream.ssl_verify, 0);
+    ngx_conf_merge_uint_value(conf->ssl_verify_depth,
+                              prev->ssl_verify_depth, 1);
+    ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
+                              prev->ssl_trusted_certificate, "");
+    ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
+
+    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;
@@ -1542,7 +1735,7 @@ ngx_http_uwsgi_merge_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
 
             s->key = h->key;
             s->value = h->value;
-            s->skip_empty = 0;
+            s->skip_empty = 1;
 
         next:
 
@@ -1664,6 +1857,7 @@ 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;
@@ -1699,12 +1893,35 @@ ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
             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 = value[1];
+    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);
@@ -1764,7 +1981,7 @@ ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     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.variables = ngx_http_script_variables_count(&value[1]);
     sc.complete_lengths = 1;
     sc.complete_values = 1;
 
@@ -1838,3 +2055,67 @@ 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)
+{
+    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;
+    }
+
+    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;
+
+    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;
+    }
+
+    if (uwcf->upstream.ssl_verify) {
+        if (uwcf->ssl_trusted_certificate.len == 0) {
+            ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+                      "no uwsgi_ssl_trusted_certificate for uwsgi_ssl_verify");
+            return NGX_ERROR;
+        }
+
+        if (ngx_ssl_trusted_certificate(cf, uwcf->upstream.ssl,
+                                        &uwcf->ssl_trusted_certificate,
+                                        uwcf->ssl_verify_depth)
+            != NGX_OK)
+        {
+            return NGX_ERROR;
+        }
+
+        if (ngx_ssl_crl(cf, uwcf->upstream.ssl, &uwcf->ssl_crl) != NGX_OK) {
+            return NGX_ERROR;
+        }
+    }
+
+    return NGX_OK;
+}
+
+#endif

  Renamed: vendor/nginx-1.7.2/src/http/modules/ngx_http_xslt_filter_module.c (+32 -6) 96%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/ngx_http_xslt_filter_module.c    2014-07-02 11:31:57 +0900 (a6ae1ce)
+++ vendor/nginx-1.7.2/src/http/modules/ngx_http_xslt_filter_module.c    2014-07-04 15:15:55 +0900 (9e85693)
@@ -58,6 +58,7 @@ typedef struct {
     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;
 
 
@@ -103,6 +104,7 @@ 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);
 
@@ -150,12 +152,19 @@ static ngx_command_t  ngx_http_xslt_filter_commands[] = {
       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 = {
-    NULL,                                  /* preconfiguration */
+    ngx_http_xslt_filter_preconfiguration, /* preconfiguration */
     ngx_http_xslt_filter_init,             /* postconfiguration */
 
     ngx_http_xslt_filter_create_main_conf, /* create main configuration */
@@ -300,9 +309,10 @@ 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_int_t                         rc;
+    ngx_chain_t                       out;
+    ngx_pool_cleanup_t               *cln;
+    ngx_http_xslt_filter_loc_conf_t  *conf;
 
     ctx->done = 1;
 
@@ -327,8 +337,13 @@ ngx_http_xslt_send(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
             r->headers_out.content_length = NULL;
         }
 
-        ngx_http_clear_last_modified(r);
         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);
@@ -1058,6 +1073,8 @@ ngx_http_xslt_filter_create_conf(ngx_conf_t *cf)
      *     conf->params = NULL;
      */
 
+    conf->last_modified = NGX_CONF_UNSET;
+
     return conf;
 }
 
@@ -1088,12 +1105,14 @@ ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
         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_init(ngx_conf_t *cf)
+ngx_http_xslt_filter_preconfiguration(ngx_conf_t *cf)
 {
     xmlInitParser();
 
@@ -1101,6 +1120,13 @@ ngx_http_xslt_filter_init(ngx_conf_t *cf)
     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;
 

  Renamed: vendor/nginx-1.7.2/src/http/modules/perl/Makefile.PL (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/perl/nginx.pm (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/perl/nginx.xs (+4 -7) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/perl/nginx.xs    2014-07-02 11:31:57 +0900 (77fb653)
+++ vendor/nginx-1.7.2/src/http/modules/perl/nginx.xs    2014-07-04 15:15:55 +0900 (71f17a8)
@@ -261,13 +261,12 @@ header_in(r, key)
             sep = ';';
             goto multi;
         }
-
-    #if (NGX_HTTP_X_FORWARDED_FOR)
+#if (NGX_HTTP_X_FORWARDED_FOR)
         if (hh->offset == offsetof(ngx_http_headers_in_t, x_forwarded_for)) {
             sep = ',';
             goto multi;
         }
-    #endif
+#endif
 
         if (hh->offset) {
 
@@ -898,8 +897,7 @@ variable(r, name, value = NULL)
 
     var.len = len;
     var.data = lowcase;
-
-    #if (NGX_DEBUG)
+#if (NGX_DEBUG)
 
     if (value) {
         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -908,8 +906,7 @@ variable(r, name, value = NULL)
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "perl variable: \"%V\"", &var);
     }
-
-    #endif
+#endif
 
     vv = ngx_http_get_variable(r, &var, hash);
     if (vv == NULL) {

  Renamed: vendor/nginx-1.7.2/src/http/modules/perl/ngx_http_perl_module.c (+2 -2) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/modules/perl/ngx_http_perl_module.c    2014-07-02 11:31:57 +0900 (90e32e8)
+++ vendor/nginx-1.7.2/src/http/modules/perl/ngx_http_perl_module.c    2014-07-04 15:15:55 +0900 (bf4d1fe)
@@ -421,7 +421,7 @@ ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx,
             return NGX_ERROR;
         }
 
-        asv[0] = (SV *) i;
+        asv[0] = (SV *) (uintptr_t) i;
 
         for (i = 0; args[i]; i++) {
             asv[i + 1] = newSVpvn((char *) args[i]->data, args[i]->len);
@@ -692,7 +692,7 @@ ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub,
     if (args) {
         EXTEND(sp, (intptr_t) args[0]);
 
-        for (i = 1; i <= (ngx_uint_t) args[0]; i++) {
+        for (i = 1; i <= (uintptr_t) args[0]; i++) {
             PUSHs(sv_2mortal(args[i]));
         }
     }

  Renamed: vendor/nginx-1.7.2/src/http/modules/perl/ngx_http_perl_module.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/modules/perl/typemap (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http.c (+17 -7) 98%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http.c    2014-07-02 11:31:57 +0900 (987ae54)
+++ vendor/nginx-1.7.2/src/http/ngx_http.c    2014-07-04 15:15:55 +0900 (ce5adb7)
@@ -949,7 +949,8 @@ ngx_http_cmp_locations(const ngx_queue_t *one, const ngx_queue_t *two)
 
 #endif
 
-    rc = ngx_strcmp(first->name.data, second->name.data);
+    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 */
@@ -975,8 +976,10 @@ ngx_http_join_exact_locations(ngx_conf_t *cf, ngx_queue_t *locations)
         lq = (ngx_http_location_queue_t *) q;
         lx = (ngx_http_location_queue_t *) x;
 
-        if (ngx_strcmp(lq->name->data, lx->name->data) == 0) {
-
+        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",
@@ -1028,7 +1031,7 @@ ngx_http_create_locations_list(ngx_queue_t *locations, ngx_queue_t *q)
         lx = (ngx_http_location_queue_t *) x;
 
         if (len > lx->name->len
-            || (ngx_strncmp(name, lx->name->data, len) != 0))
+            || ngx_filename_cmp(name, lx->name->data, len) != 0)
         {
             break;
         }
@@ -1346,11 +1349,13 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
         }
     }
 
-#if (NGX_HTTP_SPDY && NGX_HTTP_SSL && !defined TLSEXT_TYPE_next_proto_neg)
+#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 NPN support, "
-                           "SPDY is not enabled for %s", lsopt->addr);
+                           "nginx was built without OpenSSL ALPN or NPN "
+                           "support, SPDY is not enabled for %s", lsopt->addr);
     }
 #endif
 
@@ -1808,6 +1813,10 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
     ls->setfib = addr->opt.setfib;
 #endif
 
+#if (NGX_HAVE_TCP_FASTOPEN)
+    ls->fastopen = addr->opt.fastopen;
+#endif
+
     return ls;
 }
 
@@ -1840,6 +1849,7 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
 #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

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http.h (+2 -0) 98%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http.h    2014-07-02 11:31:57 +0900 (d4dc1bd)
+++ vendor/nginx-1.7.2/src/http/ngx_http.h    2014-07-04 15:15:55 +0900 (0acc234)
@@ -105,6 +105,8 @@ 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_parse_set_cookie_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,

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_busy_lock.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_busy_lock.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_cache.h (+4 -2) 96%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_cache.h    2014-07-02 11:31:57 +0900 (2a2d722)
+++ vendor/nginx-1.7.2/src/http/ngx_http_cache.h    2014-07-04 15:15:55 +0900 (193a353)
@@ -19,8 +19,9 @@
 #define NGX_HTTP_CACHE_EXPIRED       3
 #define NGX_HTTP_CACHE_STALE         4
 #define NGX_HTTP_CACHE_UPDATING      5
-#define NGX_HTTP_CACHE_HIT           6
-#define NGX_HTTP_CACHE_SCARCE        7
+#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
 
@@ -143,6 +144,7 @@ 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);

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_config.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_copy_filter_module.c (+4 -2) 97%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_copy_filter_module.c    2014-07-02 11:31:57 +0900 (95bc0b8)
+++ vendor/nginx-1.7.2/src/http/ngx_http_copy_filter_module.c    2014-07-04 15:15:55 +0900 (3ad27b0)
@@ -169,13 +169,15 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
             offset = c->busy_sendfile->file_pos;
 
             if (file->aio) {
-                c->aio_sendfile = (offset != file->aio->last_offset);
+                c->busy_count = (offset == file->aio->last_offset) ?
+                                c->busy_count + 1 : 0;
                 file->aio->last_offset = offset;
 
-                if (c->aio_sendfile == 0) {
+                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;
                 }
             }
 

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_core_module.c (+75 -69) 98%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_core_module.c    2014-07-02 11:31:57 +0900 (f2c3ade)
+++ vendor/nginx-1.7.2/src/http/ngx_http_core_module.c    2014-07-04 15:15:55 +0900 (fb02dd4)
@@ -1144,7 +1144,9 @@ ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
         }
 
         if (rc == NGX_HTTP_FORBIDDEN || rc == NGX_HTTP_UNAUTHORIZED) {
-            r->access_code = rc;
+            if (r->access_code != NGX_HTTP_UNAUTHORIZED) {
+                r->access_code = rc;
+            }
 
             r->phase_handler++;
             return NGX_AGAIN;
@@ -1243,10 +1245,8 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
         if (!alias) {
             reserve = len > r->uri.len ? len - r->uri.len : 0;
 
-#if (NGX_PCRE)
-        } else if (clcf->regex) {
+        } else if (alias == NGX_MAX_SIZE_T_VALUE) {
             reserve = len;
-#endif
 
         } else {
             reserve = len > r->uri.len - alias ? len - (r->uri.len - alias) : 0;
@@ -1363,13 +1363,12 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
         if (!alias) {
             r->uri = path;
 
-#if (NGX_PCRE)
-        } else if (clcf->regex) {
+        } else if (alias == NGX_MAX_SIZE_T_VALUE) {
             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);
@@ -1933,6 +1932,12 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
 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;
@@ -1998,16 +2003,12 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
 
     } else {
 
-#if (NGX_PCRE)
-        ngx_uint_t  captures;
-
-        captures = alias && clcf->regex;
+        if (alias == NGX_MAX_SIZE_T_VALUE) {
+            reserved += r->add_uri_to_alias ? r->uri.len + 1 : 1;
 
-        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
+        } else {
+            reserved += r->uri.len - alias + 1;
+        }
 
         if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved,
                                 clcf->root_values->elts)
@@ -2016,15 +2017,16 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
             return NULL;
         }
 
-        if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path, 0) != NGX_OK) {
+        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 (alias == NGX_MAX_SIZE_T_VALUE) {
             if (!r->add_uri_to_alias) {
                 *last = '\0';
                 return last;
@@ -2032,7 +2034,6 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
 
             alias = 0;
         }
-#endif
     }
 
     last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1);
@@ -2358,7 +2359,7 @@ equal:
 }
 
 
-ngx_uint_t
+static ngx_uint_t
 ngx_http_gzip_quantity(u_char *p, u_char *last)
 {
     u_char      c;
@@ -2622,6 +2623,14 @@ ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
         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) {
@@ -3031,9 +3040,12 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
 #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.addr,
+        (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) {
@@ -3211,9 +3223,9 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
 
 #if (NGX_PCRE)
         if (clcf->regex == NULL
-            && ngx_strncmp(clcf->name.data, pclcf->name.data, len) != 0)
+            && ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
 #else
-        if (ngx_strncmp(clcf->name.data, pclcf->name.data, len) != 0)
+        if (ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
 #endif
         {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -3411,25 +3423,16 @@ ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
 {
     ngx_http_core_main_conf_t *cmcf = conf;
 
-    if (cmcf->server_names_hash_max_size == NGX_CONF_UNSET_UINT) {
-        cmcf->server_names_hash_max_size = 512;
-    }
-
-    if (cmcf->server_names_hash_bucket_size == NGX_CONF_UNSET_UINT) {
-        cmcf->server_names_hash_bucket_size = ngx_cacheline_size;
-    }
+    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);
 
 
-    if (cmcf->variables_hash_max_size == NGX_CONF_UNSET_UINT) {
-        cmcf->variables_hash_max_size = 512;
-    }
-
-    if (cmcf->variables_hash_bucket_size == NGX_CONF_UNSET_UINT) {
-        cmcf->variables_hash_bucket_size = 64;
-    }
+    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);
@@ -3698,8 +3701,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
                               prev->types_hash_max_size, 1024);
 
     ngx_conf_merge_uint_value(conf->types_hash_bucket_size,
-                              prev->types_hash_bucket_size,
-                              ngx_cacheline_size);
+                              prev->types_hash_bucket_size, 64);
 
     conf->types_hash_bucket_size = ngx_align(conf->types_hash_bucket_size,
                                              ngx_cacheline_size);
@@ -3979,12 +3981,15 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 #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.addr,
+    (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.socklen, lsopt.addr,
                          NGX_SOCKADDR_STRLEN, 1);
 
     for (n = 2; n < cf->args->nelts; n++) {
@@ -4005,6 +4010,8 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 #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,
@@ -4015,6 +4022,23 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
             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;
@@ -4244,6 +4268,11 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 #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;
@@ -4438,6 +4467,7 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
 #if (NGX_PCRE)
     if (alias && clcf->regex) {
+        clcf->alias = NGX_MAX_SIZE_T_VALUE;
         n = 1;
     }
 #endif
@@ -4469,7 +4499,7 @@ static ngx_http_method_name_t  ngx_methods_names[] = {
    { (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 *) "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 },
@@ -4759,7 +4789,8 @@ ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         tf[i].name = value[i + 1];
 
         if (tf[i].name.len > 0
-            && tf[i].name.data[tf[i].name.len - 1] == '/')
+            && tf[i].name.data[tf[i].name.len - 1] == '/'
+            && i + 2 < cf->args->nelts)
         {
             tf[i].test_dir = 1;
             tf[i].name.len--;
@@ -4890,32 +4921,7 @@ ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
     ngx_http_core_loc_conf_t *clcf = conf;
 
-    ngx_str_t  *value, name;
-
-    if (clcf->error_log) {
-        return "is duplicate";
-    }
-
-    value = cf->args->elts;
-
-    if (ngx_strcmp(value[1].data, "stderr") == 0) {
-        ngx_str_null(&name);
-
-    } else {
-        name = value[1];
-    }
-
-    clcf->error_log = ngx_log_create(cf->cycle, &name);
-    if (clcf->error_log == NULL) {
-        return NGX_CONF_ERROR;
-    }
-
-    if (cf->args->nelts == 2) {
-        clcf->error_log->log_level = NGX_LOG_ERR;
-        return NGX_CONF_OK;
-    }
-
-    return ngx_log_set_levels(cf, clcf->error_log);
+    return ngx_log_set_log(cf, &clcf->error_log);
 }
 
 

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_core_module.h (+5 -0) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_core_module.h    2014-07-02 11:31:57 +0900 (5b38000)
+++ vendor/nginx-1.7.2/src/http/ngx_http_core_module.h    2014-07-04 15:15:55 +0900 (799d2fe)
@@ -82,6 +82,7 @@ typedef struct {
     unsigned                   ipv6only:1;
 #endif
     unsigned                   so_keepalive:2;
+    unsigned                   proxy_protocol:1;
 
     int                        backlog;
     int                        rcvbuf;
@@ -89,6 +90,9 @@ typedef struct {
 #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;
@@ -240,6 +244,7 @@ struct ngx_http_addr_conf_s {
 #if (NGX_HTTP_SPDY)
     unsigned                   spdy:1;
 #endif
+    unsigned                   proxy_protocol:1;
 };
 
 

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_file_cache.c (+120 -3) 92%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_file_cache.c    2014-07-02 11:31:57 +0900 (6d94c50)
+++ vendor/nginx-1.7.2/src/http/ngx_http_file_cache.c    2014-07-04 15:15:55 +0900 (49abdb4)
@@ -53,6 +53,7 @@ ngx_str_t  ngx_http_cache_status[] = {
     ngx_string("EXPIRED"),
     ngx_string("STALE"),
     ngx_string("UPDATING"),
+    ngx_string("REVALIDATED"),
     ngx_string("HIT")
 };
 
@@ -445,8 +446,7 @@ ngx_http_file_cache_lock_wait_handler(ngx_event_t *ev)
     timer = c->wait_time - ngx_current_msec;
 
     if ((ngx_msec_int_t) timer <= 0) {
-        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
-                       "http file cache lock timeout");
+        ngx_log_error(NGX_LOG_INFO, ev->log, 0, "cache lock timeout");
         c->lock = 0;
         goto wakeup;
     }
@@ -504,7 +504,7 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
         return NGX_DECLINED;
     }
 
-    if (h->body_start > c->body_start) {
+    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);
@@ -875,6 +875,8 @@ ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
 
     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;
@@ -970,6 +972,116 @@ 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)
+{
+    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)
 {
@@ -1201,6 +1313,11 @@ ngx_http_file_cache_expire(ngx_http_file_cache_t *cache)
 
     for ( ;; ) {
 
+        if (ngx_quit || ngx_terminate) {
+            wait = 1;
+            break;
+        }
+
         if (ngx_queue_empty(&cache->sh->queue)) {
             wait = 10;
             break;

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_header_filter_module.c (+9 -6) 98%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_header_filter_module.c    2014-07-02 11:31:57 +0900 (707a813)
+++ vendor/nginx-1.7.2/src/http/ngx_http_header_filter_module.c    2014-07-04 15:15:55 +0900 (507dc93)
@@ -92,10 +92,7 @@ static ngx_str_t ngx_http_status_lines[] = {
     ngx_string("411 Length Required"),
     ngx_string("412 Precondition Failed"),
     ngx_string("413 Request Entity Too Large"),
-    ngx_null_string,  /* "414 Request-URI Too Large", but we never send it
-                       * because we treat such requests as the HTTP/0.9
-                       * requests and send only a body without a header
-                       */
+    ngx_string("414 Request-URI Too Large"),
     ngx_string("415 Unsupported Media Type"),
     ngx_string("416 Requested Range Not Satisfiable"),
 
@@ -267,7 +264,13 @@ ngx_http_header_filter(ngx_http_request_t *r)
             len += ngx_http_status_lines[status].len;
 
         } else {
-            len += NGX_INT_T_LEN;
+            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;
         }
     }
@@ -448,7 +451,7 @@ ngx_http_header_filter(ngx_http_request_t *r)
         b->last = ngx_copy(b->last, status_line->data, status_line->len);
 
     } else {
-        b->last = ngx_sprintf(b->last, "%03ui", status);
+        b->last = ngx_sprintf(b->last, "%03ui ", status);
     }
     *b->last++ = CR; *b->last++ = LF;
 

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_parse.c (+139 -10) 94%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_parse.c    2014-07-02 11:31:57 +0900 (f8d5910)
+++ vendor/nginx-1.7.2/src/http/ngx_http_parse.c    2014-07-04 15:15:55 +0900 (f287869)
@@ -212,14 +212,17 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
                 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;
@@ -883,6 +886,19 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
                     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;
                 }
@@ -1258,8 +1274,8 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
          * the line feed
          */
 
-        ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "s:%d in:'%Xd:%c', out:'%c'", state, ch, ch, *u);
+        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "s:%d in:'%Xd:%c'", state, ch, ch);
 
         switch (state) {
 
@@ -1777,17 +1793,21 @@ ngx_int_t
 ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
     ngx_str_t *args, ngx_uint_t *flags)
 {
-    u_char  ch, *p;
-    size_t  len;
+    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 == 3 && p[1] == '.' && (ngx_path_separator(p[2]))) {
+    if (p[0] == '.' && len > 1 && p[1] == '.'
+        && (len == 2 || ngx_path_separator(p[2])))
+    {
         goto unsafe;
     }
 
@@ -1795,6 +1815,11 @@ ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
 
         ch = *p++;
 
+        if (ch == '%') {
+            quoted = 1;
+            continue;
+        }
+
         if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
             continue;
         }
@@ -1804,7 +1829,7 @@ ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
             args->data = p;
             uri->len -= len;
 
-            return NGX_OK;
+            break;
         }
 
         if (ch == '\0') {
@@ -1813,11 +1838,63 @@ ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
 
         if (ngx_path_separator(ch) && len > 2) {
 
-            /* detect "/../" */
+            /* 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] == '.' && p[1] == '.' && ngx_path_separator(p[2])) {
+        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;
+                }
+            }
         }
     }
 
@@ -1908,6 +1985,57 @@ ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name,
 
 
 ngx_int_t
+ngx_http_parse_set_cookie_lines(ngx_array_t *headers, ngx_str_t *name,
+    ngx_str_t *value)
+{
+    ngx_uint_t         i;
+    u_char            *start, *last, *end;
+    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;
+
+        if (ngx_strncasecmp(start, name->data, name->len) != 0) {
+            continue;
+        }
+
+        for (start += name->len; start < end && *start == ' '; start++) {
+            /* void */
+        }
+
+        if (start == end || *start++ != '=') {
+            /* the invalid header value */
+            continue;
+        }
+
+        while (start < end && *start == ' ') { start++; }
+
+        for (last = start; last < end && *last != ';'; last++) {
+            /* void */
+        }
+
+        value->len = last - start;
+        value->data = start;
+
+        return i;
+    }
+
+    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;
@@ -2182,8 +2310,9 @@ data:
         ctx->length = 3 /* "0" LF LF */;
         break;
     case sw_chunk_size:
-        ctx->length = 2 /* LF LF */
-                      + (ctx->size ? ctx->size + 4 /* LF "0" LF LF */ : 0);
+        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:

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_parse_time.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_postpone_filter_module.c (+2 -4) 96%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_postpone_filter_module.c    2014-07-02 11:31:57 +0900 (85c4b84)
+++ vendor/nginx-1.7.2/src/http/ngx_http_postpone_filter_module.c    2014-07-04 15:15:55 +0900 (e893b83)
@@ -70,8 +70,7 @@ ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
 #if 0
         /* TODO: SSI may pass NULL */
         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
-                      "http postpone filter NULL inactive request",
-                      &r->uri, &r->args);
+                      "http postpone filter NULL inactive request");
 #endif
 
         return NGX_OK;
@@ -108,8 +107,7 @@ ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
 
         if (pr->out == NULL) {
             ngx_log_error(NGX_LOG_ALERT, c->log, 0,
-                          "http postpone filter NULL output",
-                          &r->uri, &r->args);
+                          "http postpone filter NULL output");
 
         } else {
             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_request.c (+116 -8) 96%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_request.c    2014-07-02 11:31:57 +0900 (1be2d46)
+++ vendor/nginx-1.7.2/src/http/ngx_http_request.c    2014-07-04 15:15:55 +0900 (4bf9d1f)
@@ -343,6 +343,11 @@ ngx_http_init_connection(ngx_connection_t *c)
     }
 #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 */
 
@@ -368,6 +373,7 @@ ngx_http_init_connection(ngx_connection_t *c)
 static void
 ngx_http_wait_request_handler(ngx_event_t *rev)
 {
+    u_char                    *p;
     size_t                     size;
     ssize_t                    n;
     ngx_buf_t                 *b;
@@ -458,6 +464,27 @@ ngx_http_wait_request_handler(ngx_event_t *rev)
 
     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);
@@ -557,6 +584,7 @@ ngx_http_create_request(ngx_connection_t *c)
     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;
@@ -588,7 +616,8 @@ ngx_http_create_request(ngx_connection_t *c)
 static void
 ngx_http_ssl_handshake(ngx_event_t *rev)
 {
-    u_char                    buf[1];
+    u_char                   *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1];
+    size_t                    size;
     ssize_t                   n;
     ngx_err_t                 err;
     ngx_int_t                 rc;
@@ -597,6 +626,7 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
     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");
@@ -612,7 +642,9 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
         return;
     }
 
-    n = recv(c->fd, (char *) buf, 1, MSG_PEEK);
+    size = hc->proxy_protocol ? sizeof(buf) : 1;
+
+    n = recv(c->fd, (char *) buf, size, MSG_PEEK);
 
     err = ngx_socket_errno;
 
@@ -639,12 +671,39 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
         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]);
 
-            hc = c->data;
             sscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
                                                 ngx_http_ssl_module);
 
@@ -704,13 +763,26 @@ ngx_http_ssl_handshake_handler(ngx_connection_t *c)
 
         c->ssl->no_wait_shutdown = 1;
 
-#if (NGX_HTTP_SPDY && defined TLSEXT_TYPE_next_proto_neg)
+#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);
@@ -1930,6 +2002,10 @@ ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host)
     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)
@@ -2670,6 +2746,33 @@ ngx_http_test_reading(ngx_http_request_t *r)
 
 #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) {
@@ -2710,7 +2813,7 @@ closed:
     ngx_log_error(NGX_LOG_INFO, c->log, err,
                   "client prematurely closed connection");
 
-    ngx_http_finalize_request(r, 0);
+    ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST);
 }
 
 
@@ -3143,8 +3246,8 @@ ngx_http_lingering_close_handler(ngx_event_t *rev)
         return;
     }
 
-    timer = (ngx_msec_t) (r->lingering_time - ngx_time());
-    if (timer <= 0) {
+    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;
     }
@@ -3319,10 +3422,15 @@ ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
         return;
     }
 
-    for (cln = r->cleanup; cln; cln = cln->next) {
+    cln = r->cleanup;
+    r->cleanup = NULL;
+
+    while (cln) {
         if (cln->handler) {
             cln->handler(cln->data);
         }
+
+        cln = cln->next;
     }
 
 #if (NGX_STAT_STUB)

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_request.h (+7 -2) 97%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_request.h    2014-07-02 11:31:57 +0900 (bd842df)
+++ vendor/nginx-1.7.2/src/http/ngx_http_request.h    2014-07-04 15:15:55 +0900 (0d3a799)
@@ -309,8 +309,9 @@ typedef struct {
     ngx_int_t                         nfree;
 
 #if (NGX_HTTP_SSL)
-    ngx_uint_t                        ssl;    /* unsigned  ssl:1; */
+    unsigned                          ssl:1;
 #endif
+    unsigned                          proxy_protocol:1;
 } ngx_http_connection_t;
 
 
@@ -420,6 +421,7 @@ struct ngx_http_request_s {
 #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;
@@ -509,7 +511,6 @@ struct ngx_http_request_s {
     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;
@@ -526,6 +527,7 @@ struct ngx_http_request_s {
     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;
@@ -584,6 +586,9 @@ 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;                                     \
     }

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_request_body.c (+7 -7) 98%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_request_body.c    2014-07-02 11:31:57 +0900 (e9cf3e9)
+++ vendor/nginx-1.7.2/src/http/ngx_http_request_body.c    2014-07-04 15:15:55 +0900 (bbf16fd)
@@ -43,7 +43,7 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
     r->main->count++;
 
 #if (NGX_HTTP_SPDY)
-    if (r->spdy_stream) {
+    if (r->spdy_stream && r == r->main) {
         rc = ngx_http_spdy_read_request_body(r, post_handler);
         goto done;
     }
@@ -582,9 +582,9 @@ ngx_http_discarded_request_body_handler(ngx_http_request_t *r)
     }
 
     if (r->lingering_time) {
-        timer = (ngx_msec_t) (r->lingering_time - ngx_time());
+        timer = (ngx_msec_t) r->lingering_time - (ngx_msec_t) ngx_time();
 
-        if (timer <= 0) {
+        if ((ngx_msec_int_t) timer <= 0) {
             r->discard_body = 0;
             r->lingering_close = 0;
             ngx_http_finalize_request(r, NGX_ERROR);
@@ -726,7 +726,7 @@ ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b)
                 size = b->last - b->pos;
 
                 if ((off_t) size > rb->chunked->size) {
-                    b->pos += rb->chunked->size;
+                    b->pos += (size_t) rb->chunked->size;
                     rb->chunked->size = 0;
 
                 } else {
@@ -765,7 +765,7 @@ ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b)
         size = b->last - b->pos;
 
         if ((off_t) size > r->headers_in.content_length_n) {
-            b->pos += r->headers_in.content_length_n;
+            b->pos += (size_t) r->headers_in.content_length_n;
             r->headers_in.content_length_n = 0;
 
         } else {
@@ -882,7 +882,7 @@ ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in)
             rb->rest -= size;
 
         } else {
-            cl->buf->pos += rb->rest;
+            cl->buf->pos += (size_t) rb->rest;
             rb->rest = 0;
             b->last = cl->buf->pos;
             b->last_buf = 1;
@@ -988,7 +988,7 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
                 size = cl->buf->last - cl->buf->pos;
 
                 if ((off_t) size > rb->chunked->size) {
-                    cl->buf->pos += rb->chunked->size;
+                    cl->buf->pos += (size_t) rb->chunked->size;
                     r->headers_in.content_length_n += rb->chunked->size;
                     rb->chunked->size = 0;
 

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_script.c (+6 -5) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_script.c    2014-07-02 11:31:57 +0900 (54d0195)
+++ vendor/nginx-1.7.2/src/http/ngx_http_script.c    2014-07-04 15:15:55 +0900 (02e2be3)
@@ -1327,16 +1327,17 @@ ngx_http_script_full_name_code(ngx_http_script_engine_t *e)
 {
     ngx_http_script_full_name_code_t  *code;
 
-    ngx_str_t  value;
+    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;
 
-    if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &value, code->conf_prefix)
-        != NGX_OK)
-    {
+    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;
@@ -1393,7 +1394,7 @@ ngx_http_script_if_code(ngx_http_script_engine_t *e)
 
     e->sp--;
 
-    if (e->sp->len && (e->sp->len !=1 || e->sp->data[0] != '0')) {
+    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);

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_script.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_spdy.c (+1146 -380) 58%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_spdy.c    2014-07-02 11:31:57 +0900 (99afbfc)
+++ vendor/nginx-1.7.2/src/http/ngx_http_spdy.c    2014-07-04 15:15:55 +0900 (810d8d8)
@@ -42,16 +42,19 @@
 
 #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) & 0xffffff00) == ngx_spdy_ctl_frame_head(0))
+    (((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) & 0x000000ff)
+#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
@@ -64,10 +67,21 @@
 #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;
@@ -81,20 +95,24 @@ 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_state_detect_settings(
-    ngx_http_spdy_connection_t *sc, u_char *pos, u_char *end);
+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_skip(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,
+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,
@@ -103,17 +121,20 @@ 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_noop(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_inflate_error(
+    ngx_http_spdy_connection_t *sc, int rc);
 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);
@@ -138,55 +159,220 @@ 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_url(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[] =
-    "options" "get" "head" "post" "put" "delete" "trace"
-    "accept" "accept-charset" "accept-encoding" "accept-language"
-    "authorization" "expect" "from" "host"
-    "if-modified-since" "if-match" "if-none-match" "if-range"
-    "if-unmodifiedsince" "max-forwards" "proxy-authorization"
-    "range" "referer" "te" "user-agent"
-    "100" "101" "200" "201" "202" "203" "204" "205" "206"
-    "300" "301" "302" "303" "304" "305" "306" "307"
-    "400" "401" "402" "403" "404" "405" "406" "407" "408" "409" "410"
-    "411" "412" "413" "414" "415" "416" "417"
-    "500" "501" "502" "503" "504" "505"
-    "accept-ranges" "age" "etag" "location" "proxy-authenticate" "public"
-    "retry-after" "server" "vary" "warning" "www-authenticate" "allow"
-    "content-base" "content-encoding" "cache-control" "connection" "date"
-    "trailer" "transfer-encoding" "upgrade" "via" "warning"
-    "content-language" "content-length" "content-location"
-    "content-md5" "content-range" "content-type" "etag" "expires"
-    "last-modified" "set-cookie"
-    "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday"
-    "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
-    "chunked" "text/html" "image/png" "image/jpg" "image/gif"
-    "application/xml" "application/xhtml" "text/plain" "public" "max-age"
-    "charset=iso-8859-1" "utf-8" "gzip" "deflate" "HTTP/1.1" "status"
-    "version" "url";
+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, 3, "url", ngx_http_spdy_parse_url },
+    { 0, 4, "host", ngx_http_spdy_parse_host },
+    { 0, 4, "path", ngx_http_spdy_parse_path },
     { 0, 7, "version", ngx_http_spdy_parse_version },
 };
 
@@ -209,8 +395,7 @@ ngx_http_spdy_init(ngx_event_t *rev)
     c = rev->data;
     hc = c->data;
 
-    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                   "init spdy request");
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "init spdy request");
 
     c->log->action = "processing SPDY";
 
@@ -233,7 +418,13 @@ ngx_http_spdy_init(ngx_event_t *rev)
     sc->connection = c;
     sc->http_connection = hc;
 
-    sc->handler = ngx_http_spdy_state_detect_settings;
+    sc->send_window = NGX_SPDY_CONNECTION_WINDOW;
+    sc->recv_window = NGX_SPDY_CONNECTION_WINDOW;
+
+    sc->init_window = NGX_SPDY_INIT_STREAM_WINDOW;
+
+    sc->handler = hc->proxy_protocol ? ngx_http_spdy_proxy_protocol
+                                     : ngx_http_spdy_state_head;
 
     sc->zstream_in.zalloc = ngx_http_spdy_zalloc;
     sc->zstream_in.zfree = ngx_http_spdy_zfree;
@@ -295,6 +486,24 @@ ngx_http_spdy_init(ngx_event_t *rev)
         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;
@@ -344,9 +553,9 @@ ngx_http_spdy_read_handler(ngx_event_t *rev)
             break;
         }
 
-        if (n == 0 && (sc->waiting || sc->processing)) {
+        if (n == 0 && (sc->incomplete || sc->processing)) {
             ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                          "client closed prematurely connection");
+                          "client prematurely closed connection");
         }
 
         if (n == 0 || n == NGX_ERROR) {
@@ -358,7 +567,7 @@ ngx_http_spdy_read_handler(ngx_event_t *rev)
         end += n;
 
         sc->buffer_used = 0;
-        sc->waiting = 0;
+        sc->incomplete = 0;
 
         do {
             p = sc->handler(sc, p, end);
@@ -376,6 +585,11 @@ ngx_http_spdy_read_handler(ngx_event_t *rev)
         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) {
@@ -393,8 +607,9 @@ 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, *s, *sn;
+    ngx_http_spdy_stream_t      *stream;
     ngx_http_spdy_connection_t  *sc;
 
     c = wev->data;
@@ -409,7 +624,7 @@ ngx_http_spdy_write_handler(ngx_event_t *wev)
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy write handler");
 
-    sc->blocked = 2;
+    sc->blocked = 1;
 
     rc = ngx_http_spdy_send_output_queue(sc);
 
@@ -418,24 +633,17 @@ ngx_http_spdy_write_handler(ngx_event_t *wev)
         return;
     }
 
-    stream = NULL;
+    while (!ngx_queue_empty(&sc->posted)) {
+        q = ngx_queue_head(&sc->posted);
 
-    for (s = sc->last_stream; s; s = sn) {
-         sn = s->next;
-         s->next = stream;
-         stream = s;
-    }
+        ngx_queue_remove(q);
 
-    sc->last_stream = NULL;
+        stream = ngx_queue_data(q, ngx_http_spdy_stream_t, queue);
 
-    sc->blocked = 1;
-
-    for ( /* void */ ; stream; stream = sn) {
-        sn = stream->next;
         stream->handled = 0;
 
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "spdy run stream %ui", stream->id);
+                       "run spdy stream %ui", stream->id);
 
         wev = stream->request->connection->write;
         wev->handler(wev);
@@ -484,9 +692,9 @@ ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc)
         out = frame;
 
         ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "spdy frame out: %p sid:%ui prio:%ui bl:%ui size:%uz",
+                       "spdy frame out: %p sid:%ui prio:%ui bl:%d len:%uz",
                        out, out->stream ? out->stream->id : 0, out->priority,
-                       out->blocked, out->size);
+                       out->blocked, out->length);
     }
 
     cl = c->send_chain(c, cl, 0);
@@ -517,7 +725,9 @@ ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc)
         }
     }
 
-    for ( /* void */ ; out; out = out->next) {
+    for ( /* void */ ; out; out = fn) {
+        fn = out->next;
+
         if (out->handler(sc, out) != NGX_OK) {
             out->blocked = 1;
             out->priority = NGX_SPDY_HIGHEST_PRIORITY;
@@ -525,9 +735,9 @@ ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc)
         }
 
         ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "spdy frame sent: %p sid:%ui bl:%ui size:%uz",
+                       "spdy frame sent: %p sid:%ui bl:%d len:%uz",
                        out, out->stream ? out->stream->id : 0,
-                       out->blocked, out->size);
+                       out->blocked, out->length);
     }
 
     frame = NULL;
@@ -567,7 +777,7 @@ ngx_http_spdy_handle_connection(ngx_http_spdy_connection_t *sc)
 
     sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
                                         ngx_http_spdy_module);
-    if (sc->waiting) {
+    if (sc->incomplete) {
         ngx_add_timer(c->read, sscf->recv_timeout);
         return;
     }
@@ -605,34 +815,23 @@ ngx_http_spdy_handle_connection(ngx_http_spdy_connection_t *sc)
 
 
 static u_char *
-ngx_http_spdy_state_detect_settings(ngx_http_spdy_connection_t *sc,
-    u_char *pos, u_char *end)
+ngx_http_spdy_proxy_protocol(ngx_http_spdy_connection_t *sc, u_char *pos,
+    u_char *end)
 {
-    if (end - pos < NGX_SPDY_FRAME_HEADER_SIZE) {
-        return ngx_http_spdy_state_save(sc, pos, end,
-                                        ngx_http_spdy_state_detect_settings);
-    }
-
-    /*
-     * Since this is the first frame in a buffer,
-     * then it is properly aligned
-     */
+    ngx_log_t  *log;
 
-    if (*(uint32_t *) pos == htonl(ngx_spdy_ctl_frame_head(NGX_SPDY_SETTINGS)))
-    {
-        sc->length = ngx_spdy_frame_length(htonl(((uint32_t *) pos)[1]));
+    log = sc->connection->log;
+    log->action = "reading PROXY protocol";
 
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
-                       "spdy SETTINGS frame received, size: %uz", sc->length);
+    pos = ngx_proxy_protocol_parse(sc->connection, pos, end);
 
-        pos += NGX_SPDY_FRAME_HEADER_SIZE;
+    log->action = "processing SPDY";
 
-        return ngx_http_spdy_state_settings(sc, pos, end);
+    if (pos == NULL) {
+        return ngx_http_spdy_state_protocol_error(sc);
     }
 
-    ngx_http_spdy_send_settings(sc);
-
-    return ngx_http_spdy_state_head(sc, pos, end);
+    return ngx_http_spdy_state_complete(sc, pos, end);
 }
 
 
@@ -640,7 +839,8 @@ static u_char *
 ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos,
     u_char *end)
 {
-    uint32_t  head, flen;
+    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,
@@ -659,26 +859,27 @@ ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos,
     pos += sizeof(uint32_t);
 
     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
-                   "spdy process frame head:%08Xd f:%ui l:%ui",
+                   "process spdy frame head:%08XD f:%Xd l:%uz",
                    head, sc->flags, sc->length);
 
     if (ngx_spdy_ctl_frame_check(head)) {
-        switch (ngx_spdy_ctl_frame_type(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:
+            ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
+                          "client sent unexpected SYN_REPLY frame");
             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_skip(sc, pos, end);
-
-        case NGX_SPDY_NOOP:
-            return ngx_http_spdy_state_noop(sc, pos, end);
+            return ngx_http_spdy_state_settings(sc, pos, end);
 
         case NGX_SPDY_PING:
             return ngx_http_spdy_state_ping(sc, pos, end);
@@ -687,9 +888,16 @@ ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos,
             return ngx_http_spdy_state_skip(sc, pos, end); /* TODO */
 
         case NGX_SPDY_HEADERS:
+            ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
+                          "client sent unexpected HEADERS frame");
             return ngx_http_spdy_state_protocol_error(sc);
 
-        default: /* TODO logging */
+        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);
         }
     }
@@ -699,10 +907,8 @@ ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos,
         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");
+    ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
+                  "client sent invalid frame");
 
     return ngx_http_spdy_state_protocol_error(sc);
 }
@@ -722,27 +928,51 @@ ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
     }
 
     if (sc->length <= NGX_SPDY_SYN_STREAM_SIZE) {
-        /* TODO logging */
+        ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
+                      "client sent SYN_STREAM frame with incorrect length %uz",
+                      sc->length);
+
         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] >> 6;
+    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);
 
+    if (sid % 2 == 0 || sid <= sc->last_sid) {
+        ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
+                      "client sent SYN_STREAM frame "
+                      "with invalid Stream-ID %ui", sid);
+
+        stream = ngx_http_spdy_get_stream_by_id(sc, sid);
+
+        if (stream) {
+            if (ngx_http_spdy_terminate_stream(sc, stream,
+                                               NGX_SPDY_PROTOCOL_ERROR)
+                != NGX_OK)
+            {
+                return ngx_http_spdy_state_internal_error(sc);
+            }
+        }
+
+        return ngx_http_spdy_state_protocol_error(sc);
+    }
+
+    sc->last_sid = sid;
+
     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 excessed %ui", sc->processing);
+                      "concurrent streams exceeded %ui", sc->processing);
 
         if (ngx_http_spdy_send_rst_stream(sc, sid, NGX_SPDY_REFUSED_STREAM,
                                           prio)
@@ -767,8 +997,6 @@ ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
 
     sc->stream = stream;
 
-    sc->last_sid = sid;
-
     return ngx_http_spdy_state_headers(sc, pos, end);
 }
 
@@ -781,7 +1009,6 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
     size_t               size;
     ngx_buf_t           *buf;
     ngx_int_t            rc;
-    ngx_uint_t           complete;
     ngx_http_request_t  *r;
 
     size = end - pos;
@@ -791,24 +1018,22 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
                                         ngx_http_spdy_state_headers);
     }
 
-    if (size >= sc->length) {
+    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);
+                   "process spdy header block %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);
@@ -816,11 +1041,21 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
     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);
+            if (z == Z_DATA_ERROR) {
+                ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                              "client sent SYN_STREAM frame with header "
+                              "block encoded using wrong dictionary: %ul",
+                              (u_long) sc->zstream_in.adler);
+
+                return ngx_http_spdy_state_protocol_error(sc);
+            }
+
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                          "inflateSetDictionary() failed: %d", z);
+
+            return ngx_http_spdy_state_internal_error(sc);
         }
 
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -831,10 +1066,7 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
     }
 
     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);
+        return ngx_http_spdy_state_inflate_error(sc, z);
     }
 
     ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -851,24 +1083,33 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
     if (r->headers_in.headers.part.elts == NULL) {
 
         if (buf->last - buf->pos < NGX_SPDY_NV_NUM_SIZE) {
+
+            if (sc->length == 0) {
+                ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                               "premature end of spdy header block");
+
+                return ngx_http_spdy_state_headers_error(sc, pos, end);
+            }
+
             return ngx_http_spdy_state_save(sc, pos, end,
                                             ngx_http_spdy_state_headers);
         }
 
-        sc->headers = ngx_spdy_frame_parse_uint16(buf->pos);
+        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 count: %ui", sc->headers);
+                       "spdy header block has %ui entries",
+                       sc->entries);
 
-        if (ngx_list_init(&r->headers_in.headers, r->pool, sc->headers + 3,
+        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);
+            return ngx_http_spdy_state_headers_skip(sc, pos, end);
         }
 
         if (ngx_array_init(&r->headers_in.cookies, r->pool, 2,
@@ -877,18 +1118,18 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
         {
             ngx_http_spdy_close_stream(sc->stream,
                                        NGX_HTTP_INTERNAL_SERVER_ERROR);
-            return ngx_http_spdy_state_headers_error(sc, pos, end);
+            return ngx_http_spdy_state_headers_skip(sc, pos, end);
         }
     }
 
-    while (sc->headers) {
+    while (sc->entries) {
 
         rc = ngx_http_spdy_parse_header(r);
 
         switch (rc) {
 
         case NGX_DONE:
-            sc->headers--;
+            sc->entries--;
 
         case NGX_OK:
             break;
@@ -900,30 +1141,31 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
                 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);
+                    return ngx_http_spdy_state_headers_skip(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);
+                    return ngx_http_spdy_state_headers_skip(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);
+                    return ngx_http_spdy_state_inflate_error(sc, z);
                 }
 
                 sc->length -= sc->zstream_in.next_in - pos;
@@ -934,33 +1176,22 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
                 continue;
             }
 
-            if (complete) {
-                /* TODO: improve error message */
+            if (sc->length == 0) {
                 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);
+                               "premature end of spdy header block");
+
+                return ngx_http_spdy_state_headers_error(sc, pos, end);
             }
 
             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");
-
+        case NGX_HTTP_PARSE_INVALID_HEADER:
             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+            return ngx_http_spdy_state_headers_skip(sc, pos, end);
 
+        default: /* NGX_ERROR */
             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 */
@@ -969,33 +1200,34 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
 
         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);
+                ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+                return ngx_http_spdy_state_headers_skip(sc, pos, end);
             }
 
-            if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) {
-                ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+            if (rc != NGX_ABORT) {
+                ngx_http_spdy_close_stream(sc->stream,
+                                           NGX_HTTP_INTERNAL_SERVER_ERROR);
             }
 
-            return ngx_http_spdy_state_headers_error(sc, pos, end);
+            return ngx_http_spdy_state_headers_skip(sc, pos, end);
         }
     }
 
-    if (buf->pos != buf->last) {
-        /* TODO: improve error message */
-        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "end %ui %p %p", complete, buf->pos, buf->last);
-        ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
-        return ngx_http_spdy_state_protocol_error(sc);
+    if (buf->pos != buf->last || sc->zstream_in.avail_in) {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "incorrect number of spdy header block entries");
+
+        return ngx_http_spdy_state_headers_error(sc, pos, end);
     }
 
-    if (!complete) {
+    if (sc->length) {
         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);
@@ -1003,18 +1235,6 @@ ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
 
 
 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)
 {
@@ -1033,6 +1253,9 @@ ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
                                         ngx_http_spdy_state_headers_skip);
     }
 
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy header block skip %uz of %uz", size, sc->length);
+
     sc->zstream_in.next_in = pos;
     sc->zstream_in.avail_in = (size < sc->length) ? size : sc->length;
 
@@ -1042,12 +1265,8 @@ ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
 
         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);
+            return ngx_http_spdy_state_inflate_error(sc, n);
         }
     }
 
@@ -1064,14 +1283,246 @@ ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
 
 
 static u_char *
+ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc, u_char *pos,
+    u_char *end)
+{
+    ngx_http_spdy_stream_t  *stream;
+
+    stream = sc->stream;
+
+    ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
+                  "client sent SYN_STREAM frame for stream %ui "
+                  "with invalid header block", stream->id);
+
+    if (ngx_http_spdy_send_rst_stream(sc, stream->id, NGX_SPDY_PROTOCOL_ERROR,
+                                      stream->priority)
+        != NGX_OK)
+    {
+        return ngx_http_spdy_state_internal_error(sc);
+    }
+
+    stream->out_closed = 1;
+
+    ngx_http_spdy_close_stream(stream, NGX_HTTP_BAD_REQUEST);
+
+    return ngx_http_spdy_state_headers_skip(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_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                           "unknown spdy stream");
+
+            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 "
+                          "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 "
+                          "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: "
+                      "received DATA frame length %uz, 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) {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                       "unknown spdy stream");
+
+        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: "
+                      "received DATA frame length %uz, 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_uint_t                 complete;
     ngx_temp_file_t           *tf;
     ngx_http_request_t        *r;
     ngx_http_spdy_stream_t    *stream;
@@ -1080,37 +1531,27 @@ ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc, u_char *pos,
 
     stream = sc->stream;
 
-    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
-                   "spdy DATA frame");
-
     if (stream == NULL) {
         return ngx_http_spdy_state_skip(sc, pos, end);
     }
 
-    if (stream->in_closed) {
-        /* TODO log */
-        return ngx_http_spdy_state_protocol_error(sc);
-    }
-
     if (stream->skip_data) {
 
         if (sc->flags & NGX_SPDY_FLAG_FIN) {
             stream->in_closed = 1;
         }
 
-        /* TODO log and accounting */
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                       "skipping spdy DATA frame, reason: %d",
+                       stream->skip_data);
+
         return ngx_http_spdy_state_skip(sc, pos, end);
     }
 
     size = end - pos;
 
-    if (size >= sc->length) {
+    if (size > sc->length) {
         size = sc->length;
-        complete = 1;
-
-    } else {
-        sc->length -= size;
-        complete = 0;
     }
 
     r = stream->request;
@@ -1132,7 +1573,10 @@ ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc, u_char *pos,
         if (r->headers_in.content_length_n != -1
             && r->headers_in.content_length_n < rb->rest)
         {
-            /* TODO logging */
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client intended to send body data "
+                          "larger than declared");
+
             stream->skip_data = NGX_SPDY_DATA_ERROR;
             goto error;
 
@@ -1143,15 +1587,16 @@ ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc, u_char *pos,
                 && 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);
+                              "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;
@@ -1180,15 +1625,28 @@ ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc, u_char *pos,
         r->request_length += size;
     }
 
-    if (!complete) {
+    if (sc->length) {
         return ngx_http_spdy_state_save(sc, pos, end,
-                                        ngx_http_spdy_state_data);
+                                        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: "
+                          "only %O out 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));
 
@@ -1199,11 +1657,8 @@ ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc, u_char *pos,
             rb->buf = NULL;
         }
 
-        if (r->headers_in.content_length_n < 0) {
-            r->headers_in.content_length_n = rb->rest;
-        }
-
         if (rb->post_handler) {
+            r->read_event_handler = ngx_http_block_reading;
             rb->post_handler(r);
         }
     }
@@ -1237,7 +1692,6 @@ ngx_http_spdy_state_rst_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
     ngx_uint_t               sid, status;
     ngx_event_t             *ev;
     ngx_connection_t        *fc;
-    ngx_http_request_t      *r;
     ngx_http_spdy_stream_t  *stream;
 
     if (end - pos < NGX_SPDY_RST_STREAM_SIZE) {
@@ -1246,7 +1700,10 @@ ngx_http_spdy_state_rst_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
     }
 
     if (sc->length != NGX_SPDY_RST_STREAM_SIZE) {
-        /* TODO logging */
+        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);
     }
 
@@ -1261,55 +1718,44 @@ ngx_http_spdy_state_rst_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
     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);
 
-    switch (status) {
+    if (stream == NULL) {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                       "unknown spdy stream");
 
-    case NGX_SPDY_PROTOCOL_ERROR:
-        /* TODO logging */
-        return ngx_http_spdy_state_protocol_error(sc);
+        return ngx_http_spdy_state_complete(sc, pos, end);
+    }
 
-    case NGX_SPDY_INVALID_STREAM:
-        /* TODO */
-        break;
+    stream->in_closed = 1;
+    stream->out_closed = 1;
 
-    case NGX_SPDY_REFUSED_STREAM:
-        /* TODO */
-        break;
+    fc = stream->request->connection;
+    fc->error = 1;
 
-    case NGX_SPDY_UNSUPPORTED_VERSION:
-        /* TODO logging */
-        return ngx_http_spdy_state_protocol_error(sc);
+    switch (status) {
 
     case NGX_SPDY_CANCEL:
-    case NGX_SPDY_INTERNAL_ERROR:
-        stream = ngx_http_spdy_get_stream_by_id(sc, sid);
-        if (stream == NULL) {
-            /* TODO false cancel */
-            break;
-        }
-
-        stream->in_closed = 1;
-        stream->out_closed = 1;
-
-        r = stream->request;
-
-        fc = r->connection;
-        fc->error = 1;
-
-        ev = fc->read;
-        ev->handler(ev);
-
+        ngx_log_error(NGX_LOG_INFO, fc->log, 0,
+                      "client canceled stream %ui", sid);
         break;
 
-    case NGX_SPDY_FLOW_CONTROL_ERROR:
-        /* TODO logging */
-        return ngx_http_spdy_state_protocol_error(sc);
+    case NGX_SPDY_INTERNAL_ERROR:
+        ngx_log_error(NGX_LOG_INFO, fc->log, 0,
+                      "client terminated stream %ui due to internal error",
+                      sid);
+        break;
 
     default:
-        /* TODO */
-        return ngx_http_spdy_state_protocol_error(sc);
+        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);
 }
 
@@ -1328,7 +1774,10 @@ ngx_http_spdy_state_ping(ngx_http_spdy_connection_t *sc, u_char *pos,
     }
 
     if (sc->length != NGX_SPDY_PING_SIZE) {
-        /* TODO logging */
+        ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
+                      "client sent PING frame with incorrect length %uz",
+                      sc->length);
+
         return ngx_http_spdy_state_protocol_error(sc);
     }
 
@@ -1368,6 +1817,9 @@ ngx_http_spdy_state_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
 
     size = end - pos;
 
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy frame skip %uz of %uz", size, sc->length);
+
     if (size < sc->length) {
         sc->length -= size;
         return ngx_http_spdy_state_save(sc, end, end,
@@ -1382,70 +1834,80 @@ static u_char *
 ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc, u_char *pos,
     u_char *end)
 {
-    ngx_uint_t                 v;
-    ngx_http_spdy_srv_conf_t  *sscf;
+    ngx_uint_t  fid, val;
 
-    if (sc->headers == 0) {
+    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->headers = ngx_spdy_frame_parse_uint32(pos);
+        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->headers * NGX_SPDY_SETTINGS_PAIR_SIZE) {
-            /* TODO logging */
+        if (sc->length < sc->entries * NGX_SPDY_SETTINGS_PAIR_SIZE) {
+            ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
+                          "client sent SETTINGS frame with incorrect "
+                          "length %uz or number of entries %ui",
+                          sc->length, sc->entries);
+
             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->headers);
+                       "spdy SETTINGS frame has %ui entries", sc->entries);
     }
 
-    while (sc->headers) {
+    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->headers--;
+        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;
 
-        if (pos[0] != NGX_SPDY_SETTINGS_MAX_STREAMS) {
-            pos += NGX_SPDY_SETTINGS_PAIR_SIZE;
-            sc->length -= NGX_SPDY_SETTINGS_PAIR_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;
         }
 
-        v = ngx_spdy_frame_parse_uint32(pos + NGX_SPDY_SETTINGS_IDF_SIZE);
-
-        sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
-                                            ngx_http_spdy_module);
+        switch (ngx_spdy_frame_id(fid)) {
 
-        if (v != sscf->concurrent_streams) {
-            ngx_http_spdy_send_settings(sc);
-        }
+        case NGX_SPDY_SETTINGS_INIT_WINDOW:
 
-        return ngx_http_spdy_state_skip(sc, pos, end);
-    }
+            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);
 
-    ngx_http_spdy_send_settings(sc);
+                return ngx_http_spdy_state_protocol_error(sc);
+            }
 
-    return ngx_http_spdy_state_complete(sc, pos, end);
-}
+            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;
 
-static u_char *
-ngx_http_spdy_state_noop(ngx_http_spdy_connection_t *sc, u_char *pos,
-    u_char *end)
-{
-    if (sc->length) {
-        /* TODO logging */
-        return ngx_http_spdy_state_protocol_error(sc);
+            continue;
+        }
     }
 
     return ngx_http_spdy_state_complete(sc, pos, end);
@@ -1456,7 +1918,20 @@ static u_char *
 ngx_http_spdy_state_complete(ngx_http_spdy_connection_t *sc, u_char *pos,
     u_char *end)
 {
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy frame complete pos:%p end:%p", pos, end);
+
+    if (pos > end) {
+        ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
+                      "receive buffer overrun");
+
+        ngx_debug_point();
+        return ngx_http_spdy_state_internal_error(sc);
+    }
+
     sc->handler = ngx_http_spdy_state_head;
+    sc->stream = NULL;
+
     return pos;
 }
 
@@ -1465,33 +1940,63 @@ 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)
 {
-#if 1
-    if (end - pos > NGX_SPDY_STATE_BUFFER_SIZE) {
+    size_t  size;
+
+    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy frame state save pos:%p end:%p handler:%p",
+                   pos, end, handler);
+
+    size = end - pos;
+
+    if (size > NGX_SPDY_STATE_BUFFER_SIZE) {
         ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
-                      "spdy state buffer overflow: "
-                      "%i bytes required", end - pos);
+                      "state buffer overflow: %uz bytes required", size);
+
+        ngx_debug_point();
         return ngx_http_spdy_state_internal_error(sc);
     }
-#endif
 
     ngx_memcpy(sc->buffer, pos, NGX_SPDY_STATE_BUFFER_SIZE);
 
-    sc->buffer_used = end - pos;
+    sc->buffer_used = size;
     sc->handler = handler;
-    sc->waiting = 1;
+    sc->incomplete = 1;
 
     return end;
 }
 
 
 static u_char *
+ngx_http_spdy_state_inflate_error(ngx_http_spdy_connection_t *sc, int rc)
+{
+    if (rc == Z_DATA_ERROR || rc == Z_STREAM_END) {
+        ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
+                      "client sent SYN_STREAM frame with "
+                      "corrupted header block, inflate() failed: %d", rc);
+
+        return ngx_http_spdy_state_protocol_error(sc);
+    }
+
+    ngx_log_error(NGX_LOG_ERR, sc->connection->log, 0,
+                  "inflate() failed: %d", rc);
+
+    return ngx_http_spdy_state_internal_error(sc);
+}
+
+
+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 */
+    if (sc->stream) {
+        sc->stream->out_closed = 1;
+        ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
+    }
+
     ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
+
     return NULL;
 }
 
@@ -1502,13 +2007,53 @@ 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 */
+    if (sc->stream) {
+        sc->stream->out_closed = 1;
+        ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
+    }
+
     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 send 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)
 {
@@ -1521,7 +2066,7 @@ ngx_http_spdy_send_rst_stream(ngx_http_spdy_connection_t *sc, ngx_uint_t sid,
     }
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
-                   "spdy write RST_STREAM sid:%ui st:%ui", sid, status);
+                   "spdy send RST_STREAM sid:%ui st:%ui", sid, status);
 
     frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_RST_STREAM_SIZE,
                                         priority);
@@ -1556,7 +2101,7 @@ ngx_http_spdy_send_goaway(ngx_http_spdy_connection_t *sc)
     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);
+                   "spdy send GOAWAY sid:%ui", sc->last_sid);
 
     frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_GOAWAY_SIZE,
                                         NGX_SPDY_HIGHEST_PRIORITY);
@@ -1587,29 +2132,26 @@ ngx_http_spdy_send_settings(ngx_http_spdy_connection_t *sc)
 {
     u_char                     *p;
     ngx_buf_t                  *buf;
-    ngx_pool_t                 *pool;
     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");
+                   "spdy send SETTINGS frame");
 
-    pool = sc->connection->pool;
-
-    frame = ngx_palloc(pool, sizeof(ngx_http_spdy_out_frame_t));
+    frame = ngx_palloc(sc->pool, sizeof(ngx_http_spdy_out_frame_t));
     if (frame == NULL) {
         return NGX_ERROR;
     }
 
-    cl = ngx_alloc_chain_link(pool);
+    cl = ngx_alloc_chain_link(sc->pool);
     if (cl == NULL) {
         return NGX_ERROR;
     }
 
-    buf = ngx_create_temp_buf(pool, NGX_SPDY_FRAME_HEADER_SIZE
-                                    + NGX_SPDY_SETTINGS_NUM_SIZE
-                                    + NGX_SPDY_SETTINGS_PAIR_SIZE);
+    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;
     }
@@ -1622,11 +2164,10 @@ ngx_http_spdy_send_settings(ngx_http_spdy_connection_t *sc)
     frame->first = cl;
     frame->last = cl;
     frame->handler = ngx_http_spdy_settings_frame_handler;
-#if (NGX_DEBUG)
     frame->stream = NULL;
-    frame->size = NGX_SPDY_FRAME_HEADER_SIZE
-                  + NGX_SPDY_SETTINGS_NUM_SIZE
-                  + NGX_SPDY_SETTINGS_PAIR_SIZE;
+#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;
@@ -1635,19 +2176,20 @@ ngx_http_spdy_send_settings(ngx_http_spdy_connection_t *sc)
 
     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
-                                              + NGX_SPDY_SETTINGS_PAIR_SIZE);
+                                           NGX_SPDY_SETTINGS_NUM_SIZE
+                                           + 2 * NGX_SPDY_SETTINGS_PAIR_SIZE);
 
-    p = ngx_spdy_frame_aligned_write_uint32(p, 1);
-    p = ngx_spdy_frame_aligned_write_uint32(p,
-                                            NGX_SPDY_SETTINGS_MAX_STREAMS << 24
-                                            | NGX_SPDY_SETTINGS_FLAG_PERSIST);
+    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);
@@ -1675,7 +2217,7 @@ ngx_http_spdy_settings_frame_handler(ngx_http_spdy_connection_t *sc,
 
 
 static ngx_http_spdy_out_frame_t *
-ngx_http_spdy_get_ctl_frame(ngx_http_spdy_connection_t *sc, size_t size,
+ngx_http_spdy_get_ctl_frame(ngx_http_spdy_connection_t *sc, size_t length,
     ngx_uint_t priority)
 {
     ngx_chain_t                *cl;
@@ -1684,7 +2226,7 @@ ngx_http_spdy_get_ctl_frame(ngx_http_spdy_connection_t *sc, size_t size,
     frame = sc->free_ctl_frames;
 
     if (frame) {
-        sc->free_ctl_frames = frame->free;
+        sc->free_ctl_frames = frame->next;
 
         cl = frame->first;
         cl->buf->pos = cl->buf->start;
@@ -1711,19 +2253,17 @@ ngx_http_spdy_get_ctl_frame(ngx_http_spdy_connection_t *sc, size_t size,
         frame->first = cl;
         frame->last = cl;
         frame->handler = ngx_http_spdy_ctl_frame_handler;
+        frame->stream = NULL;
     }
 
-    frame->free = NULL;
-
 #if (NGX_DEBUG)
-    if (size > NGX_SPDY_CTL_FRAME_BUFFER_SIZE - NGX_SPDY_FRAME_HEADER_SIZE) {
+    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: %z", size);
+                      "requested control frame is too large: %uz", length);
         return NULL;
     }
 
-    frame->stream = NULL;
-    frame->size = size;
+    frame->length = length;
 #endif
 
     frame->priority = priority;
@@ -1745,7 +2285,7 @@ ngx_http_spdy_ctl_frame_handler(ngx_http_spdy_connection_t *sc,
         return NGX_AGAIN;
     }
 
-    frame->free = sc->free_ctl_frames;
+    frame->next = sc->free_ctl_frames;
     sc->free_ctl_frames = frame;
 
     return NGX_OK;
@@ -1814,7 +2354,7 @@ ngx_http_spdy_create_stream(ngx_http_spdy_connection_t *sc, ngx_uint_t id,
 
     rev->data = fc;
     rev->ready = 1;
-    rev->handler = ngx_http_empty_handler;
+    rev->handler = ngx_http_spdy_close_stream_handler;
     rev->log = log;
 
     ngx_memcpy(wev, rev, sizeof(ngx_event_t));
@@ -1864,6 +2404,10 @@ ngx_http_spdy_create_stream(ngx_http_spdy_connection_t *sc, ngx_uint_t id,
     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);
@@ -1907,7 +2451,7 @@ static ngx_int_t
 ngx_http_spdy_parse_header(ngx_http_request_t *r)
 {
     u_char                     *p, *end, ch;
-    ngx_uint_t                  len, hash;
+    ngx_uint_t                  hash;
     ngx_http_core_srv_conf_t   *cscf;
 
     enum {
@@ -1930,16 +2474,17 @@ ngx_http_spdy_parse_header(ngx_http_request_t *r)
             return NGX_AGAIN;
         }
 
-        len = ngx_spdy_frame_parse_uint16(p);
+        r->lowcase_index = ngx_spdy_frame_parse_uint32(p);
 
-        if (!len) {
-            return NGX_HTTP_PARSE_INVALID_HEADER;
+        if (r->lowcase_index == 0) {
+            return NGX_ERROR;
         }
 
+        /* null-terminate the previous header value */
+        *p = '\0';
+
         p += NGX_SPDY_NV_NLEN_SIZE;
 
-        r->header_name_end = p + len;
-        r->lowcase_index = len;
         r->invalid_header = 0;
 
         state = sw_name;
@@ -1948,13 +2493,18 @@ ngx_http_spdy_parse_header(ngx_http_request_t *r)
 
     case sw_name:
 
-        if (r->header_name_end > end) {
+        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;
 
@@ -1977,11 +2527,15 @@ ngx_http_spdy_parse_header(ngx_http_request_t *r)
             case LF:
             case CR:
             case ':':
-                return NGX_HTTP_PARSE_INVALID_REQUEST;
+                ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                              "client sent invalid header name: \"%*s\"",
+                              r->lowcase_index, r->header_name_start);
+
+                return NGX_HTTP_PARSE_INVALID_HEADER;
             }
 
             if (ch >= 'A' && ch <= 'Z') {
-                return NGX_HTTP_PARSE_INVALID_HEADER;
+                return NGX_ERROR;
             }
 
             r->invalid_header = 1;
@@ -1999,30 +2553,26 @@ ngx_http_spdy_parse_header(ngx_http_request_t *r)
             break;
         }
 
-        len = ngx_spdy_frame_parse_uint16(p);
+        r->lowcase_index = ngx_spdy_frame_parse_uint32(p);
 
-        if (!len) {
-            return NGX_ERROR;
-        }
+        /* null-terminate header name */
+        *p = '\0';
 
         p += NGX_SPDY_NV_VLEN_SIZE;
 
-        r->header_end = p + len;
-
         state = sw_value;
 
         /* fall through */
 
     case sw_value:
 
-        if (r->header_end > end) {
+        if ((ngx_uint_t) (end - p) < r->lowcase_index) {
             break;
         }
 
         r->header_start = p;
 
-        for ( /* void */ ; p != r->header_end; p++) {
-
+        while (r->lowcase_index--) {
             ch = *p;
 
             if (ch == '\0') {
@@ -2031,18 +2581,29 @@ ngx_http_spdy_parse_header(ngx_http_request_t *r)
                     return NGX_ERROR;
                 }
 
-                r->header_size = p - r->header_start;
+                r->header_end = p;
                 r->header_in->pos = p + 1;
 
                 return NGX_OK;
             }
 
             if (ch == CR || ch == LF) {
+                ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                              "client sent header \"%*s\" with "
+                              "invalid value: \"%*s\\%c...\"",
+                              r->header_name_end - r->header_name_start,
+                              r->header_name_start,
+                              p - r->header_start,
+                              r->header_start,
+                              ch == CR ? 'r' : 'n');
+
                 return NGX_HTTP_PARSE_INVALID_HEADER;
             }
+
+            p++;
         }
 
-        r->header_size = p - r->header_start;
+        r->header_end = p;
         r->header_in->pos = p;
 
         r->state = 0;
@@ -2060,7 +2621,7 @@ 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)
 {
-    u_char                    *old, *new;
+    u_char                    *old, *new, *p;
     size_t                     rest;
     ngx_buf_t                 *buf;
     ngx_http_spdy_stream_t    *stream;
@@ -2076,12 +2637,30 @@ ngx_http_spdy_alloc_large_header_buffer(ngx_http_request_t *r)
     if (stream->header_buffers
         == (ngx_uint_t) cscf->large_client_header_buffers.num)
     {
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent too large request");
+
         return NGX_DECLINED;
     }
 
     rest = r->header_in->last - r->header_in->pos;
 
+    /*
+     * equality is prohibited since one more byte is needed
+     * for null-termination
+     */
     if (rest >= cscf->large_client_header_buffers.size) {
+        p = r->header_in->pos;
+
+        if (rest > NGX_MAX_ERROR_STR - 300) {
+            rest = NGX_MAX_ERROR_STR - 300;
+            p[rest++] = '.'; p[rest++] = '.'; p[rest++] = '.';
+        }
+
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent too long header name or value: \"%*s\"",
+                      rest, p);
+
         return NGX_DECLINED;
     }
 
@@ -2101,13 +2680,6 @@ ngx_http_spdy_alloc_large_header_buffer(ngx_http_request_t *r)
         buf->last = ngx_cpymem(new, old, rest);
     }
 
-    if (r->header_name_end > old) {
-        r->header_name_end = new + (r->header_name_end - old);
-
-    } else if (r->header_end > old) {
-        r->header_end = new + (r->header_end - old);
-    }
-
     r->header_in = buf;
 
     stream->header_buffers++;
@@ -2135,39 +2707,44 @@ ngx_http_spdy_handle_request_header(ngx_http_request_t *r)
             return NGX_OK;
         }
 
-    } else {
+    }
+
+    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->lowcase_index
-                || ngx_strncmp(sh->header, r->header_name_start,
-                               r->lowcase_index)
-                   != 0)
+                || 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);
         }
+
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent invalid header name: \":%*s\"",
+                      r->header_end - r->header_name_start,
+                      r->header_name_start);
+
+        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;
     }
 
     h->hash = r->header_hash;
 
-    h->key.len = r->lowcase_index;
+    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_size;
+    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 = h->key.data;
 
@@ -2176,7 +2753,7 @@ ngx_http_spdy_handle_request_header(ngx_http_request_t *r)
 
 
 void
-ngx_http_spdy_request_headers_init()
+ngx_http_spdy_request_headers_init(void)
 {
     ngx_uint_t                       i;
     ngx_http_spdy_request_header_t  *h;
@@ -2223,10 +2800,13 @@ ngx_http_spdy_parse_method(ngx_http_request_t *r)
     }, *test;
 
     if (r->method_name.len) {
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent duplicate :method header");
+
         return NGX_HTTP_PARSE_INVALID_HEADER;
     }
 
-    len = r->header_size;
+    len = r->header_end - r->header_start;
 
     r->method_name.len = len;
     r->method_name.data = r->header_start;
@@ -2260,8 +2840,10 @@ ngx_http_spdy_parse_method(ngx_http_request_t *r)
     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;
+                          "client sent invalid method: \"%V\"",
+                          &r->method_name);
+
+            return NGX_HTTP_PARSE_INVALID_HEADER;
         }
 
         p++;
@@ -2276,6 +2858,9 @@ static ngx_int_t
 ngx_http_spdy_parse_scheme(ngx_http_request_t *r)
 {
     if (r->schema_start) {
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent duplicate :schema header");
+
         return NGX_HTTP_PARSE_INVALID_HEADER;
     }
 
@@ -2287,9 +2872,45 @@ ngx_http_spdy_parse_scheme(ngx_http_request_t *r)
 
 
 static ngx_int_t
-ngx_http_spdy_parse_url(ngx_http_request_t *r)
+ngx_http_spdy_parse_host(ngx_http_request_t *r)
+{
+    ngx_table_elt_t  *h;
+
+    if (r->headers_in.host) {
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent duplicate :host header");
+
+        return NGX_HTTP_PARSE_INVALID_HEADER;
+    }
+
+    h = ngx_list_push(&r->headers_in.headers);
+    if (h == NULL) {
+        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) {
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent duplicate :path header");
+
         return NGX_HTTP_PARSE_INVALID_HEADER;
     }
 
@@ -2297,11 +2918,19 @@ ngx_http_spdy_parse_url(ngx_http_request_t *r)
     r->uri_end = r->header_end;
 
     if (ngx_http_parse_uri(r) != NGX_OK) {
-        return NGX_HTTP_PARSE_INVALID_REQUEST;
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent invalid URI: \"%*s\"",
+                      r->uri_end - r->uri_start, r->uri_start);
+
+        return NGX_HTTP_PARSE_INVALID_HEADER;
     }
 
     if (ngx_http_process_request_uri(r) != NGX_OK) {
-        return NGX_ERROR;
+        /*
+         * request has been finalized already
+         * in ngx_http_process_request_uri()
+         */
+        return NGX_ABORT;
     }
 
     return NGX_OK;
@@ -2314,19 +2943,22 @@ ngx_http_spdy_parse_version(ngx_http_request_t *r)
     u_char  *p, ch;
 
     if (r->http_protocol.len) {
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent duplicate :version header");
+
         return NGX_HTTP_PARSE_INVALID_HEADER;
     }
 
     p = r->header_start;
 
-    if (r->header_size < 8 || !(ngx_str5cmp(p, 'H', 'T', 'T', 'P', '/'))) {
-        return NGX_HTTP_PARSE_INVALID_REQUEST;
+    if (r->header_end - p < 8 || !(ngx_str5cmp(p, 'H', 'T', 'T', 'P', '/'))) {
+        goto invalid;
     }
 
     ch = *(p + 5);
 
     if (ch < '1' || ch > '9') {
-        return NGX_HTTP_PARSE_INVALID_REQUEST;
+        goto invalid;
     }
 
     r->http_major = ch - '0';
@@ -2335,21 +2967,25 @@ ngx_http_spdy_parse_version(ngx_http_request_t *r)
 
         ch = *p;
 
+        if (ch == '.') {
+            break;
+        }
+
         if (ch < '0' || ch > '9') {
-            return NGX_HTTP_PARSE_INVALID_REQUEST;
+            goto invalid;
         }
 
         r->http_major = r->http_major * 10 + ch - '0';
     }
 
     if (*p != '.') {
-        return NGX_HTTP_PARSE_INVALID_REQUEST;
+        goto invalid;
     }
 
     ch = *(p + 1);
 
     if (ch < '0' || ch > '9') {
-        return NGX_HTTP_PARSE_INVALID_REQUEST;
+        goto invalid;
     }
 
     r->http_minor = ch - '0';
@@ -2359,17 +2995,25 @@ ngx_http_spdy_parse_version(ngx_http_request_t *r)
         ch = *p;
 
         if (ch < '0' || ch > '9') {
-            return NGX_HTTP_PARSE_INVALID_REQUEST;
+            goto invalid;
         }
 
         r->http_minor = r->http_minor * 10 + ch - '0';
     }
 
-    r->http_protocol.len = r->header_size;
+    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;
+
+invalid:
+
+    ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                  "client sent invalid http version: \"%*s\"",
+                  r->header_end - r->header_start, r->header_start);
+
+    return NGX_HTTP_PARSE_INVALID_HEADER;
 }
 
 
@@ -2392,7 +3036,8 @@ ngx_http_spdy_construct_request_line(ngx_http_request_t *r)
 
     p = ngx_pnalloc(r->pool, r->request_line.len + 1);
     if (p == NULL) {
-        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        ngx_http_spdy_close_stream(r->spdy_stream,
+                                   NGX_HTTP_INTERNAL_SERVER_ERROR);
         return NGX_ERROR;
     }
 
@@ -2456,7 +3101,7 @@ ngx_http_spdy_run_request(ngx_http_request_t *r)
         }
 
         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "http header: \"%V: %V\"", &h[i].key, &h[i].value);
+                       "spdy http header: \"%V: %V\"", &h[i].key, &h[i].value);
     }
 
     r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
@@ -2465,6 +3110,16 @@ ngx_http_spdy_run_request(ngx_http_request_t *r)
         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);
 }
 
@@ -2597,10 +3252,55 @@ ngx_http_spdy_read_request_body(ngx_http_request_t *r,
 
     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)
 {
@@ -2612,9 +3312,16 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
 
     sc = stream->connection;
 
-    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
-                   "spdy close stream %ui, processing %ui",
-                   stream->id, sc->processing);
+    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,
@@ -2650,14 +3357,13 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
         index = &s->index;
     }
 
-    fc = stream->request->connection;
-
     ngx_http_free_request(stream->request, rc);
 
     ev = fc->read;
 
     if (ev->active || ev->disabled) {
-        ngx_del_event(ev, NGX_READ_EVENT, 0);
+        ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
+                      "fake read event was activated");
     }
 
     if (ev->timer_set) {
@@ -2671,7 +3377,8 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
     ev = fc->write;
 
     if (ev->active || ev->disabled) {
-        ngx_del_event(ev, NGX_WRITE_EVENT, 0);
+        ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
+                      "fake write event was activated");
     }
 
     if (ev->timer_set) {
@@ -2802,6 +3509,7 @@ ngx_http_spdy_finalize_connection(ngx_http_spdy_connection_t *sc,
 
     c->error = 1;
     c->read->handler = ngx_http_empty_handler;
+    c->write->handler = ngx_http_empty_handler;
 
     sc->last_out = NULL;
 
@@ -2816,15 +3524,18 @@ ngx_http_spdy_finalize_connection(ngx_http_spdy_connection_t *sc,
         stream = sc->streams_index[i];
 
         while (stream) {
-            r = stream->request;
+            stream->handled = 0;
 
+            r = stream->request;
             fc = r->connection;
+
             fc->error = 1;
 
-            if (stream->waiting) {
-                r->blocked -= stream->waiting;
-                stream->waiting = 0;
+            if (stream->queued) {
+                stream->queued = 0;
+
                 ev = fc->write;
+                ev->delayed = 0;
 
             } else {
                 ev = fc->read;
@@ -2847,6 +3558,61 @@ ngx_http_spdy_finalize_connection(ngx_http_spdy_connection_t *sc,
 }
 
 
+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)
 {

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_spdy.h (+59 -33) 69%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_spdy.h    2014-07-02 11:31:57 +0900 (4294e3d)
+++ vendor/nginx-1.7.2/src/http/ngx_http_spdy.h    2014-07-04 15:15:55 +0900 (df24495)
@@ -15,12 +15,10 @@
 #include <zlib.h>
 
 
-#define NGX_SPDY_VERSION              2
+#define NGX_SPDY_VERSION              3
 
-#ifdef TLSEXT_TYPE_next_proto_neg
-#define NGX_SPDY_NPN_ADVERTISE        "\x06spdy/2"
-#define NGX_SPDY_NPN_NEGOTIATED       "spdy/2"
-#endif
+#define NGX_SPDY_NPN_ADVERTISE        "\x08spdy/3.1"
+#define NGX_SPDY_NPN_NEGOTIATED       "spdy/3.1"
 
 #define NGX_SPDY_STATE_BUFFER_SIZE    16
 
@@ -30,32 +28,34 @@
 #define NGX_SPDY_SYN_REPLY            2
 #define NGX_SPDY_RST_STREAM           3
 #define NGX_SPDY_SETTINGS             4
-#define NGX_SPDY_NOOP                 5
 #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       6
+#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          4
-#define NGX_SPDY_NV_NUM_SIZE          2
-#define NGX_SPDY_NV_NLEN_SIZE         2
-#define NGX_SPDY_NV_VLEN_SIZE         2
+#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_IDF_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_IDF_SIZE + NGX_SPDY_SETTINGS_VAL_SIZE)
+    (NGX_SPDY_SETTINGS_FID_SIZE + NGX_SPDY_SETTINGS_VAL_SIZE)
 
 #define NGX_SPDY_HIGHEST_PRIORITY     0
-#define NGX_SPDY_LOWEST_PRIORITY      3
+#define NGX_SPDY_LOWEST_PRIORITY      7
 
 #define NGX_SPDY_FLAG_FIN             0x01
 #define NGX_SPDY_FLAG_UNIDIRECTIONAL  0x02
@@ -81,6 +81,12 @@ struct ngx_http_spdy_connection_s {
 
     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;
@@ -96,18 +102,19 @@ struct ngx_http_spdy_connection_s {
     ngx_http_spdy_stream_t         **streams_index;
 
     ngx_http_spdy_out_frame_t       *last_out;
-    ngx_http_spdy_stream_t          *last_stream;
+
+    ngx_queue_t                      posted;
 
     ngx_http_spdy_stream_t          *stream;
 
-    ngx_uint_t                       headers;
+    ngx_uint_t                       entries;
     size_t                           length;
     u_char                           flags;
 
     ngx_uint_t                       last_sid;
 
-    unsigned                         blocked:2;
-    unsigned                         waiting:1; /* FIXME better name */
+    unsigned                         blocked:1;
+    unsigned                         incomplete:1;
 };
 
 
@@ -116,15 +123,27 @@ struct ngx_http_spdy_stream_s {
     ngx_http_request_t              *request;
     ngx_http_spdy_connection_t      *connection;
     ngx_http_spdy_stream_t          *index;
-    ngx_http_spdy_stream_t          *next;
 
     ngx_uint_t                       header_buffers;
-    ngx_uint_t                       waiting;
+    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;
 
-    unsigned                         priority:2;
+    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;
@@ -138,10 +157,8 @@ struct ngx_http_spdy_out_frame_s {
     ngx_int_t                      (*handler)(ngx_http_spdy_connection_t *sc,
                                         ngx_http_spdy_out_frame_t *frame);
 
-    ngx_http_spdy_out_frame_t       *free;
-
     ngx_http_spdy_stream_t          *stream;
-    size_t                           size;
+    size_t                           length;
 
     ngx_uint_t                       priority;
     unsigned                         blocked:1;
@@ -157,6 +174,9 @@ ngx_http_spdy_queue_frame(ngx_http_spdy_connection_t *sc,
 
     for (out = &sc->last_out; *out; out = &(*out)->next)
     {
+        /*
+         * NB: higher values represent lower priorities.
+         */
         if (frame->priority >= (*out)->priority) {
             break;
         }
@@ -173,9 +193,9 @@ ngx_http_spdy_queue_blocked_frame(ngx_http_spdy_connection_t *sc,
 {
     ngx_http_spdy_out_frame_t  **out;
 
-    for (out = &sc->last_out; *out && !(*out)->blocked; out = &(*out)->next)
+    for (out = &sc->last_out; *out; out = &(*out)->next)
     {
-        if (frame->priority >= (*out)->priority) {
+        if ((*out)->blocked) {
             break;
         }
     }
@@ -186,7 +206,7 @@ ngx_http_spdy_queue_blocked_frame(ngx_http_spdy_connection_t *sc,
 
 
 void ngx_http_spdy_init(ngx_event_t *rev);
-void ngx_http_spdy_request_headers_init();
+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);
@@ -210,13 +230,16 @@ ngx_int_t ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc);
 #else
 
 #define ngx_spdy_frame_write_uint16(p, s)                                     \
-    ((p)[0] = (u_char) (s) >> 8, (p)[1] = (u_char) (s), (p) + sizeof(uint16_t))
+    ((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))
+    ((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
 
@@ -229,7 +252,10 @@ ngx_int_t ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc);
 
 #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_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_ */

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_spdy_filter_module.c (+383 -169) 65%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_spdy_filter_module.c    2014-07-02 11:31:57 +0900 (8fe46b2)
+++ vendor/nginx-1.7.2/src/http/ngx_http_spdy_filter_module.c    2014-07-04 15:15:55 +0900 (82405d9)
@@ -14,14 +14,12 @@
 #include <zlib.h>
 
 
-#define NGX_SPDY_WRITE_BUFFERED  NGX_HTTP_WRITE_BUFFERED
-
 #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_uint16
-#define ngx_http_spdy_nv_write_nlen  ngx_spdy_frame_write_uint16
-#define ngx_http_spdy_nv_write_vlen  ngx_spdy_frame_write_uint16
+#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)
@@ -29,12 +27,22 @@
 #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_uint_t flags,
-    ngx_chain_t *first, ngx_chain_t *last);
+    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);
@@ -82,7 +90,6 @@ ngx_module_t  ngx_http_spdy_filter_module = {
 
 
 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
@@ -159,10 +166,12 @@ ngx_http_spdy_header_filter(ngx_http_request_t *r)
     }
 
     len = NGX_SPDY_NV_NUM_SIZE
-          + ngx_http_spdy_nv_nsize("version")
+          + ngx_http_spdy_nv_nsize(":version")
           + ngx_http_spdy_nv_vsize("HTTP/1.1")
-          + ngx_http_spdy_nv_nsize("status")
-          + ngx_http_spdy_nv_vsize("418");
+          + 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);
 
@@ -300,12 +309,20 @@ ngx_http_spdy_header_filter(ngx_http_request_t *r)
 
     last = buf + NGX_SPDY_NV_NUM_SIZE;
 
-    last = ngx_http_spdy_nv_write_name(last, "version");
+    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");
-    last = ngx_spdy_frame_write_uint16(last, 3);
-    last = ngx_sprintf(last, "%03ui", r->headers_out.status);
+    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;
 
@@ -444,17 +461,6 @@ ngx_http_spdy_header_filter(ngx_http_request_t *r)
             continue;
         }
 
-        if ((header[i].key.len == 6
-             && ngx_strncasecmp(header[i].key.data,
-                                (u_char *) "status", 6) == 0)
-            || (header[i].key.len == 7
-                && ngx_strncasecmp(header[i].key.data,
-                                   (u_char *) "version", 7) == 0))
-        {
-            header[i].hash = 0;
-            continue;
-        }
-
         last = ngx_http_spdy_nv_write_nlen(last, header[i].key.len);
 
         ngx_strlow(last, header[i].key.data, header[i].key.len);
@@ -500,7 +506,7 @@ ngx_http_spdy_header_filter(ngx_http_request_t *r)
         count++;
     }
 
-    (void) ngx_spdy_frame_write_uint16(buf, count);
+    (void) ngx_http_spdy_nv_write_num(buf, count);
 
     stream = r->spdy_stream;
     sc = stream->connection;
@@ -527,8 +533,7 @@ ngx_http_spdy_header_filter(ngx_http_request_t *r)
     ngx_free(buf);
 
     if (rc != Z_OK) {
-        ngx_log_error(NGX_LOG_ALERT, c->log, 0,
-                      "spdy deflate() failed: %d", rc);
+        ngx_log_error(NGX_LOG_ALERT, c->log, 0, "deflate() failed: %d", rc);
         return NGX_ERROR;
     }
 
@@ -547,13 +552,14 @@ ngx_http_spdy_header_filter(ngx_http_request_t *r)
 
     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 - NGX_SPDY_FRAME_HEADER_SIZE);
+        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 - NGX_SPDY_FRAME_HEADER_SIZE);
+        p = ngx_spdy_frame_write_flags_and_len(p, 0, len);
     }
 
     (void) ngx_spdy_frame_write_sid(p, stream->id);
@@ -574,21 +580,18 @@ ngx_http_spdy_header_filter(ngx_http_request_t *r)
     frame->first = cl;
     frame->last = cl;
     frame->handler = ngx_http_spdy_syn_frame_handler;
-    frame->free = NULL;
     frame->stream = stream;
-    frame->size = len;
+    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: size:%uz",
-                   stream->id, frame, frame->size);
+                   "spdy:%ui create SYN_REPLY frame %p: len:%uz",
+                   stream->id, frame, frame->length);
 
     ngx_http_spdy_queue_blocked_frame(sc, frame);
 
-    r->blocked++;
-
     cln = ngx_http_cleanup_add(r, 0);
     if (cln == NULL) {
         return NGX_ERROR;
@@ -597,109 +600,240 @@ ngx_http_spdy_header_filter(ngx_http_request_t *r)
     cln->handler = ngx_http_spdy_filter_cleanup;
     cln->data = stream;
 
-    stream->waiting = 1;
+    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_int_t
-ngx_http_spdy_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
+static ngx_chain_t *
+ngx_http_spdy_send_chain(ngx_connection_t *fc, ngx_chain_t *in, off_t limit)
 {
-    off_t                       size;
-    ngx_buf_t                  *b;
-    ngx_chain_t                *cl, *ll, *out, **ln;
-    ngx_http_spdy_stream_t     *stream;
-    ngx_http_spdy_out_frame_t  *frame;
-
+    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 (stream == NULL) {
-        return ngx_http_next_body_filter(r, in);
+#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;
     }
 
-    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "spdy body filter \"%V?%V\"", &r->uri, &r->args);
+    if (in == NULL) {
 
-    if (in == NULL || r->header_only) {
+        if (stream->queued) {
+            fc->write->delayed = 1;
+        } else {
+            fc->buffered &= ~NGX_SPDY_BUFFERED;
+        }
 
-        if (stream->waiting) {
-            return NGX_AGAIN;
+        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;
         }
 
-        r->connection->buffered &= ~NGX_SPDY_WRITE_BUFFERED;
+        cl->buf = in->buf;
+        in->buf = cl->buf->shadow;
 
-        return NGX_OK;
+        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;
     }
 
-    size = 0;
-    ln = &out;
-    ll = in;
+#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 ( ;; ) {
-        b = ll->buf;
-#if 1
-        if (ngx_buf_size(b) == 0 && !ngx_buf_special(b)) {
-            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
-                          "zero size buf in spdy body filter "
-                          "t:%d r:%d f:%d %p %p-%p %p %O-%O",
-                          b->temporary,
-                          b->recycled,
-                          b->in_file,
-                          b->start,
-                          b->pos,
-                          b->last,
-                          b->file,
-                          b->file_pos,
-                          b->file_last);
-
-            ngx_debug_point();
-            return NGX_ERROR;
+        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);
         }
-#endif
-        cl = ngx_alloc_chain_link(r->pool);
-        if (cl == NULL) {
-            return NGX_ERROR;
+
+        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;
         }
 
-        size += ngx_buf_size(b);
-        cl->buf = b;
+        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;
+        }
 
-        *ln = cl;
-        ln = &cl->next;
+        limit -= frame_size;
 
-        if (ll->next == NULL) {
+        if (limit == 0) {
             break;
         }
 
-        ll = ll->next;
+        if (limit < (off_t) slcf->chunk_size) {
+            frame_size = (size_t) limit;
+        }
     }
 
-    if (size > NGX_SPDY_MAX_FRAME_SIZE) {
-        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
-                      "FIXME: chain too big in spdy filter: %O", size);
-        return NGX_ERROR;
+    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);
     }
 
-    frame = ngx_http_spdy_filter_get_data_frame(stream, (size_t) size,
-                                                b->last_buf, out, cl);
-    if (frame == NULL) {
-        return NGX_ERROR;
+    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;
     }
 
-    ngx_http_spdy_queue_frame(stream->connection, frame);
+    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));
 
-    stream->waiting++;
+    chunk->tag = (ngx_buf_tag_t) &ngx_http_spdy_filter_get_shadow;
+    chunk->shadow = buf;
 
-    r->main->blocked++;
+    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 ngx_http_spdy_filter_send(r->connection, stream);
+    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_uint_t fin, ngx_chain_t *first, ngx_chain_t *last)
+    size_t len, ngx_chain_t *first, ngx_chain_t *last)
 {
     u_char                     *p;
     ngx_buf_t                  *buf;
@@ -711,7 +845,7 @@ ngx_http_spdy_filter_get_data_frame(ngx_http_spdy_stream_t *stream,
     frame = stream->free_frames;
 
     if (frame) {
-        stream->free_frames = frame->free;
+        stream->free_frames = frame->next;
 
     } else {
         frame = ngx_palloc(stream->request->pool,
@@ -721,62 +855,60 @@ ngx_http_spdy_filter_get_data_frame(ngx_http_spdy_stream_t *stream,
         }
     }
 
+    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 fin:%ui",
-                   stream->id, frame, len, fin);
+                   "spdy:%ui create DATA frame %p: len:%uz flags:%ui",
+                   stream->id, frame, len, flags);
 
-    if (len || fin) {
+    cl = ngx_chain_get_free_buf(stream->request->pool,
+                                &stream->free_data_headers);
+    if (cl == NULL) {
+        return NULL;
+    }
 
-        flags = fin ? NGX_SPDY_FLAG_FIN : 0;
+    buf = cl->buf;
 
-        cl = ngx_chain_get_free_buf(stream->request->pool,
-                                    &stream->free_data_headers);
-        if (cl == NULL) {
-            return NULL;
-        }
+    if (buf->start) {
+        p = buf->start;
+        buf->pos = p;
 
-        buf = cl->buf;
+        p += NGX_SPDY_SID_SIZE;
 
-        if (buf->start) {
-            p = buf->start;
-            buf->pos = p;
+        (void) ngx_spdy_frame_write_flags_and_len(p, flags, len);
 
-            p += sizeof(uint32_t);
+    } else {
+        p = ngx_palloc(stream->request->pool, NGX_SPDY_FRAME_HEADER_SIZE);
+        if (p == NULL) {
+            return NULL;
+        }
 
-            (void) ngx_spdy_frame_write_flags_and_len(p, flags, len);
+        buf->pos = p;
+        buf->start = p;
 
-        } else {
-            p = ngx_palloc(stream->request->pool, NGX_SPDY_FRAME_HEADER_SIZE);
-            if (p == NULL) {
-                return NULL;
-            }
+        p = ngx_spdy_frame_write_sid(p, stream->id);
+        p = ngx_spdy_frame_write_flags_and_len(p, flags, len);
 
-            buf->pos = p;
-            buf->start = p;
+        buf->last = p;
+        buf->end = 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;
+    }
 
-            buf->tag = (ngx_buf_tag_t) &ngx_http_spdy_filter_module;
-            buf->memory = 1;
-        }
+    cl->next = first;
+    first = cl;
 
-        cl->next = first;
-        first = cl;
-    }
+    last->buf->flush = 1;
 
     frame->first = first;
     frame->last = last;
     frame->handler = ngx_http_spdy_data_frame_handler;
-    frame->free = NULL;
     frame->stream = stream;
-    frame->size = NGX_SPDY_FRAME_HEADER_SIZE + len;
+    frame->length = len;
     frame->priority = stream->priority;
     frame->blocked = 0;
-    frame->fin = fin;
+    frame->fin = last->buf->last_buf;
 
     return frame;
 }
@@ -785,23 +917,76 @@ ngx_http_spdy_filter_get_data_frame(ngx_http_spdy_stream_t *stream,
 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;
     }
 
-    if (stream->waiting) {
-        fc->buffered |= NGX_SPDY_WRITE_BUFFERED;
+    stream->blocked = 0;
+
+    if (stream->queued) {
+        fc->buffered |= NGX_SPDY_BUFFERED;
         fc->write->delayed = 1;
         return NGX_AGAIN;
     }
 
-    fc->buffered &= ~NGX_SPDY_WRITE_BUFFERED;
+    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)
@@ -834,6 +1019,7 @@ 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;
 
@@ -841,7 +1027,7 @@ ngx_http_spdy_data_frame_handler(ngx_http_spdy_connection_t *sc,
 
     cl = frame->first;
 
-    if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_spdy_filter_module) {
+    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,
@@ -864,6 +1050,18 @@ ngx_http_spdy_data_frame_handler(ngx_http_spdy_connection_t *sc,
     }
 
     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) {
@@ -880,7 +1078,13 @@ ngx_http_spdy_data_frame_handler(ngx_http_spdy_connection_t *sc,
 
         ln = cl->next;
 
-        ngx_free_chain(stream->request->pool, cl);
+        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;
@@ -912,17 +1116,16 @@ ngx_http_spdy_handle_frame(ngx_http_spdy_stream_t *stream,
 
     r = stream->request;
 
-    r->connection->sent += frame->size;
-    r->blocked--;
+    r->connection->sent += NGX_SPDY_FRAME_HEADER_SIZE + frame->length;
 
     if (frame->fin) {
         stream->out_closed = 1;
     }
 
-    frame->free = stream->free_frames;
+    frame->next = stream->free_frames;
     stream->free_frames = frame;
 
-    stream->waiting--;
+    stream->queued--;
 }
 
 
@@ -930,21 +1133,19 @@ static ngx_inline void
 ngx_http_spdy_handle_stream(ngx_http_spdy_connection_t *sc,
     ngx_http_spdy_stream_t *stream)
 {
-    ngx_connection_t  *fc;
-
-    fc = stream->request->connection;
-
-    fc->write->delayed = 0;
+    ngx_event_t  *wev;
 
-    if (stream->handled) {
+    if (stream->handled || stream->blocked || stream->exhausted) {
         return;
     }
 
-    if (sc->blocked == 2) {
-        stream->handled = 1;
+    wev = stream->request->connection->write;
+
+    if (!wev->timer_set) {
+        wev->delayed = 0;
 
-        stream->next = sc->last_stream;
-        sc->last_stream = stream;
+        stream->handled = 1;
+        ngx_queue_insert_tail(&sc->posted, &stream->queue);
     }
 }
 
@@ -954,16 +1155,22 @@ ngx_http_spdy_filter_cleanup(void *data)
 {
     ngx_http_spdy_stream_t *stream = data;
 
-    ngx_http_request_t         *r;
-    ngx_http_spdy_out_frame_t  *frame, **fn;
+    size_t                       delta;
+    ngx_http_spdy_out_frame_t   *frame, **fn;
+    ngx_http_spdy_connection_t  *sc;
 
-    if (stream->waiting == 0) {
-        return;
+    if (stream->handled) {
+        stream->handled = 0;
+        ngx_queue_remove(&stream->queue);
     }
 
-    r = stream->request;
+    if (stream->queued == 0) {
+        return;
+    }
 
-    fn = &stream->connection->last_out;
+    delta = 0;
+    sc = stream->connection;
+    fn = &sc->last_out;
 
     for ( ;; ) {
         frame = *fn;
@@ -973,16 +1180,26 @@ ngx_http_spdy_filter_cleanup(void *data)
         }
 
         if (frame->stream == stream && !frame->blocked) {
+            *fn = frame->next;
 
-            stream->waiting--;
-            r->blocked--;
+            delta += frame->length;
+
+            if (--stream->queued == 0) {
+                break;
+            }
 
-            *fn = frame->next;
             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;
 }
 
 
@@ -992,8 +1209,5 @@ 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;
 
-    ngx_http_next_body_filter = ngx_http_top_body_filter;
-    ngx_http_top_body_filter = ngx_http_spdy_body_filter;
-
     return NGX_OK;
 }

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_spdy_module.c (+65 -8) 83%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_spdy_module.c    2014-07-02 11:31:57 +0900 (7f02a18)
+++ vendor/nginx-1.7.2/src/http/ngx_http_spdy_module.c    2014-07-04 15:15:55 +0900 (5178a36)
@@ -22,16 +22,19 @@ 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 = {
@@ -44,6 +47,8 @@ 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[] = {
@@ -97,6 +102,13 @@ static ngx_command_t  ngx_http_spdy_commands[] = {
       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
 };
 
@@ -111,8 +123,8 @@ static ngx_http_module_t  ngx_http_spdy_module_ctx = {
     ngx_http_spdy_create_srv_conf,         /* create server configuration */
     ngx_http_spdy_merge_srv_conf,          /* merge server configuration */
 
-    NULL,                                  /* create location configuration */
-    NULL                                   /* merge location configuration */
+    ngx_http_spdy_create_loc_conf,         /* create location configuration */
+    ngx_http_spdy_merge_loc_conf           /* merge location configuration */
 };
 
 
@@ -168,11 +180,11 @@ ngx_http_spdy_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
 {
     if (r->spdy_stream) {
-        v->len = 1;
+        v->len = sizeof("3.1") - 1;
         v->valid = 1;
         v->no_cacheable = 0;
         v->not_found = 0;
-        v->data = (u_char *) "2";
+        v->data = (u_char *) "3.1";
 
         return NGX_OK;
     }
@@ -239,9 +251,7 @@ ngx_http_spdy_init_main_conf(ngx_conf_t *cf, void *conf)
 {
     ngx_http_spdy_main_conf_t *smcf = conf;
 
-    if (smcf->recv_buffer_size == NGX_CONF_UNSET_SIZE) {
-        smcf->recv_buffer_size = 256 * 1024;
-    }
+    ngx_conf_init_size_value(smcf->recv_buffer_size, 256 * 1024);
 
     return NGX_CONF_OK;
 }
@@ -296,6 +306,34 @@ 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)
+{
+    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)
 {
@@ -349,3 +387,22 @@ ngx_http_spdy_streams_index_mask(ngx_conf_t *cf, void *post, void *data)
 
     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;
+}

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_spdy_module.h (+5 -0) 89%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_spdy_module.h    2014-07-02 11:31:57 +0900 (97a7a13)
+++ vendor/nginx-1.7.2/src/http/ngx_http_spdy_module.h    2014-07-04 15:15:55 +0900 (5242322)
@@ -30,6 +30,11 @@ typedef struct {
 } 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;
 
 

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_special_response.c (+1 -1) 99%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_special_response.c    2014-07-02 11:31:57 +0900 (875c24d)
+++ vendor/nginx-1.7.2/src/http/ngx_http_special_response.c    2014-07-04 15:15:55 +0900 (5464005)
@@ -370,7 +370,7 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
     ngx_http_core_loc_conf_t  *clcf;
 
     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http special response: %d, \"%V?%V\"",
+                   "http special response: %i, \"%V?%V\"",
                    error, &r->uri, &r->args);
 
     r->err_status = error;

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_upstream.c (+476 -117) 89%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_upstream.c    2014-07-02 11:31:57 +0900 (d99d854)
+++ vendor/nginx-1.7.2/src/http/ngx_http_upstream.c    2014-07-04 15:15:55 +0900 (8b6d3f6)
@@ -17,6 +17,8 @@ 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);
@@ -154,6 +156,8 @@ static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf);
 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);
+static ngx_int_t ngx_http_upstream_ssl_name(ngx_http_request_t *r,
+    ngx_http_upstream_t *u, ngx_connection_t *c);
 #endif
 
 
@@ -212,7 +216,8 @@ ngx_http_upstream_header_t  ngx_http_upstream_headers_in[] = {
                  ngx_http_upstream_rewrite_refresh, 0, 0 },
 
     { ngx_string("Set-Cookie"),
-                 ngx_http_upstream_process_set_cookie, 0,
+                 ngx_http_upstream_process_set_cookie,
+                 offsetof(ngx_http_upstream_headers_in_t, cookies),
                  ngx_http_upstream_rewrite_set_cookie, 0, 1 },
 
     { ngx_string("Content-Disposition"),
@@ -358,6 +363,10 @@ static ngx_http_variable_t  ngx_http_upstream_vars[] = {
       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 }
@@ -369,6 +378,7 @@ static ngx_http_upstream_next_t  ngx_http_upstream_next_errors[] = {
     { 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 }
 };
@@ -577,6 +587,10 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
 
     } else {
 
+#if (NGX_HTTP_SSL)
+        u->ssl_name = u->resolved->host;
+#endif
+
         if (u->resolved->sockaddr) {
 
             if (ngx_http_upstream_create_round_robin_peer(r, u->resolved)
@@ -605,7 +619,7 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
             if (uscf->host.len == host->len
                 && ((uscf->port == 0 && u->resolved->no_port)
                      || uscf->port == u->resolved->port)
-                && ngx_memcmp(uscf->host.data, host->data, host->len) == 0)
+                && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0)
             {
                 goto found;
             }
@@ -637,7 +651,6 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
         }
 
         ctx->name = *host;
-        ctx->type = NGX_RESOLVE_A;
         ctx->handler = ngx_http_upstream_resolve_handler;
         ctx->data = r;
         ctx->timeout = clcf->resolver_timeout;
@@ -664,6 +677,10 @@ found:
         return;
     }
 
+#if (NGX_HTTP_SSL)
+    u->ssl_name = uscf->host;
+#endif
+
     if (uscf->peer.init(r, uscf) != NGX_OK) {
         ngx_http_upstream_finalize_request(r, u,
                                            NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -709,7 +726,7 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
         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 increased at least to %uz",
+                          "it should be increased to at least %uz",
                           &u->conf->module, u->conf->buffer_size,
                           ngx_align(r->cache->header_start + 256, 1024));
 
@@ -911,16 +928,18 @@ ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
 
 #if (NGX_DEBUG)
     {
-    in_addr_t   addr;
+    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 = ntohl(ur->addrs[i]);
+        addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen,
+                                 text, NGX_SOCKADDR_STRLEN, 0);
 
-        ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "name was resolved to %ud.%ud.%ud.%ud",
-                       (addr >> 24) & 0xff, (addr >> 16) & 0xff,
-                       (addr >> 8) & 0xff, addr & 0xff);
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "name was resolved to %V", &addr);
     }
     }
 #endif
@@ -1069,6 +1088,55 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
 
 #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;
@@ -1180,7 +1248,7 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
         return;
     }
 
-    /* rc == NGX_OK || rc == NGX_AGAIN */
+    /* rc == NGX_OK || rc == NGX_AGAIN || rc == NGX_DONE */
 
     c = u->peer.connection;
 
@@ -1281,6 +1349,11 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
 {
     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)
@@ -1293,6 +1366,14 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
     c->sendfile = 0;
     u->output.sendfile = 0;
 
+    if (u->conf->ssl_server_name || u->conf->ssl_verify) {
+        if (ngx_http_upstream_ssl_name(r, u, c) != NGX_OK) {
+            ngx_http_upstream_finalize_request(r, u,
+                                               NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
+        }
+    }
+
     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,
@@ -1317,6 +1398,7 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
 static void
 ngx_http_upstream_ssl_handshake(ngx_connection_t *c)
 {
+    long                  rc;
     ngx_http_request_t   *r;
     ngx_http_upstream_t  *u;
 
@@ -1325,6 +1407,24 @@ ngx_http_upstream_ssl_handshake(ngx_connection_t *c)
 
     if (c->ssl->handshaked) {
 
+        if (u->conf->ssl_verify) {
+            rc = SSL_get_verify_result(c->ssl->connection);
+
+            if (rc != X509_V_OK) {
+                ngx_log_error(NGX_LOG_ERR, c->log, 0,
+                              "upstream SSL certificate verify error: (%l:%s)",
+                              rc, X509_verify_cert_error_string(rc));
+                goto failed;
+            }
+
+            if (ngx_ssl_check_host(c, &u->ssl_name) != NGX_OK) {
+                ngx_log_error(NGX_LOG_ERR, c->log, 0,
+                              "upstream SSL certificate does not match \"%V\"",
+                              &u->ssl_name);
+                goto failed;
+            }
+        }
+
         if (u->conf->ssl_session_reuse) {
             u->peer.save_session(&u->peer, u->peer.data);
         }
@@ -1332,13 +1432,112 @@ ngx_http_upstream_ssl_handshake(ngx_connection_t *c)
         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;
     }
 
+failed:
+
+    c = r->connection;
+
     ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
 
+    ngx_http_run_posted_requests(c);
+}
+
+
+static ngx_int_t
+ngx_http_upstream_ssl_name(ngx_http_request_t *r, ngx_http_upstream_t *u,
+    ngx_connection_t *c)
+{
+    u_char     *p, *last;
+    ngx_str_t   name;
+
+    if (u->conf->ssl_name) {
+        if (ngx_http_complex_value(r, u->conf->ssl_name, &name) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
+    } else {
+        name = u->ssl_name;
+    }
+
+    if (name.len == 0) {
+        goto done;
+    }
+
+    /*
+     * ssl name here may contain port, notably if derived from $proxy_host
+     * or $http_host; we have to strip it
+     */
+
+    p = name.data;
+    last = name.data + name.len;
+
+    if (*p == '[') {
+        p = ngx_strlchr(p, last, ']');
+
+        if (p == NULL) {
+            p = name.data;
+        }
+    }
+
+    p = ngx_strlchr(p, last, ':');
+
+    if (p != NULL) {
+        name.len = p - name.data;
+    }
+
+    if (!u->conf->ssl_server_name) {
+        goto done;
+    }
+
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+
+    /* as per RFC 6066, literal IPv4 and IPv6 addresses are not permitted */
+
+    if (name.len == 0 || *name.data == '[') {
+        goto done;
+    }
+
+    if (ngx_inet_addr(name.data, name.len) != INADDR_NONE) {
+        goto done;
+    }
+
+    /*
+     * SSL_set_tlsext_host_name() needs a null-terminated string,
+     * hence we explicitly null-terminate name here
+     */
+
+    p = ngx_pnalloc(r->pool, name.len + 1);
+    if (p == NULL) {
+        return NGX_ERROR;
+    }
+
+    (void) ngx_cpystrn(p, name.data, name.len + 1);
+
+    name.data = p;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "upstream SSL server name: \"%s\"", name.data);
+
+    if (SSL_set_tlsext_host_name(c->ssl->connection, name.data) == 0) {
+        ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0,
+                      "SSL_set_tlsext_host_name(\"%s\") failed", name.data);
+        return NGX_ERROR;
+    }
+
+#endif
+
+done:
+
+    u->ssl_name = name;
+
+    return NGX_OK;
 }
 
 #endif
@@ -1471,22 +1670,10 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u)
 
     ngx_add_timer(c->read, u->conf->read_timeout);
 
-#if 1
     if (c->read->ready) {
-
-        /* post aio operation */
-
-        /*
-         * TODO comment
-         * although we can post aio operation just in the end
-         * of ngx_http_upstream_connect() CHECK IT !!!
-         * it's better to do here because we postpone header buffer allocation
-         */
-
         ngx_http_upstream_process_header(r, u);
         return;
     }
-#endif
 
     u->write_event_handler = ngx_http_upstream_dummy_handler;
 
@@ -1660,11 +1847,7 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
 
     /* rc == NGX_OK */
 
-    if (u->headers_in.status_n > NGX_HTTP_SPECIAL_RESPONSE) {
-
-        if (r->subrequest_in_memory) {
-            u->buffer.last = u->buffer.pos;
-        }
+    if (u->headers_in.status_n >= NGX_HTTP_SPECIAL_RESPONSE) {
 
         if (ngx_http_upstream_test_next(r, u) == NGX_OK) {
             return;
@@ -1693,15 +1876,14 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
     }
 
     if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) {
-        ngx_http_upstream_finalize_request(r, u,
-                                           NGX_HTTP_INTERNAL_SERVER_ERROR);
+        ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
         return;
     }
 
     n = u->buffer.last - u->buffer.pos;
 
     if (n) {
-        u->buffer.last -= n;
+        u->buffer.last = u->buffer.pos;
 
         u->state->response_length += n;
 
@@ -1709,11 +1891,11 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
             ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
             return;
         }
+    }
 
-        if (u->length == 0) {
-            ngx_http_upstream_finalize_request(r, u, 0);
-            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;
@@ -1762,6 +1944,56 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
 #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;
 }
 
@@ -1876,7 +2108,7 @@ ngx_http_upstream_test_connect(ngx_connection_t *c)
         if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
             == -1)
         {
-            err = ngx_errno;
+            err = ngx_socket_errno;
         }
 
         if (err) {
@@ -1893,7 +2125,7 @@ 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)
 {
-    ngx_str_t                      *uri, args;
+    ngx_str_t                       uri, args;
     ngx_uint_t                      i, flags;
     ngx_list_part_t                *part;
     ngx_table_elt_t                *h;
@@ -1934,11 +2166,11 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
             }
         }
 
-        uri = &u->headers_in.x_accel_redirect->value;
+        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) {
+        if (ngx_http_parse_unsafe_uri(r, &uri, &args, &flags) != NGX_OK) {
             ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
             return NGX_DONE;
         }
@@ -1947,7 +2179,7 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
             r->method = NGX_HTTP_GET;
         }
 
-        ngx_http_internal_redirect(r, uri, &args);
+        ngx_http_internal_redirect(r, &uri, &args);
         ngx_http_finalize_request(r, NGX_DONE);
         return NGX_DONE;
     }
@@ -2006,7 +2238,7 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
 
     r->headers_out.content_length_n = u->headers_in.content_length_n;
 
-    u->length = u->headers_in.content_length_n;
+    u->length = -1;
 
     return NGX_OK;
 }
@@ -2030,7 +2262,7 @@ ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
 
     if (rev->timedout) {
         ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
-        ngx_http_upstream_finalize_request(r, u, NGX_ETIMEDOUT);
+        ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT);
         return;
     }
 
@@ -2106,6 +2338,8 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
         return;
     }
 
+    u->header_sent = 1;
+
     if (u->upgrade) {
         ngx_http_upstream_upgrade(r, u);
         return;
@@ -2132,8 +2366,6 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
         }
     }
 
-    u->header_sent = 1;
-
     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;
@@ -2156,7 +2388,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
         r->limit_rate = 0;
 
         if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) {
-            ngx_http_upstream_finalize_request(r, u, 0);
+            ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
             return;
         }
 
@@ -2170,7 +2402,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
             {
                 ngx_connection_error(c, ngx_socket_errno,
                                      "setsockopt(TCP_NODELAY) failed");
-                ngx_http_upstream_finalize_request(r, u, 0);
+                ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
                 return;
             }
 
@@ -2185,7 +2417,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
             u->state->response_length += n;
 
             if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
-                ngx_http_upstream_finalize_request(r, u, 0);
+                ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
                 return;
             }
 
@@ -2196,7 +2428,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
             u->buffer.last = u->buffer.start;
 
             if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) {
-                ngx_http_upstream_finalize_request(r, u, 0);
+                ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
                 return;
             }
 
@@ -2220,7 +2452,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
     switch (ngx_http_test_predicates(r, u->conf->no_cache)) {
 
     case NGX_ERROR:
-        ngx_http_upstream_finalize_request(r, u, 0);
+        ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
         return;
 
     case NGX_DECLINED:
@@ -2236,7 +2468,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
             r->cache->file_cache = u->conf->cache->data;
 
             if (ngx_http_file_cache_create(r) != NGX_OK) {
-                ngx_http_upstream_finalize_request(r, u, 0);
+                ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
                 return;
             }
         }
@@ -2297,7 +2529,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
 
     p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
     if (p->temp_file == NULL) {
-        ngx_http_upstream_finalize_request(r, u, 0);
+        ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
         return;
     }
 
@@ -2320,7 +2552,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
 
     p->preread_bufs = ngx_alloc_chain_link(r->pool);
     if (p->preread_bufs == NULL) {
-        ngx_http_upstream_finalize_request(r, u, 0);
+        ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
         return;
     }
 
@@ -2334,7 +2566,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
 
         p->buf_to_file = ngx_calloc_buf(r->pool);
         if (p->buf_to_file == NULL) {
-            ngx_http_upstream_finalize_request(r, u, 0);
+            ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
             return;
         }
 
@@ -2382,7 +2614,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
     if (u->input_filter_init
         && u->input_filter_init(p->input_ctx) != NGX_OK)
     {
-        ngx_http_upstream_finalize_request(r, u, 0);
+        ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
         return;
     }
 
@@ -2424,7 +2656,7 @@ ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
             {
                 ngx_connection_error(c, ngx_socket_errno,
                                      "setsockopt(TCP_NODELAY) failed");
-                ngx_http_upstream_finalize_request(r, u, 0);
+                ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
                 return;
             }
 
@@ -2440,7 +2672,7 @@ ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
             {
                 ngx_connection_error(u->peer.connection, ngx_socket_errno,
                                      "setsockopt(TCP_NODELAY) failed");
-                ngx_http_upstream_finalize_request(r, u, 0);
+                ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
                 return;
             }
 
@@ -2449,7 +2681,7 @@ ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
     }
 
     if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) {
-        ngx_http_upstream_finalize_request(r, u, 0);
+        ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
         return;
     }
 
@@ -2524,7 +2756,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
 
     if (upstream->read->timedout || upstream->write->timedout) {
         ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
-        ngx_http_upstream_finalize_request(r, u, 0);
+        ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT);
         return;
     }
 
@@ -2547,7 +2779,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
         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, 0);
+                ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
                 return;
             }
 
@@ -2570,7 +2802,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
                 n = dst->send(dst, b->pos, size);
 
                 if (n == NGX_ERROR) {
-                    ngx_http_upstream_finalize_request(r, u, 0);
+                    ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
                     return;
                 }
 
@@ -2625,7 +2857,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
     if (ngx_handle_write_event(upstream->write, u->conf->send_lowat)
         != NGX_OK)
     {
-        ngx_http_upstream_finalize_request(r, u, 0);
+        ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
         return;
     }
 
@@ -2637,7 +2869,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
     }
 
     if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) {
-        ngx_http_upstream_finalize_request(r, u, 0);
+        ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
         return;
     }
 
@@ -2651,12 +2883,12 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
     if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
         != NGX_OK)
     {
-        ngx_http_upstream_finalize_request(r, u, 0);
+        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, 0);
+        ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
         return;
     }
 
@@ -2711,7 +2943,7 @@ ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r,
 
     if (c->read->timedout) {
         ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
-        ngx_http_upstream_finalize_request(r, u, 0);
+        ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT);
         return;
     }
 
@@ -2747,7 +2979,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
                 rc = ngx_http_output_filter(r, u->out_bufs);
 
                 if (rc == NGX_ERROR) {
-                    ngx_http_upstream_finalize_request(r, u, 0);
+                    ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
                     return;
                 }
 
@@ -2758,13 +2990,27 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
             if (u->busy_bufs == NULL) {
 
                 if (u->length == 0
-                    || upstream->read->eof
-                    || upstream->read->error)
+                    || (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;
             }
@@ -2784,7 +3030,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
                 u->state->response_length += n;
 
                 if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
-                    ngx_http_upstream_finalize_request(r, u, 0);
+                    ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
                     return;
                 }
             }
@@ -2803,7 +3049,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
         if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
             != NGX_OK)
         {
-            ngx_http_upstream_finalize_request(r, u, 0);
+            ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
             return;
         }
     }
@@ -2816,7 +3062,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
     }
 
     if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) {
-        ngx_http_upstream_finalize_request(r, u, 0);
+        ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
         return;
     }
 
@@ -2907,14 +3153,14 @@ ngx_http_upstream_process_downstream(ngx_http_request_t *r)
                 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, 0);
+                    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, 0);
+                ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
                 return;
             }
 
@@ -2932,14 +3178,14 @@ ngx_http_upstream_process_downstream(ngx_http_request_t *r)
                            "http downstream delayed");
 
             if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
-                ngx_http_upstream_finalize_request(r, u, 0);
+                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, 0);
+            ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
             return;
         }
     }
@@ -2967,7 +3213,7 @@ ngx_http_upstream_process_upstream(ngx_http_request_t *r,
 
     } else {
         if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) {
-            ngx_http_upstream_finalize_request(r, u, 0);
+            ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
             return;
         }
     }
@@ -2992,11 +3238,12 @@ ngx_http_upstream_process_request(ngx_http_request_t *r)
 
             if (p->upstream_eof || p->upstream_done) {
 
-                tf = u->pipe->temp_file;
+                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)))
+                        || u->headers_in.content_length_n == tf->offset))
                 {
                     ngx_http_upstream_store(r, u);
                     u->store = 0;
@@ -3009,15 +3256,16 @@ ngx_http_upstream_process_request(ngx_http_request_t *r)
         if (u->cacheable) {
 
             if (p->upstream_done) {
-                ngx_http_file_cache_update(r, u->pipe->temp_file);
+                ngx_http_file_cache_update(r, p->temp_file);
 
             } else if (p->upstream_eof) {
 
-                tf = u->pipe->temp_file;
+                tf = p->temp_file;
 
-                if (u->headers_in.content_length_n == -1
-                    || u->headers_in.content_length_n
-                       == tf->offset - (off_t) r->cache->body_start)
+                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);
 
@@ -3026,7 +3274,7 @@ ngx_http_upstream_process_request(ngx_http_request_t *r)
                 }
 
             } else if (p->upstream_error) {
-                ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
+                ngx_http_file_cache_free(r->cache, p->temp_file);
             }
         }
 
@@ -3035,10 +3283,20 @@ ngx_http_upstream_process_request(ngx_http_request_t *r)
         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 0
-            ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
-#endif
-            ngx_http_upstream_finalize_request(r, u, 0);
+
+            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;
         }
     }
@@ -3048,7 +3306,7 @@ ngx_http_upstream_process_request(ngx_http_request_t *r)
                        "http upstream downstream error");
 
         if (!u->cacheable && !u->store && u->peer.connection) {
-            ngx_http_upstream_finalize_request(r, u, 0);
+            ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
         }
     }
 }
@@ -3148,14 +3406,13 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http next upstream, %xi", ft_type);
 
-#if 0
-    ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
-#endif
-
     if (u->peer.sockaddr) {
 
-        if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) {
+        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;
         }
@@ -3187,6 +3444,10 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
             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;
@@ -3258,13 +3519,6 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
         u->peer.connection = NULL;
     }
 
-#if 0
-    if (u->conf->busy_lock && !u->busy_locked) {
-        ngx_http_upstream_busy_lock(p);
-        return;
-    }
-#endif
-
     ngx_http_upstream_connect(r, u);
 }
 
@@ -3285,6 +3539,7 @@ 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,
@@ -3391,11 +3646,10 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
 
 #endif
 
-    if (u->header_sent
-        && rc != NGX_HTTP_REQUEST_TIME_OUT
-        && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE))
+    if (r->subrequest_in_memory
+        && u->headers_in.status_n >= NGX_HTTP_SPECIAL_RESPONSE)
     {
-        rc = 0;
+        u->buffer.last = u->buffer.pos;
     }
 
     if (rc == NGX_DECLINED) {
@@ -3404,14 +3658,32 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
 
     r->connection->log->action = "sending to client";
 
-    if (rc == 0
-        && !r->header_only
-#if (NGX_HTTP_CACHE)
-        && !r->cached
-#endif
-       )
+    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);
@@ -3461,11 +3733,28 @@ 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;
+    ngx_array_t           *pa;
+    ngx_table_elt_t      **ph;
+    ngx_http_upstream_t   *u;
 
     u = r->upstream;
+    pa = &u->headers_in.cookies;
 
+    if (pa->elts == NULL) {
+        if (ngx_array_init(pa, r->pool, 1, 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)
     if (!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_SET_COOKIE)) {
         u->cacheable = 0;
     }
@@ -3513,7 +3802,7 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
         return NGX_OK;
     }
 
-    if (r->cache->valid_sec != 0) {
+    if (r->cache->valid_sec != 0 && u->headers_in.x_accel_expires != NULL) {
         return NGX_OK;
     }
 
@@ -4042,7 +4331,12 @@ ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
     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
@@ -4274,7 +4568,7 @@ ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
             ms = (ngx_msec_int_t)
                      (state[i].response_sec * 1000 + state[i].response_msec);
             ms = ngx_max(ms, 0);
-            p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000);
+            p = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000);
 
         } else {
             *p++ = '-';
@@ -4382,6 +4676,40 @@ ngx_http_upstream_header_variable(ngx_http_request_t *r,
 }
 
 
+ngx_int_t
+ngx_http_upstream_cookie_variable(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;
+
+    if (r->upstream == NULL) {
+        v->not_found = 1;
+        return NGX_OK;
+    }
+
+    s.len = name->len - (sizeof("upstream_cookie_") - 1);
+    s.data = name->data + sizeof("upstream_cookie_") - 1;
+
+    if (ngx_http_parse_set_cookie_lines(&r->upstream->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;
+}
+
+
 #if (NGX_HTTP_CACHE)
 
 ngx_int_t
@@ -4406,6 +4734,36 @@ ngx_http_upstream_cache_status(ngx_http_request_t *r,
     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
 
 
@@ -4615,7 +4973,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
             continue;
         }
 
-        if (ngx_strncmp(value[i].data, "backup", 6) == 0) {
+        if (ngx_strcmp(value[i].data, "backup") == 0) {
 
             if (!(uscf->flags & NGX_HTTP_UPSTREAM_BACKUP)) {
                 goto invalid;
@@ -4626,7 +4984,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
             continue;
         }
 
-        if (ngx_strncmp(value[i].data, "down", 4) == 0) {
+        if (ngx_strcmp(value[i].data, "down") == 0) {
 
             if (!(uscf->flags & NGX_HTTP_UPSTREAM_DOWN)) {
                 goto invalid;
@@ -4640,6 +4998,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         goto invalid;
     }
 
+    us->name = u.url;
     us->addrs = u.addrs;
     us->naddrs = u.naddrs;
     us->weight = weight;

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_upstream.h (+21 -5) 93%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_upstream.h    2014-07-02 11:31:57 +0900 (29ebf9b)
+++ vendor/nginx-1.7.2/src/http/ngx_http_upstream.h    2014-07-04 15:15:55 +0900 (3128cce)
@@ -24,10 +24,11 @@
 #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_404        0x00000100
-#define NGX_HTTP_UPSTREAM_FT_UPDATING        0x00000200
-#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK       0x00000400
-#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING     0x00000800
+#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
 
@@ -35,6 +36,7 @@
                                              |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
@@ -85,6 +87,7 @@ typedef struct {
 
 
 typedef struct {
+    ngx_str_t                        name;
     ngx_addr_t                      *addrs;
     ngx_uint_t                       naddrs;
     ngx_uint_t                       weight;
@@ -176,6 +179,8 @@ typedef struct {
     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;
@@ -191,6 +196,10 @@ typedef struct {
 #if (NGX_HTTP_SSL)
     ngx_ssl_t                       *ssl;
     ngx_flag_t                       ssl_session_reuse;
+
+    ngx_http_complex_value_t        *ssl_name;
+    ngx_flag_t                       ssl_server_name;
+    ngx_flag_t                       ssl_verify;
 #endif
 
     ngx_str_t                        module;
@@ -240,6 +249,7 @@ typedef struct {
     off_t                            content_length_n;
 
     ngx_array_t                      cache_control;
+    ngx_array_t                      cookies;
 
     unsigned                         connection_close:1;
     unsigned                         chunked:1;
@@ -252,7 +262,7 @@ typedef struct {
     ngx_uint_t                       no_port; /* unsigned no_port:1 */
 
     ngx_uint_t                       naddrs;
-    in_addr_t                       *addrs;
+    ngx_addr_t                      *addrs;
 
     struct sockaddr                 *sockaddr;
     socklen_t                        socklen;
@@ -319,6 +329,10 @@ struct ngx_http_upstream_s {
     ngx_str_t                        schema;
     ngx_str_t                        uri;
 
+#if (NGX_HTTP_SSL)
+    ngx_str_t                        ssl_name;
+#endif
+
     ngx_http_cleanup_pt             *cleanup;
 
     unsigned                         store:1;
@@ -351,6 +365,8 @@ typedef struct {
 } ngx_http_upstream_param_t;
 
 
+ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_upstream_round_robin.c (+90 -72) 81%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_upstream_round_robin.c    2014-07-02 11:31:57 +0900 (e0c6c58)
+++ vendor/nginx-1.7.2/src/http/ngx_http_upstream_round_robin.c    2014-07-04 15:15:55 +0900 (37c835c)
@@ -30,6 +30,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
     ngx_url_t                      u;
     ngx_uint_t                     i, j, n, w;
     ngx_http_upstream_server_t    *server;
+    ngx_http_upstream_rr_peer_t   *peer;
     ngx_http_upstream_rr_peers_t  *peers, *backup;
 
     us->peer.init = ngx_http_upstream_init_round_robin_peer;
@@ -69,22 +70,24 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
         peers->name = &us->host;
 
         n = 0;
+        peer = peers->peer;
 
         for (i = 0; i < us->servers->nelts; i++) {
+            if (server[i].backup) {
+                continue;
+            }
+
             for (j = 0; j < server[i].naddrs; j++) {
-                if (server[i].backup) {
-                    continue;
-                }
-
-                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].max_fails = server[i].max_fails;
-                peers->peer[n].fail_timeout = server[i].fail_timeout;
-                peers->peer[n].down = server[i].down;
-                peers->peer[n].weight = server[i].weight;
-                peers->peer[n].effective_weight = server[i].weight;
-                peers->peer[n].current_weight = 0;
+                peer[n].sockaddr = server[i].addrs[j].sockaddr;
+                peer[n].socklen = server[i].addrs[j].socklen;
+                peer[n].name = server[i].addrs[j].name;
+                peer[n].weight = server[i].weight;
+                peer[n].effective_weight = server[i].weight;
+                peer[n].current_weight = 0;
+                peer[n].max_fails = server[i].max_fails;
+                peer[n].fail_timeout = server[i].fail_timeout;
+                peer[n].down = server[i].down;
+                peer[n].server = server[i].name;
                 n++;
             }
         }
@@ -123,22 +126,24 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
         backup->name = &us->host;
 
         n = 0;
+        peer = backup->peer;
 
         for (i = 0; i < us->servers->nelts; i++) {
+            if (!server[i].backup) {
+                continue;
+            }
+
             for (j = 0; j < server[i].naddrs; j++) {
-                if (!server[i].backup) {
-                    continue;
-                }
-
-                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;
+                peer[n].sockaddr = server[i].addrs[j].sockaddr;
+                peer[n].socklen = server[i].addrs[j].socklen;
+                peer[n].name = server[i].addrs[j].name;
+                peer[n].weight = server[i].weight;
+                peer[n].effective_weight = server[i].weight;
+                peer[n].current_weight = 0;
+                peer[n].max_fails = server[i].max_fails;
+                peer[n].fail_timeout = server[i].fail_timeout;
+                peer[n].down = server[i].down;
+                peer[n].server = server[i].name;
                 n++;
             }
         }
@@ -187,15 +192,17 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
     peers->total_weight = n;
     peers->name = &us->host;
 
+    peer = peers->peer;
+
     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;
+        peer[i].sockaddr = u.addrs[i].sockaddr;
+        peer[i].socklen = u.addrs[i].socklen;
+        peer[i].name = u.addrs[i].name;
+        peer[i].weight = 1;
+        peer[i].effective_weight = 1;
+        peer[i].current_weight = 0;
+        peer[i].max_fails = 1;
+        peer[i].fail_timeout = 10;
     }
 
     us->peer.data = peers;
@@ -266,8 +273,10 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
 {
     u_char                            *p;
     size_t                             len;
+    socklen_t                          socklen;
     ngx_uint_t                         i, n;
-    struct sockaddr_in                *sin;
+    struct sockaddr                   *sockaddr;
+    ngx_http_upstream_rr_peer_t       *peer;
     ngx_http_upstream_rr_peers_t      *peers;
     ngx_http_upstream_rr_peer_data_t  *rrp;
 
@@ -292,48 +301,57 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
     peers->number = ur->naddrs;
     peers->name = &ur->host;
 
+    peer = peers->peer;
+
     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;
+        peer[0].sockaddr = ur->sockaddr;
+        peer[0].socklen = ur->socklen;
+        peer[0].name = ur->host;
+        peer[0].weight = 1;
+        peer[0].effective_weight = 1;
+        peer[0].current_weight = 0;
+        peer[0].max_fails = 1;
+        peer[0].fail_timeout = 10;
 
     } else {
 
         for (i = 0; i < ur->naddrs; i++) {
 
-            len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;
+            socklen = ur->addrs[i].socklen;
 
-            p = ngx_pnalloc(r->pool, len);
-            if (p == NULL) {
+            sockaddr = ngx_palloc(r->pool, socklen);
+            if (sockaddr == NULL) {
                 return NGX_ERROR;
             }
 
-            len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN);
-            len = ngx_sprintf(&p[len], ":%d", ur->port) - p;
+            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);
+            }
 
-            sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in));
-            if (sin == NULL) {
+            p = ngx_pnalloc(r->pool, NGX_SOCKADDR_STRLEN);
+            if (p == NULL) {
                 return NGX_ERROR;
             }
 
-            sin->sin_family = AF_INET;
-            sin->sin_port = htons(ur->port);
-            sin->sin_addr.s_addr = ur->addrs[i];
-
-            peers->peer[i].sockaddr = (struct sockaddr *) sin;
-            peers->peer[i].socklen = sizeof(struct sockaddr_in);
-            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;
+            len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1);
+
+            peer[i].sockaddr = sockaddr;
+            peer[i].socklen = socklen;
+            peer[i].name.len = len;
+            peer[i].name.data = p;
+            peer[i].weight = 1;
+            peer[i].effective_weight = 1;
+            peer[i].current_weight = 0;
+            peer[i].max_fails = 1;
+            peer[i].fail_timeout = 10;
         }
     }
 
@@ -379,13 +397,15 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
     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];
+    peers = rrp->peers;
+
+    /* ngx_lock_mutex(peers->mutex); */
+
+    if (peers->single) {
+        peer = &peers->peer[0];
 
         if (peer->down) {
             goto failed;
@@ -410,18 +430,16 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
     pc->socklen = peer->socklen;
     pc->name = &peer->name;
 
-    /* ngx_unlock_mutex(rrp->peers->mutex); */
+    /* ngx_unlock_mutex(peers->mutex); */
 
-    if (pc->tries == 1 && rrp->peers->next) {
-        pc->tries += rrp->peers->next->number;
+    if (pc->tries == 1 && peers->next) {
+        pc->tries += peers->next->number;
     }
 
     return NGX_OK;
 
 failed:
 
-    peers = rrp->peers;
-
     if (peers->next) {
 
         /* ngx_unlock_mutex(peers->mutex); */

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_upstream_round_robin.h (+1 -0) 98%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_upstream_round_robin.h    2014-07-02 11:31:57 +0900 (ea90ab9)
+++ vendor/nginx-1.7.2/src/http/ngx_http_upstream_round_robin.h    2014-07-04 15:15:55 +0900 (9db82a6)
@@ -18,6 +18,7 @@ typedef struct {
     struct sockaddr                *sockaddr;
     socklen_t                       socklen;
     ngx_str_t                       name;
+    ngx_str_t                       server;
 
     ngx_int_t                       current_weight;
     ngx_int_t                       effective_weight;

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_variables.c (+78 -7) 96%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_variables.c    2014-07-02 11:31:57 +0900 (7a7d15c)
+++ vendor/nginx-1.7.2/src/http/ngx_http_variables.c    2014-07-04 15:15:55 +0900 (1b61c39)
@@ -13,8 +13,10 @@
 
 static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+#if 0
 static void ngx_http_variable_request_set(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+#endif
 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,
@@ -54,6 +56,8 @@ 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,
@@ -62,6 +66,8 @@ 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 void ngx_http_variable_set_args(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,
@@ -183,6 +189,9 @@ static ngx_http_variable_t  ngx_http_core_variables[] = {
 
     { 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 },
@@ -218,7 +227,7 @@ static ngx_http_variable_t  ngx_http_core_variables[] = {
       NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("args"),
-      ngx_http_variable_request_set,
+      ngx_http_variable_set_args,
       ngx_http_variable_request,
       offsetof(ngx_http_request_t, args),
       NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
@@ -487,7 +496,7 @@ ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index)
 
     if (cmcf->variables.nelts <= index) {
         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
-                      "unknown variable index: %d", index);
+                      "unknown variable index: %ui", index);
         return NULL;
     }
 
@@ -608,6 +617,17 @@ ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key)
         return NULL;
     }
 
+    if (ngx_strncmp(name->data, "upstream_cookie_", 16) == 0) {
+
+        if (ngx_http_upstream_cookie_variable(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) {
@@ -646,6 +666,8 @@ ngx_http_variable_request(ngx_http_request_t *r, ngx_http_variable_value_t *v,
 }
 
 
+#if 0
+
 static void
 ngx_http_variable_request_set(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
@@ -658,6 +680,8 @@ ngx_http_variable_request_set(ngx_http_request_t *r,
     s->data = v->data;
 }
 
+#endif
+
 
 static ngx_int_t
 ngx_http_variable_request_get_size(ngx_http_request_t *r,
@@ -1185,6 +1209,12 @@ ngx_http_variable_remote_port(ngx_http_request_t *r,
         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);
@@ -1200,6 +1230,20 @@ ngx_http_variable_remote_port(ngx_http_request_t *r,
 
 
 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)
 {
@@ -1263,6 +1307,12 @@ ngx_http_variable_server_port(ngx_http_request_t *r,
         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);
@@ -1329,6 +1379,16 @@ ngx_http_variable_https(ngx_http_request_t *r,
 }
 
 
+static void
+ngx_http_variable_set_args(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    r->args.len = v->len;
+    r->args.data = v->data;
+    r->valid_unparsed_uri = 0;
+}
+
+
 static ngx_int_t
 ngx_http_variable_is_args(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
@@ -1374,7 +1434,9 @@ ngx_http_variable_document_root(ngx_http_request_t *r,
             return NGX_ERROR;
         }
 
-        if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &path, 0) != NGX_OK) {
+        if (ngx_get_full_name(r->pool, (ngx_str_t *) &ngx_cycle->prefix, &path)
+            != NGX_OK)
+        {
             return NGX_ERROR;
         }
 
@@ -1416,7 +1478,9 @@ ngx_http_variable_realpath_root(ngx_http_request_t *r,
 
         path.data[path.len - 1] = '\0';
 
-        if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &path, 0) != NGX_OK) {
+        if (ngx_get_full_name(r->pool, (ngx_str_t *) &ngx_cycle->prefix, &path)
+            != NGX_OK)
+        {
             return NGX_ERROR;
         }
     }
@@ -1740,8 +1804,7 @@ ngx_http_variable_sent_last_modified(ngx_http_request_t *r,
     }
 
     if (r->headers_out.last_modified_time >= 0) {
-        p = ngx_pnalloc(r->pool,
-                   sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT") - 1);
+        p = ngx_pnalloc(r->pool, sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1);
         if (p == NULL) {
             return NGX_ERROR;
         }
@@ -2257,6 +2320,7 @@ ngx_http_regex_compile(ngx_conf_t *cf, ngx_regex_compile_t *rc)
 
     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);
@@ -2274,7 +2338,6 @@ ngx_http_regex_compile(ngx_conf_t *cf, ngx_regex_compile_t *rc)
 
     re->variables = rv;
     re->nvariables = n;
-    re->name = rc->pattern;
 
     size = rc->name_size;
     p = rc->names;
@@ -2494,6 +2557,14 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
             continue;
         }
 
+        if (ngx_strncmp(v[i].name.data, "upstream_cookie_", 16) == 0) {
+            v[i].get_handler = ngx_http_upstream_cookie_variable;
+            v[i].data = (uintptr_t) &v[i].name;
+            v[i].flags = NGX_HTTP_VAR_NOCACHEABLE;
+
+            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;

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_variables.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/http/ngx_http_write_filter_module.c (+12 -5) 95%
===================================================================
--- vendor/nginx-1.4.7/src/http/ngx_http_write_filter_module.c    2014-07-02 11:31:57 +0900 (5594c7f)
+++ vendor/nginx-1.7.2/src/http/ngx_http_write_filter_module.c    2014-07-04 15:15:55 +0900 (83cb1fa)
@@ -184,7 +184,10 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
         return NGX_AGAIN;
     }
 
-    if (size == 0 && !(c->buffered & NGX_LOWLEVEL_BUFFERED)) {
+    if (size == 0
+        && !(c->buffered & NGX_LOWLEVEL_BUFFERED)
+        && !(last && c->need_last_buf))
+    {
         if (last || flush) {
             for (cl = r->out; cl; /* void */) {
                 ln = cl;
@@ -207,8 +210,12 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
     }
 
     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 - clcf->limit_rate_after);
+                - (c->sent - r->limit_rate_after);
 
         if (limit <= 0) {
             c->write->delayed = 1;
@@ -249,14 +256,14 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
 
         nsent = c->sent;
 
-        if (clcf->limit_rate_after) {
+        if (r->limit_rate_after) {
 
-            sent -= clcf->limit_rate_after;
+            sent -= r->limit_rate_after;
             if (sent < 0) {
                 sent = 0;
             }
 
-            nsent -= clcf->limit_rate_after;
+            nsent -= r->limit_rate_after;
             if (nsent < 0) {
                 nsent = 0;
             }

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail.c (+4 -2) 98%
===================================================================
--- vendor/nginx-1.4.7/src/mail/ngx_mail.c    2014-07-02 11:31:57 +0900 (3812e15)
+++ vendor/nginx-1.7.2/src/mail/ngx_mail.c    2014-07-04 15:15:55 +0900 (350d2cd)
@@ -465,7 +465,8 @@ ngx_mail_add_addrs(ngx_conf_t *cf, ngx_mail_port_t *mport,
         addrs[i].conf.ssl = addr[i].ssl;
 #endif
 
-        len = ngx_sock_ntop(addr[i].sockaddr, buf, NGX_SOCKADDR_STRLEN, 1);
+        len = ngx_sock_ntop(addr[i].sockaddr, addr[i].socklen, buf,
+                            NGX_SOCKADDR_STRLEN, 1);
 
         p = ngx_pnalloc(cf->pool, len);
         if (p == NULL) {
@@ -513,7 +514,8 @@ ngx_mail_add_addrs6(ngx_conf_t *cf, ngx_mail_port_t *mport,
         addrs6[i].conf.ssl = addr[i].ssl;
 #endif
 
-        len = ngx_sock_ntop(addr[i].sockaddr, buf, NGX_SOCKADDR_STRLEN, 1);
+        len = ngx_sock_ntop(addr[i].sockaddr, addr[i].socklen, buf,
+                            NGX_SOCKADDR_STRLEN, 1);
 
         p = ngx_pnalloc(cf->pool, len);
         if (p == NULL) {

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail.h (+2 -0) 99%
===================================================================
--- vendor/nginx-1.4.7/src/mail/ngx_mail.h    2014-07-02 11:31:57 +0900 (ccdfb8c)
+++ vendor/nginx-1.7.2/src/mail/ngx_mail.h    2014-07-04 15:15:55 +0900 (dc39f1e)
@@ -234,6 +234,8 @@ typedef struct {
     ngx_str_t               smtp_from;
     ngx_str_t               smtp_to;
 
+    ngx_str_t               cmd;
+
     ngx_uint_t              command;
     ngx_array_t             args;
 

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_auth_http_module.c (+1 -2) 99%
===================================================================
--- vendor/nginx-1.4.7/src/mail/ngx_mail_auth_http_module.c    2014-07-02 11:31:57 +0900 (2e9b9f2)
+++ vendor/nginx-1.7.2/src/mail/ngx_mail_auth_http_module.c    2014-07-04 15:15:55 +0900 (eb7531c)
@@ -699,7 +699,6 @@ ngx_mail_auth_http_process_headers(ngx_mail_session_t *s,
 
                     p = ngx_pnalloc(s->connection->pool, ctx->err.len);
                     if (p == NULL) {
-                        ngx_close_connection(ctx->peer.connection);
                         ngx_destroy_pool(ctx->pool);
                         ngx_mail_session_internal_server_error(s);
                         return;
@@ -1270,7 +1269,7 @@ ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
     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);
+                   "mail auth http header:%N\"%V\"", &l);
     }
 #endif
 

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_core_module.c (+2 -1) 99%
===================================================================
--- vendor/nginx-1.4.7/src/mail/ngx_mail_core_module.c    2014-07-02 11:31:57 +0900 (be8673c)
+++ vendor/nginx-1.7.2/src/mail/ngx_mail_core_module.c    2014-07-04 15:15:55 +0900 (4ee7c8d)
@@ -439,7 +439,8 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                 ls->bind = 1;
 
             } else {
-                len = ngx_sock_ntop(sa, buf, NGX_SOCKADDR_STRLEN, 1);
+                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 "

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_handler.c (+22 -5) 96%
===================================================================
--- vendor/nginx-1.4.7/src/mail/ngx_mail_handler.c    2014-07-02 11:31:57 +0900 (ae955f9)
+++ vendor/nginx-1.7.2/src/mail/ngx_mail_handler.c    2014-07-04 15:15:55 +0900 (784111f)
@@ -22,6 +22,7 @@ static void ngx_mail_ssl_handshake_handler(ngx_connection_t *c);
 void
 ngx_mail_init_connection(ngx_connection_t *c)
 {
+    size_t                 len;
     ngx_uint_t             i;
     ngx_mail_port_t       *port;
     struct sockaddr       *sa;
@@ -30,6 +31,7 @@ ngx_mail_init_connection(ngx_connection_t *c)
     ngx_mail_in_addr_t    *addr;
     ngx_mail_session_t    *s;
     ngx_mail_addr_conf_t  *addr_conf;
+    u_char                 text[NGX_SOCKADDR_STRLEN];
 #if (NGX_HAVE_INET6)
     struct sockaddr_in6   *sin6;
     ngx_mail_in6_addr_t   *addr6;
@@ -127,8 +129,10 @@ ngx_mail_init_connection(ngx_connection_t *c)
     c->data = s;
     s->connection = c;
 
-    ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%ui client %V connected to %V",
-                  c->number, &c->addr_text, s->addr_text);
+    len = ngx_sock_ntop(c->sockaddr, c->socklen, text, NGX_SOCKADDR_STRLEN, 1);
+
+    ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%uA client %*s connected to %V",
+                  c->number, len, text, s->addr_text);
 
     ctx = ngx_palloc(c->pool, sizeof(ngx_mail_log_ctx_t));
     if (ctx == NULL) {
@@ -559,8 +563,13 @@ ngx_mail_send(ngx_event_t *wev)
     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);
         }
@@ -584,6 +593,8 @@ ngx_mail_send(ngx_event_t *wev)
 
     /* n == NGX_AGAIN */
 
+again:
+
     cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
 
     ngx_add_timer(c->write, cscf->timeout);
@@ -620,7 +631,9 @@ ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c)
             return NGX_ERROR;
         }
 
-        return NGX_AGAIN;
+        if (s->buffer->pos == s->buffer->last) {
+            return NGX_AGAIN;
+        }
     }
 
     cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
@@ -661,8 +674,12 @@ void
 ngx_mail_auth(ngx_mail_session_t *s, ngx_connection_t *c)
 {
     s->args.nelts = 0;
-    s->buffer->pos = s->buffer->start;
-    s->buffer->last = s->buffer->start;
+
+    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) {

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_imap_handler.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_imap_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_imap_module.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_parse.c (+32 -2) 97%
===================================================================
--- vendor/nginx-1.4.7/src/mail/ngx_mail_parse.c    2014-07-02 11:31:57 +0900 (eb16d5b)
+++ vendor/nginx-1.7.2/src/mail/ngx_mail_parse.c    2014-07-04 15:15:55 +0900 (b158f5a)
@@ -626,6 +626,8 @@ ngx_mail_smtp_parse_command(ngx_mail_session_t *s)
     ngx_str_t  *arg;
     enum {
         sw_start = 0,
+        sw_command,
+        sw_invalid,
         sw_spaces_before_argument,
         sw_argument,
         sw_almost_done
@@ -640,8 +642,14 @@ ngx_mail_smtp_parse_command(ngx_mail_session_t *s)
 
         /* 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->buffer->start;
+                c = s->cmd_start;
 
                 if (p - c == 4) {
 
@@ -719,6 +727,9 @@ ngx_mail_smtp_parse_command(ngx_mail_session_t *s)
                     goto invalid;
                 }
 
+                s->cmd.data = s->cmd_start;
+                s->cmd.len = p - s->cmd_start;
+
                 switch (ch) {
                 case ' ':
                     state = sw_spaces_before_argument;
@@ -738,6 +749,9 @@ ngx_mail_smtp_parse_command(ngx_mail_session_t *s)
 
             break;
 
+        case sw_invalid:
+            goto invalid;
+
         case sw_spaces_before_argument:
             switch (ch) {
             case ' ':
@@ -824,9 +838,21 @@ done:
 
 invalid:
 
-    s->state = sw_start;
+    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;
 }
 
@@ -842,6 +868,10 @@ ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c)
     }
 #endif
 
+    if (s->args.nelts == 0) {
+        return NGX_MAIL_PARSE_INVALID_COMMAND;
+    }
+
     arg = s->args.elts;
 
     if (arg[0].len == 5) {

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_pop3_handler.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_pop3_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_pop3_module.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_proxy_module.c (+54 -7) 95%
===================================================================
--- vendor/nginx-1.4.7/src/mail/ngx_mail_proxy_module.c    2014-07-02 11:31:57 +0900 (4ea608c)
+++ vendor/nginx-1.7.2/src/mail/ngx_mail_proxy_module.c    2014-07-04 15:15:55 +0900 (41cbcf6)
@@ -542,17 +542,40 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
                           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;
         }
 
-        line.len = ngx_sprintf(line.data,
-                       "XCLIENT ADDR=%V%s%V NAME=%V" CRLF,
-                       &s->connection->addr_text,
-                       (s->login.len ? " LOGIN=" : ""), &s->login, &s->host)
-                   - line.data;
+        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;
@@ -657,7 +680,12 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
         c->log->action = NULL;
         ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
 
-        ngx_mail_proxy_handler(s->connection->write);
+        if (s->buffer->pos == s->buffer->last) {
+            ngx_mail_proxy_handler(s->connection->write);
+
+        } else {
+            ngx_mail_proxy_handler(c->write);
+        }
 
         return;
 
@@ -702,7 +730,7 @@ ngx_mail_proxy_dummy_handler(ngx_event_t *wev)
 static ngx_int_t
 ngx_mail_proxy_read_response(ngx_mail_session_t *s, ngx_uint_t state)
 {
-    u_char                 *p;
+    u_char                 *p, *m;
     ssize_t                 n;
     ngx_buf_t              *b;
     ngx_mail_proxy_conf_t  *pcf;
@@ -779,6 +807,25 @@ ngx_mail_proxy_read_response(ngx_mail_session_t *s, ngx_uint_t state)
         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:

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_smtp_handler.c (+56 -74) 90%
===================================================================
--- vendor/nginx-1.4.7/src/mail/ngx_mail_smtp_handler.c    2014-07-02 11:31:57 +0900 (2171423)
+++ vendor/nginx-1.7.2/src/mail/ngx_mail_smtp_handler.c    2014-07-04 15:15:55 +0900 (665f5ef)
@@ -55,7 +55,6 @@ static ngx_str_t  smtp_tempunavail = ngx_string("[TEMPUNAVAIL]");
 void
 ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
 {
-    struct sockaddr_in        *sin;
     ngx_resolver_ctx_t        *ctx;
     ngx_mail_core_srv_conf_t  *cscf;
 
@@ -67,11 +66,13 @@ ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
         return;
     }
 
-    if (c->sockaddr->sa_family != AF_INET) {
+#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";
 
@@ -81,11 +82,8 @@ ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
         return;
     }
 
-    /* AF_INET only */
-
-    sin = (struct sockaddr_in *) c->sockaddr;
-
-    ctx->addr = sin->sin_addr.s_addr;
+    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;
@@ -167,7 +165,6 @@ ngx_mail_smtp_resolve_name(ngx_event_t *rev)
     }
 
     ctx->name = s->host;
-    ctx->type = NGX_RESOLVE_A;
     ctx->handler = ngx_mail_smtp_resolve_name_handler;
     ctx->data = s;
     ctx->timeout = cscf->resolver_timeout;
@@ -181,10 +178,8 @@ ngx_mail_smtp_resolve_name(ngx_event_t *rev)
 static void
 ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx)
 {
-    in_addr_t            addr;
     ngx_uint_t           i;
     ngx_connection_t    *c;
-    struct sockaddr_in  *sin;
     ngx_mail_session_t  *s;
 
     s = ctx->data;
@@ -205,22 +200,29 @@ ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx)
 
     } else {
 
-        /* AF_INET only */
+#if (NGX_DEBUG)
+        {
+        u_char     text[NGX_SOCKADDR_STRLEN];
+        ngx_str_t  addr;
 
-        sin = (struct sockaddr_in *) c->sockaddr;
+        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);
 
-            addr = ctx->addrs[i];
-
-            ngx_log_debug4(NGX_LOG_DEBUG_MAIL, c->log, 0,
-                           "name was resolved to %ud.%ud.%ud.%ud",
-                           (ntohl(addr) >> 24) & 0xff,
-                           (ntohl(addr) >> 16) & 0xff,
-                           (ntohl(addr) >> 8) & 0xff,
-                           ntohl(addr) & 0xff);
+            ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
+                           "name was resolved to %V", &addr);
+        }
+        }
+#endif
 
-            if (addr == sin->sin_addr.s_addr) {
+        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;
             }
         }
@@ -321,6 +323,7 @@ ngx_mail_smtp_invalid_pipelining(ngx_event_t *rev)
         }
 
         ngx_str_set(&s->out, smtp_invalid_pipelining);
+        s->quit = 1;
     }
 
     ngx_mail_send(c->write);
@@ -485,6 +488,10 @@ ngx_mail_smtp_auth_state(ngx_event_t *rev)
         }
     }
 
+    if (s->buffer->pos < s->buffer->last) {
+        s->blocked = 1;
+    }
+
     switch (rc) {
 
     case NGX_DONE:
@@ -504,11 +511,14 @@ ngx_mail_smtp_auth_state(ngx_event_t *rev)
 
     case NGX_OK:
         s->args.nelts = 0;
-        s->buffer->pos = s->buffer->start;
-        s->buffer->last = s->buffer->start;
+
+        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->start;
+            s->arg_start = s->buffer->pos;
         }
 
         ngx_mail_send(c->write);
@@ -651,9 +661,7 @@ 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)
 {
-    u_char                     ch;
-    ngx_str_t                  l;
-    ngx_uint_t                 i;
+    ngx_str_t                 *arg, cmd;
     ngx_mail_smtp_srv_conf_t  *sscf;
 
     sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
@@ -671,37 +679,25 @@ ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c)
         return NGX_OK;
     }
 
-    l.len = s->buffer->last - s->buffer->start;
-    l.data = s->buffer->start;
-
-    for (i = 0; i < l.len; i++) {
-        ch = l.data[i];
-
-        if (ch != CR && ch != LF) {
-            continue;
-        }
-
-        l.data[i] = ' ';
+    if (s->args.nelts == 0) {
+        ngx_str_set(&s->out, smtp_invalid_argument);
+        return NGX_OK;
     }
 
-    while (i) {
-        if (l.data[i - 1] != ' ') {
-            break;
-        }
-
-        i--;
-    }
+    arg = s->args.elts;
+    arg += s->args.nelts - 1;
 
-    l.len = i;
+    cmd.len = arg->data + arg->len - s->cmd.data;
+    cmd.data = s->cmd.data;
 
-    s->smtp_from.len = l.len;
+    s->smtp_from.len = cmd.len;
 
-    s->smtp_from.data = ngx_pnalloc(c->pool, l.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, l.data, l.len);
+    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);
@@ -715,46 +711,32 @@ ngx_mail_smtp_mail(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)
 {
-    u_char      ch;
-    ngx_str_t   l;
-    ngx_uint_t  i;
+    ngx_str_t  *arg, cmd;
 
     if (s->smtp_from.len == 0) {
         ngx_str_set(&s->out, smtp_bad_sequence);
         return NGX_OK;
     }
 
-    l.len = s->buffer->last - s->buffer->start;
-    l.data = s->buffer->start;
-
-    for (i = 0; i < l.len; i++) {
-        ch = l.data[i];
-
-        if (ch != CR && ch != LF) {
-            continue;
-        }
-
-        l.data[i] = ' ';
+    if (s->args.nelts == 0) {
+        ngx_str_set(&s->out, smtp_invalid_argument);
+        return NGX_OK;
     }
 
-    while (i) {
-        if (l.data[i - 1] != ' ') {
-            break;
-        }
-
-        i--;
-    }
+    arg = s->args.elts;
+    arg += s->args.nelts - 1;
 
-    l.len = i;
+    cmd.len = arg->data + arg->len - s->cmd.data;
+    cmd.data = s->cmd.data;
 
-    s->smtp_to.len = l.len;
+    s->smtp_to.len = cmd.len;
 
-    s->smtp_to.data = ngx_pnalloc(c->pool, l.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, l.data, l.len);
+    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);

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_smtp_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_smtp_module.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_ssl_module.c (+48 -11) 89%
===================================================================
--- vendor/nginx-1.4.7/src/mail/ngx_mail_ssl_module.c    2014-07-02 11:31:57 +0900 (60e7a9a)
+++ vendor/nginx-1.7.2/src/mail/ngx_mail_ssl_module.c    2014-07-04 15:15:55 +0900 (fe88f48)
@@ -25,7 +25,7 @@ static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
 
 
-static ngx_conf_enum_t  ngx_http_starttls_state[] = {
+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 },
@@ -58,7 +58,7 @@ static ngx_command_t  ngx_mail_ssl_commands[] = {
       ngx_mail_ssl_starttls,
       NGX_MAIL_SRV_CONF_OFFSET,
       offsetof(ngx_mail_ssl_conf_t, starttls),
-      ngx_http_starttls_state },
+      ngx_mail_starttls_state },
 
     { ngx_string("ssl_certificate"),
       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
@@ -116,6 +116,20 @@ static ngx_command_t  ngx_mail_ssl_commands[] = {
       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,
@@ -184,6 +198,8 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
     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;
 }
@@ -292,15 +308,14 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
         return NGX_CONF_ERROR;
     }
 
-    if (conf->ciphers.len) {
-        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);
-        }
+    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) {
@@ -313,6 +328,10 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
         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);
 
@@ -328,6 +347,24 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
         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;
 }
 

  Renamed: vendor/nginx-1.7.2/src/mail/ngx_mail_ssl_module.h (+3 -0) 92%
===================================================================
--- vendor/nginx-1.4.7/src/mail/ngx_mail_ssl_module.h    2014-07-02 11:31:57 +0900 (7f59b38)
+++ vendor/nginx-1.7.2/src/mail/ngx_mail_ssl_module.h    2014-07-04 15:15:55 +0900 (bef0e51)
@@ -41,6 +41,9 @@ typedef struct {
 
     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;

  Renamed: vendor/nginx-1.7.2/src/misc/ngx_cpp_test_module.cpp (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/misc/ngx_google_perftools_module.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_aio_read.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_aio_read_chain.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_aio_write.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_aio_write_chain.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_alloc.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_alloc.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_atomic.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_channel.c (+3 -1) 98%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_channel.c    2014-07-02 11:31:57 +0900 (29c69da)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_channel.c    2014-07-04 15:15:55 +0900 (8e90696)
@@ -34,6 +34,8 @@ ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
         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;
@@ -142,7 +144,7 @@ ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, ngx_log_t *log)
 
     if ((size_t) n < sizeof(ngx_channel_t)) {
         ngx_log_error(NGX_LOG_ALERT, log, 0,
-                      "recvmsg() returned not enough data: %uz", n);
+                      "recvmsg() returned not enough data: %z", n);
         return NGX_ERROR;
     }
 

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_channel.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_daemon.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_darwin.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_darwin_config.h (+1 -3) 96%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_darwin_config.h    2014-07-02 11:31:57 +0900 (149778c)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_darwin_config.h    2014-07-04 15:15:55 +0900 (bbad977)
@@ -9,9 +9,6 @@
 #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>
@@ -20,6 +17,7 @@
 #include <stddef.h>             /* offsetof() */
 #include <stdio.h>
 #include <stdlib.h>
+#include <ctype.h>
 #include <errno.h>
 #include <string.h>
 #include <signal.h>

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_darwin_init.c (+1 -1) 99%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_darwin_init.c    2014-07-02 11:31:57 +0900 (e3cc5fe)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_darwin_init.c    2014-07-04 15:15:55 +0900 (1bc7520)
@@ -59,7 +59,7 @@ sysctl_t sysctls[] = {
 
 
 void
-ngx_debug_init()
+ngx_debug_init(void)
 {
 #if (NGX_DEBUG_MALLOC)
 

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_darwin_sendfile_chain.c (+14 -16) 93%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_darwin_sendfile_chain.c    2014-07-02 11:31:57 +0900 (078d10b)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_darwin_sendfile_chain.c    2014-07-04 15:15:55 +0900 (76c4a3a)
@@ -317,9 +317,9 @@ ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 
         c->sent += sent;
 
-        for (cl = in; cl; cl = cl->next) {
+        for ( /* void */ ; in; in = in->next) {
 
-            if (ngx_buf_special(cl->buf)) {
+            if (ngx_buf_special(in->buf)) {
                 continue;
             }
 
@@ -327,28 +327,28 @@ ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
                 break;
             }
 
-            size = ngx_buf_size(cl->buf);
+            size = ngx_buf_size(in->buf);
 
             if (sent >= size) {
                 sent -= size;
 
-                if (ngx_buf_in_memory(cl->buf)) {
-                    cl->buf->pos = cl->buf->last;
+                if (ngx_buf_in_memory(in->buf)) {
+                    in->buf->pos = in->buf->last;
                 }
 
-                if (cl->buf->in_file) {
-                    cl->buf->file_pos = cl->buf->file_last;
+                if (in->buf->in_file) {
+                    in->buf->file_pos = in->buf->file_last;
                 }
 
                 continue;
             }
 
-            if (ngx_buf_in_memory(cl->buf)) {
-                cl->buf->pos += (size_t) sent;
+            if (ngx_buf_in_memory(in->buf)) {
+                in->buf->pos += (size_t) sent;
             }
 
-            if (cl->buf->in_file) {
-                cl->buf->file_pos += sent;
+            if (in->buf->in_file) {
+                in->buf->file_pos += sent;
             }
 
             break;
@@ -360,13 +360,11 @@ ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 
         if (!complete) {
             wev->ready = 0;
-            return cl;
+            return in;
         }
 
-        if (send >= limit || cl == NULL) {
-            return cl;
+        if (send >= limit || in == NULL) {
+            return in;
         }
-
-        in = cl;
     }
 }

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_errno.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_errno.h (+3 -0) 94%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_errno.h    2014-07-02 11:31:57 +0900 (1497c5f)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_errno.h    2014-07-04 15:15:55 +0900 (16cafda)
@@ -34,6 +34,8 @@ typedef int               ngx_err_t;
 #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
@@ -50,6 +52,7 @@ typedef int               ngx_err_t;
 #define NGX_EILSEQ        EILSEQ
 #define NGX_ENOMOREFILES  0
 #define NGX_ELOOP         ELOOP
+#define NGX_EBADF         EBADF
 
 #if (NGX_HAVE_OPENAT)
 #define NGX_EMLINK        EMLINK

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_file_aio_read.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_files.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_files.h (+10 -16) 95%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_files.h    2014-07-02 11:31:57 +0900 (9c97e2b)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_files.h    2014-07-04 15:15:55 +0900 (a78ec96)
@@ -53,7 +53,9 @@ typedef struct {
 
 #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)
@@ -72,8 +74,8 @@ typedef struct {
 #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_TRUNCATE        (O_CREAT|O_TRUNC)
+#define NGX_FILE_APPEND          (O_WRONLY|O_APPEND)
 #define NGX_FILE_NONBLOCK        O_NONBLOCK
 
 #if (NGX_HAVE_OPENAT)
@@ -86,13 +88,16 @@ typedef struct {
 #endif
 
 #if defined(O_SEARCH)
-#define NGX_FILE_SEARCH          O_SEARCH|NGX_FILE_DIRECTORY
+#define NGX_FILE_SEARCH          (O_SEARCH|NGX_FILE_DIRECTORY)
 
 #elif defined(O_EXEC)
-#define NGX_FILE_SEARCH          O_EXEC|NGX_FILE_DIRECTORY
+#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
+#define NGX_FILE_SEARCH          (O_RDONLY|NGX_FILE_DIRECTORY)
 #endif
 
 #endif /* NGX_HAVE_OPENAT */
@@ -189,17 +194,6 @@ ngx_int_t ngx_create_file_mapping(ngx_file_mapping_t *fm);
 void ngx_close_file_mapping(ngx_file_mapping_t *fm);
 
 
-#if (NGX_HAVE_CASELESS_FILESYSTEM)
-
-#define ngx_filename_cmp(s1, s2, n)  strncasecmp((char *) s1, (char *) s2, n)
-
-#else
-
-#define ngx_filename_cmp         ngx_memcmp
-
-#endif
-
-
 #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)

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_freebsd.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_config.h (+6 -0) 96%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_freebsd_config.h    2014-07-02 11:31:57 +0900 (5b3ff27)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_config.h    2014-07-04 15:15:55 +0900 (92b2928)
@@ -16,6 +16,7 @@
 #include <stddef.h>             /* offsetof() */
 #include <stdio.h>
 #include <stdlib.h>
+#include <ctype.h>
 #include <errno.h>
 #include <string.h>
 #include <signal.h>
@@ -94,6 +95,11 @@ typedef struct aiocb  ngx_aiocb_t;
 #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);

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_init.c (+1 -1) 99%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_freebsd_init.c    2014-07-02 11:31:57 +0900 (aeeceaf)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_init.c    2014-07-04 15:15:55 +0900 (c4c12dd)
@@ -72,7 +72,7 @@ sysctl_t sysctls[] = {
 
 
 void
-ngx_debug_init()
+ngx_debug_init(void)
 {
 #if (NGX_DEBUG_MALLOC)
 

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_rfork_thread.c (+1 -1) 99%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_freebsd_rfork_thread.c    2014-07-02 11:31:57 +0900 (530ec4a)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_rfork_thread.c    2014-07-04 15:15:55 +0900 (e92f9a9)
@@ -271,7 +271,7 @@ ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle)
 
 
 ngx_tid_t
-ngx_thread_self()
+ngx_thread_self(void)
 {
     ngx_int_t  tid;
 

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_rfork_thread.h (+2 -2) 97%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_freebsd_rfork_thread.h    2014-07-02 11:31:57 +0900 (2c238f7)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_rfork_thread.h    2014-07-04 15:15:55 +0900 (ff16044)
@@ -57,7 +57,7 @@ extern size_t   ngx_thread_stack_size;
 
 
 static ngx_inline ngx_int_t
-ngx_gettid()
+ngx_gettid(void)
 {
     char  *sp;
 
@@ -83,7 +83,7 @@ ngx_gettid()
 }
 
 
-ngx_tid_t ngx_thread_self();
+ngx_tid_t ngx_thread_self(void);
 
 
 typedef ngx_uint_t               ngx_tls_key_t;

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_sendfile_chain.c (+17 -19) 94%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_freebsd_sendfile_chain.c    2014-07-02 11:31:57 +0900 (f58b5c2)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_freebsd_sendfile_chain.c    2014-07-04 15:15:55 +0900 (11cec82)
@@ -231,7 +231,7 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
                 && c->tcp_nopush == NGX_TCP_NOPUSH_UNSET)
             {
                 if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
-                    err = ngx_errno;
+                    err = ngx_socket_errno;
 
                     /*
                      * there is a tiny chance to be interrupted, however,
@@ -368,9 +368,9 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 
         c->sent += sent;
 
-        for (cl = in; cl; cl = cl->next) {
+        for ( /* void */ ; in; in = in->next) {
 
-            if (ngx_buf_special(cl->buf)) {
+            if (ngx_buf_special(in->buf)) {
                 continue;
             }
 
@@ -378,28 +378,28 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
                 break;
             }
 
-            size = ngx_buf_size(cl->buf);
+            size = ngx_buf_size(in->buf);
 
             if (sent >= size) {
                 sent -= size;
 
-                if (ngx_buf_in_memory(cl->buf)) {
-                    cl->buf->pos = cl->buf->last;
+                if (ngx_buf_in_memory(in->buf)) {
+                    in->buf->pos = in->buf->last;
                 }
 
-                if (cl->buf->in_file) {
-                    cl->buf->file_pos = cl->buf->file_last;
+                if (in->buf->in_file) {
+                    in->buf->file_pos = in->buf->file_last;
                 }
 
                 continue;
             }
 
-            if (ngx_buf_in_memory(cl->buf)) {
-                cl->buf->pos += (size_t) sent;
+            if (ngx_buf_in_memory(in->buf)) {
+                in->buf->pos += (size_t) sent;
             }
 
-            if (cl->buf->in_file) {
-                cl->buf->file_pos += sent;
+            if (in->buf->in_file) {
+                in->buf->file_pos += sent;
             }
 
             break;
@@ -407,7 +407,7 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 
 #if (NGX_HAVE_AIO_SENDFILE)
         if (c->busy_sendfile) {
-            return cl;
+            return in;
         }
 #endif
 
@@ -421,7 +421,7 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
              */
 
             wev->ready = 0;
-            return cl;
+            return in;
         }
 
         if (eintr) {
@@ -430,13 +430,11 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 
         if (!complete) {
             wev->ready = 0;
-            return cl;
+            return in;
         }
 
-        if (send >= limit || cl == NULL) {
-            return cl;
+        if (send >= limit || in == NULL) {
+            return in;
         }
-
-        in = cl;
     }
 }

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_gcc_atomic_amd64.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_gcc_atomic_ppc.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_gcc_atomic_sparc64.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_gcc_atomic_x86.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_linux.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_linux_aio_read.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_linux_config.h (+11 -2) 93%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_linux_config.h    2014-07-02 11:31:57 +0900 (2834032)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_linux_config.h    2014-07-04 15:15:55 +0900 (c6c02c9)
@@ -22,6 +22,7 @@
 #include <stddef.h>             /* offsetof() */
 #include <stdio.h>
 #include <stdlib.h>
+#include <ctype.h>
 #include <errno.h>
 #include <string.h>
 #include <signal.h>
@@ -51,7 +52,6 @@
 #include <malloc.h>             /* memalign() */
 #include <limits.h>             /* IOV_MAX */
 #include <sys/ioctl.h>
-#include <sys/sysctl.h>
 #include <crypt.h>
 #include <sys/utsname.h>        /* uname() */
 
@@ -77,17 +77,26 @@ extern ssize_t sendfile(int s, int fd, int32_t *offset, size_t size);
 #endif
 
 
-#if (NGX_HAVE_POLL || NGX_HAVE_RTSIG)
+#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)
+#if (NGX_HAVE_SYS_EVENTFD_H)
+#include <sys/eventfd.h>
+#endif
 #include <sys/syscall.h>
 #include <linux/aio_abi.h>
 typedef struct iocb  ngx_aiocb_t;

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_linux_init.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_linux_sendfile_chain.c (+20 -22) 90%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_linux_sendfile_chain.c    2014-07-02 11:31:57 +0900 (e8f3d5a)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_linux_sendfile_chain.c    2014-07-04 15:15:55 +0900 (16395f9)
@@ -24,7 +24,7 @@
  * so we limit it to 2G-1 bytes.
  */
 
-#define NGX_SENDFILE_LIMIT  2147483647L
+#define NGX_SENDFILE_MAXSIZE  2147483647L
 
 
 #if (IOV_MAX > 64)
@@ -63,8 +63,8 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 
     /* the maximum limit size is 2G-1 - the page size */
 
-    if (limit == 0 || limit > (off_t) (NGX_SENDFILE_LIMIT - ngx_pagesize)) {
-        limit = NGX_SENDFILE_LIMIT - ngx_pagesize;
+    if (limit == 0 || limit > (off_t) (NGX_SENDFILE_MAXSIZE - ngx_pagesize)) {
+        limit = NGX_SENDFILE_MAXSIZE - ngx_pagesize;
     }
 
 
@@ -163,7 +163,7 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
                 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
                                (const void *) &tcp_nodelay, sizeof(int)) == -1)
                 {
-                    err = ngx_errno;
+                    err = ngx_socket_errno;
 
                     /*
                      * there is a tiny chance to be interrupted, however,
@@ -181,7 +181,7 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
                 } else {
                     c->tcp_nodelay = NGX_TCP_NODELAY_UNSET;
 
-                    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
                                    "no tcp_nodelay");
                 }
             }
@@ -189,7 +189,7 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
             if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
 
                 if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
-                    err = ngx_errno;
+                    err = ngx_socket_errno;
 
                     /*
                      * there is a tiny chance to be interrupted, however,
@@ -325,9 +325,9 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 
         c->sent += sent;
 
-        for (cl = in; cl; cl = cl->next) {
+        for ( /* void */ ; in; in = in->next) {
 
-            if (ngx_buf_special(cl->buf)) {
+            if (ngx_buf_special(in->buf)) {
                 continue;
             }
 
@@ -335,28 +335,28 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
                 break;
             }
 
-            size = ngx_buf_size(cl->buf);
+            size = ngx_buf_size(in->buf);
 
             if (sent >= size) {
                 sent -= size;
 
-                if (ngx_buf_in_memory(cl->buf)) {
-                    cl->buf->pos = cl->buf->last;
+                if (ngx_buf_in_memory(in->buf)) {
+                    in->buf->pos = in->buf->last;
                 }
 
-                if (cl->buf->in_file) {
-                    cl->buf->file_pos = cl->buf->file_last;
+                if (in->buf->in_file) {
+                    in->buf->file_pos = in->buf->file_last;
                 }
 
                 continue;
             }
 
-            if (ngx_buf_in_memory(cl->buf)) {
-                cl->buf->pos += (size_t) sent;
+            if (ngx_buf_in_memory(in->buf)) {
+                in->buf->pos += (size_t) sent;
             }
 
-            if (cl->buf->in_file) {
-                cl->buf->file_pos += sent;
+            if (in->buf->in_file) {
+                in->buf->file_pos += sent;
             }
 
             break;
@@ -368,13 +368,11 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 
         if (!complete) {
             wev->ready = 0;
-            return cl;
+            return in;
         }
 
-        if (send >= limit || cl == NULL) {
-            return cl;
+        if (send >= limit || in == NULL) {
+            return in;
         }
-
-        in = cl;
     }
 }

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_os.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_posix_config.h (+1 -0) 99%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_posix_config.h    2014-07-02 11:31:57 +0900 (4cf90cc)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_posix_config.h    2014-07-04 15:15:55 +0900 (d725659)
@@ -39,6 +39,7 @@
 #include <stddef.h>             /* offsetof() */
 #include <stdio.h>
 #include <stdlib.h>
+#include <ctype.h>
 #include <errno.h>
 #include <string.h>
 #include <signal.h>

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_posix_init.c (+1 -1) 97%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_posix_init.c    2014-07-02 11:31:57 +0900 (58e6f76)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_posix_init.c    2014-07-04 15:15:55 +0900 (9a4de02)
@@ -82,7 +82,7 @@ ngx_os_init(ngx_log_t *log)
 void
 ngx_os_status(ngx_log_t *log)
 {
-    ngx_log_error(NGX_LOG_NOTICE, log, 0, NGINX_VER);
+    ngx_log_error(NGX_LOG_NOTICE, log, 0, NGINX_VER_BUILD);
 
 #ifdef NGX_COMPILER
     ngx_log_error(NGX_LOG_NOTICE, log, 0, "built by " NGX_COMPILER);

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_process.c (+5 -0) 99%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_process.c    2014-07-02 11:31:57 +0900 (4ef3582)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_process.c    2014-07-04 15:15:55 +0900 (6f3f385)
@@ -291,9 +291,14 @@ ngx_init_signals(ngx_log_t *log)
         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
         }
     }
 

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_process.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_process_cycle.c (+22 -7) 97%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_process_cycle.c    2014-07-02 11:31:57 +0900 (dfdfae0)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_process_cycle.c    2014-07-04 15:15:55 +0900 (fb10d77)
@@ -355,6 +355,8 @@ ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
 
     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++) {
@@ -401,6 +403,8 @@ ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn)
                       &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;
@@ -460,6 +464,8 @@ ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo)
     ngx_err_t      err;
     ngx_channel_t  ch;
 
+    ngx_memzero(&ch, sizeof(ngx_channel_t));
+
 #if (NGX_BROKEN_SCM_RIGHTS)
 
     ch.command = 0;
@@ -530,7 +536,7 @@ ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo)
         }
 
         ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
-                       "kill (%P, %d)" , ngx_processes[i].pid, signo);
+                       "kill (%P, %d)", ngx_processes[i].pid, signo);
 
         if (kill(ngx_processes[i].pid, signo) == -1) {
             err = ngx_errno;
@@ -561,6 +567,8 @@ ngx_reap_children(ngx_cycle_t *cycle)
     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;
 
@@ -702,10 +710,13 @@ ngx_master_process_exit(ngx_cycle_t *cycle)
      * ngx_cycle->pool is already destroyed.
      */
 
-    ngx_exit_log_file.fd = ngx_cycle->log->file->fd;
 
-    ngx_exit_log = *ngx_cycle->log;
+    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;
@@ -950,6 +961,8 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
                       "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
@@ -1035,8 +1048,8 @@ ngx_worker_process_exit(ngx_cycle_t *cycle)
                 && !c[i].read->resolver)
             {
                 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
-                              "open socket #%d left in connection %ui",
-                              c[i].fd, i);
+                              "*%uA open socket #%d left in connection %ui",
+                              c[i].number, c[i].fd, i);
                 ngx_debug_quit = 1;
             }
         }
@@ -1054,10 +1067,12 @@ ngx_worker_process_exit(ngx_cycle_t *cycle)
      * ngx_cycle->pool is already destroyed.
      */
 
-    ngx_exit_log_file.fd = ngx_cycle->log->file->fd;
+    ngx_exit_log = *ngx_log_get_file_log(ngx_cycle->log);
 
-    ngx_exit_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;

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_process_cycle.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_pthread_thread.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_readv_chain.c (+2 -1) 98%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_readv_chain.c    2014-07-02 11:31:57 +0900 (7b6badf)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_readv_chain.c    2014-07-04 15:15:55 +0900 (8836c81)
@@ -129,6 +129,7 @@ ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
                                   "%d available bytes", rev->available);
 #endif
 
+                    rev->ready = 0;
                     rev->eof = 1;
                     rev->available = 0;
                 }
@@ -136,7 +137,7 @@ ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
                 return n;
             }
 
-            if (n < size) {
+            if (n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) {
                 rev->ready = 0;
             }
 

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_recv.c (+4 -1) 96%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_recv.c    2014-07-02 11:31:57 +0900 (6a4a099)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_recv.c    2014-07-04 15:15:55 +0900 (86675df)
@@ -80,6 +80,7 @@ ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
                      * even if kqueue reported about available data
                      */
 
+                    rev->ready = 0;
                     rev->eof = 1;
                     rev->available = 0;
                 }
@@ -87,7 +88,9 @@ ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
                 return n;
             }
 
-            if ((size_t) n < size) {
+            if ((size_t) n < size
+                && !(ngx_event_flags & NGX_USE_GREEDY_EVENT))
+            {
                 rev->ready = 0;
             }
 

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_send.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_setaffinity.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_setaffinity.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_setproctitle.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_setproctitle.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_shmem.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_shmem.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_socket.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_socket.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_solaris.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_solaris_config.h (+1 -0) 98%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_solaris_config.h    2014-07-02 11:31:57 +0900 (e664ba8)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_solaris_config.h    2014-07-04 15:15:55 +0900 (ddfd984)
@@ -22,6 +22,7 @@
 #include <stddef.h>             /* offsetof() */
 #include <stdio.h>
 #include <stdlib.h>
+#include <ctype.h>
 #include <errno.h>
 #include <string.h>
 #include <signal.h>

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_solaris_init.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_solaris_sendfilev_chain.c (+14 -16) 90%
===================================================================
--- vendor/nginx-1.4.7/src/os/unix/ngx_solaris_sendfilev_chain.c    2014-07-02 11:31:57 +0900 (520eaaa)
+++ vendor/nginx-1.7.2/src/os/unix/ngx_solaris_sendfilev_chain.c    2014-07-04 15:15:55 +0900 (37bb09d)
@@ -207,9 +207,9 @@ ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 
         c->sent += sent;
 
-        for (cl = in; cl; cl = cl->next) {
+        for ( /* void */ ; in; in = in->next) {
 
-            if (ngx_buf_special(cl->buf)) {
+            if (ngx_buf_special(in->buf)) {
                 continue;
             }
 
@@ -217,28 +217,28 @@ ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
                 break;
             }
 
-            size = ngx_buf_size(cl->buf);
+            size = ngx_buf_size(in->buf);
 
             if ((off_t) sent >= size) {
                 sent = (size_t) ((off_t) sent - size);
 
-                if (ngx_buf_in_memory(cl->buf)) {
-                    cl->buf->pos = cl->buf->last;
+                if (ngx_buf_in_memory(in->buf)) {
+                    in->buf->pos = in->buf->last;
                 }
 
-                if (cl->buf->in_file) {
-                    cl->buf->file_pos = cl->buf->file_last;
+                if (in->buf->in_file) {
+                    in->buf->file_pos = in->buf->file_last;
                 }
 
                 continue;
             }
 
-            if (ngx_buf_in_memory(cl->buf)) {
-                cl->buf->pos += sent;
+            if (ngx_buf_in_memory(in->buf)) {
+                in->buf->pos += sent;
             }
 
-            if (cl->buf->in_file) {
-                cl->buf->file_pos += sent;
+            if (in->buf->in_file) {
+                in->buf->file_pos += sent;
             }
 
             break;
@@ -250,13 +250,11 @@ ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 
         if (!complete) {
             wev->ready = 0;
-            return cl;
+            return in;
         }
 
-        if (send >= limit || cl == NULL) {
-            return cl;
+        if (send >= limit || in == NULL) {
+            return in;
         }
-
-        in = cl;
     }
 }

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_sunpro_amd64.il (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_sunpro_atomic_sparc64.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_sunpro_sparc64.il (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_sunpro_x86.il (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_thread.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_time.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_time.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_udp_recv.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_user.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_user.h (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/ngx_writev_chain.c (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.7.2/src/os/unix/rfork_thread.S (+0 -0) 100%
===================================================================




More information about the Groonga-commit mailing list
Back to archive index