[Groonga-commit] groonga/groonga at e82e1ca [master] httpd: update nginx to latest stable release

Back to archive index

HAYASHI Kentaro null+****@clear*****
Mon Jul 22 13:32:39 JST 2013


HAYASHI Kentaro	2013-07-22 13:32:39 +0900 (Mon, 22 Jul 2013)

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

  Message:
    httpd: update nginx to latest stable release
    
    1.2.6 ->
    1.4.2
    
      % make update-nginx NEW_NGINX_VERSION=1.4.2

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

  Modified: nginx_version (+1 -1)
===================================================================
--- nginx_version    2013-07-22 11:05:55 +0900 (3c43790)
+++ nginx_version    2013-07-22 13:32:39 +0900 (9df886c)
@@ -1 +1 @@
-1.2.6
+1.4.2

  Deleted: vendor/nginx-1.2.6/auto/lib/perl/make (+0 -36) 100644
===================================================================
--- vendor/nginx-1.2.6/auto/lib/perl/make    2013-07-22 11:05:55 +0900 (5f13bb2)
+++ /dev/null
@@ -1,36 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-cat << END                                                    >> $NGX_MAKEFILE
-
-$NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.so:		\
-		src/http/modules/perl/nginx.pm				\
-		src/http/modules/perl/nginx.xs				\
-		src/http/modules/perl/ngx_http_perl_module.h		\
-		$NGX_OBJS/src/http/modules/perl/Makefile
-	cp -p src/http/modules/perl/nginx.* $NGX_OBJS/src/http/modules/perl/
-
-	cd $NGX_OBJS/src/http/modules/perl && \$(MAKE)
-
-	rm -rf $NGX_OBJS/install_perl
-
-
-$NGX_OBJS/src/http/modules/perl/Makefile:				\
-		src/http/modules/perl/Makefile.PL			\
-		src/http/modules/perl/nginx.pm
-	cp -p src/http/modules/perl/nginx.* $NGX_OBJS/src/http/modules/perl/
-	cp -p src/http/modules/perl/typemap $NGX_OBJS/src/http/modules/perl/
-	cp -p src/http/modules/perl/Makefile.PL $NGX_OBJS/src/http/modules/perl/
-
-	cd $NGX_OBJS/src/http/modules/perl				\
-		&& NGX_PM_CFLAGS="\$(NGX_PM_CFLAGS) -g $NGX_CC_OPT"	\
-			NGX_PCRE=$PCRE					\
-			NGX_OBJS=$NGX_OBJS				\
-			NGX_OPENSSL=$OPENSSL				\
-		$NGX_PERL Makefile.PL					\
-			LIB=$NGX_PERL_MODULES				\
-			INSTALLSITEMAN3DIR=$NGX_PERL_MODULES_MAN
-
-END

  Deleted: vendor/nginx-1.2.6/src/http/modules/perl/Makefile.PL (+0 -42) 100644
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/perl/Makefile.PL    2013-07-22 11:05:55 +0900 (cfb38c1)
+++ /dev/null
@@ -1,42 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-use 5.006001;
-use ExtUtils::MakeMaker;
-
-WriteMakefile(
-    NAME              => 'nginx',
-    VERSION_FROM      => 'nginx.pm',     # finds $VERSION
-    PREREQ_PM         => {},             # e.g., Module::Name => 1.1
-
-    ABSTRACT_FROM     => 'nginx.pm',     # retrieve abstract from module
-    AUTHOR            => 'Igor Sysoev',
-
-    CCFLAGS           => "$ENV{NGX_PM_CFLAGS}",
-    OPTIMIZE          => '-O',
-
-    INC               => "-I ../../../../../src/core " .
-                         "-I ../../../../../src/event " .
-                         "-I ../../../../../src/os/unix " .
-                         "-I ../../../../../src/http " .
-                         "-I ../../../../../src/http/modules " .
-                         "-I ../../../../../src/http/modules/perl " .
-                         "-I ../../../../../$ENV{NGX_OBJS} " .
-                         ($ENV{NGX_PCRE} =~ /^(YES|NO)/ ? "" :
-                             ($ENV{NGX_PCRE} =~ m#^/# ? "-I $ENV{NGX_PCRE} " :
-                                  "-I ../../../../../$ENV{NGX_PCRE} ")) .
-                         ($ENV{NGX_OPENSSL} =~ /^(YES|NO)/ ? "" :
-                             ($ENV{NGX_OPENSSL} =~ m#^/# ?
-                                  "-I $ENV{NGX_OPENSSL}/.openssl/include " :
-                      "-I ../../../../../$ENV{NGX_OPENSSL}/.openssl/include ")),
-
-    depend => {
-        'nginx.c'     =>
-                  "../../../../../src/http/modules/perl/ngx_http_perl_module.h"
-    },
-
-    PM => {
-        'nginx.pm'    => '$(INST_LIBDIR)/nginx.pm'
-    }
-);

  Deleted: vendor/nginx-1.2.6/src/http/ngx_http_request_body.c (+0 -653) 100644
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_request_body.c    2013-07-22 11:05:55 +0900 (3c69d05)
+++ /dev/null
@@ -1,653 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r);
-static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r);
-static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r,
-    ngx_chain_t *body);
-static ngx_int_t ngx_http_read_discarded_request_body(ngx_http_request_t *r);
-static ngx_int_t ngx_http_test_expect(ngx_http_request_t *r);
-
-
-/*
- * on completion ngx_http_read_client_request_body() adds to
- * r->request_body->bufs one or two bufs:
- *    *) one memory buf that was preread in r->header_in;
- *    *) one memory or file buf that contains the rest of the body
- */
-
-ngx_int_t
-ngx_http_read_client_request_body(ngx_http_request_t *r,
-    ngx_http_client_body_handler_pt post_handler)
-{
-    size_t                     preread;
-    ssize_t                    size;
-    ngx_int_t                  rc;
-    ngx_buf_t                 *b;
-    ngx_chain_t               *cl, **next;
-    ngx_http_request_body_t   *rb;
-    ngx_http_core_loc_conf_t  *clcf;
-
-    r->main->count++;
-
-    if (r->request_body || r->discard_body) {
-        post_handler(r);
-        return NGX_OK;
-    }
-
-    if (ngx_http_test_expect(r) != NGX_OK) {
-        rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
-        goto done;
-    }
-
-    rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
-    if (rb == NULL) {
-        rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
-        goto done;
-    }
-
-    r->request_body = rb;
-
-    if (r->headers_in.content_length_n < 0) {
-        post_handler(r);
-        return NGX_OK;
-    }
-
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
-    if (r->headers_in.content_length_n == 0) {
-
-        if (r->request_body_in_file_only) {
-            if (ngx_http_write_request_body(r, NULL) != NGX_OK) {
-                rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
-                goto done;
-            }
-        }
-
-        post_handler(r);
-
-        return NGX_OK;
-    }
-
-    rb->post_handler = post_handler;
-
-    /*
-     * set by ngx_pcalloc():
-     *
-     *     rb->bufs = NULL;
-     *     rb->buf = NULL;
-     *     rb->rest = 0;
-     */
-
-    preread = r->header_in->last - r->header_in->pos;
-
-    if (preread) {
-
-        /* there is the pre-read part of the request body */
-
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "http client request body preread %uz", preread);
-
-        b = ngx_calloc_buf(r->pool);
-        if (b == NULL) {
-            rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
-            goto done;
-        }
-
-        b->temporary = 1;
-        b->start = r->header_in->pos;
-        b->pos = r->header_in->pos;
-        b->last = r->header_in->last;
-        b->end = r->header_in->end;
-
-        rb->bufs = ngx_alloc_chain_link(r->pool);
-        if (rb->bufs == NULL) {
-            rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
-            goto done;
-        }
-
-        rb->bufs->buf = b;
-        rb->bufs->next = NULL;
-
-        rb->buf = b;
-
-        if ((off_t) preread >= r->headers_in.content_length_n) {
-
-            /* the whole request body was pre-read */
-
-            r->header_in->pos += (size_t) r->headers_in.content_length_n;
-            r->request_length += r->headers_in.content_length_n;
-            b->last = r->header_in->pos;
-
-            if (r->request_body_in_file_only) {
-                if (ngx_http_write_request_body(r, rb->bufs) != NGX_OK) {
-                    rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
-                    goto done;
-                }
-            }
-
-            post_handler(r);
-
-            return NGX_OK;
-        }
-
-        /*
-         * to not consider the body as pipelined request in
-         * ngx_http_set_keepalive()
-         */
-        r->header_in->pos = r->header_in->last;
-
-        r->request_length += preread;
-
-        rb->rest = r->headers_in.content_length_n - preread;
-
-        if (rb->rest <= (off_t) (b->end - b->last)) {
-
-            /* the whole request body may be placed in r->header_in */
-
-            rb->to_write = rb->bufs;
-
-            r->read_event_handler = ngx_http_read_client_request_body_handler;
-
-            rc = ngx_http_do_read_client_request_body(r);
-            goto done;
-        }
-
-        next = &rb->bufs->next;
-
-    } else {
-        b = NULL;
-        rb->rest = r->headers_in.content_length_n;
-        next = &rb->bufs;
-    }
-
-    size = clcf->client_body_buffer_size;
-    size += size >> 2;
-
-    if (rb->rest < size) {
-        size = (ssize_t) rb->rest;
-
-        if (r->request_body_in_single_buf) {
-            size += preread;
-        }
-
-    } else {
-        size = clcf->client_body_buffer_size;
-
-        /* disable copying buffer for r->request_body_in_single_buf */
-        b = NULL;
-    }
-
-    rb->buf = ngx_create_temp_buf(r->pool, size);
-    if (rb->buf == NULL) {
-        rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
-        goto done;
-    }
-
-    cl = ngx_alloc_chain_link(r->pool);
-    if (cl == NULL) {
-        rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
-        goto done;
-    }
-
-    cl->buf = rb->buf;
-    cl->next = NULL;
-
-    if (b && r->request_body_in_single_buf) {
-        size = b->last - b->pos;
-        ngx_memcpy(rb->buf->pos, b->pos, size);
-        rb->buf->last += size;
-
-        next = &rb->bufs;
-    }
-
-    *next = cl;
-
-    if (r->request_body_in_file_only || r->request_body_in_single_buf) {
-        rb->to_write = rb->bufs;
-
-    } else {
-        rb->to_write = rb->bufs->next ? rb->bufs->next : rb->bufs;
-    }
-
-    r->read_event_handler = ngx_http_read_client_request_body_handler;
-
-    rc = ngx_http_do_read_client_request_body(r);
-
-done:
-
-    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
-        r->main->count--;
-    }
-
-    return rc;
-}
-
-
-static void
-ngx_http_read_client_request_body_handler(ngx_http_request_t *r)
-{
-    ngx_int_t  rc;
-
-    if (r->connection->read->timedout) {
-        r->connection->timedout = 1;
-        ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
-        return;
-    }
-
-    rc = ngx_http_do_read_client_request_body(r);
-
-    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
-        ngx_http_finalize_request(r, rc);
-    }
-}
-
-
-static ngx_int_t
-ngx_http_do_read_client_request_body(ngx_http_request_t *r)
-{
-    size_t                     size;
-    ssize_t                    n;
-    ngx_buf_t                 *b;
-    ngx_connection_t          *c;
-    ngx_http_request_body_t   *rb;
-    ngx_http_core_loc_conf_t  *clcf;
-
-    c = r->connection;
-    rb = r->request_body;
-
-    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                   "http read client request body");
-
-    for ( ;; ) {
-        for ( ;; ) {
-            if (rb->buf->last == rb->buf->end) {
-
-                if (ngx_http_write_request_body(r, rb->to_write) != NGX_OK) {
-                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
-                }
-
-                rb->to_write = rb->bufs->next ? rb->bufs->next : rb->bufs;
-                rb->buf->last = rb->buf->start;
-            }
-
-            size = rb->buf->end - rb->buf->last;
-
-            if ((off_t) size > rb->rest) {
-                size = (size_t) rb->rest;
-            }
-
-            n = c->recv(c, rb->buf->last, size);
-
-            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                           "http client request body recv %z", n);
-
-            if (n == NGX_AGAIN) {
-                break;
-            }
-
-            if (n == 0) {
-                ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                              "client prematurely closed connection");
-            }
-
-            if (n == 0 || n == NGX_ERROR) {
-                c->error = 1;
-                return NGX_HTTP_BAD_REQUEST;
-            }
-
-            rb->buf->last += n;
-            rb->rest -= n;
-            r->request_length += n;
-
-            if (rb->rest == 0) {
-                break;
-            }
-
-            if (rb->buf->last < rb->buf->end) {
-                break;
-            }
-        }
-
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "http client request body rest %O", rb->rest);
-
-        if (rb->rest == 0) {
-            break;
-        }
-
-        if (!c->read->ready) {
-            clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-            ngx_add_timer(c->read, clcf->client_body_timeout);
-
-            if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
-                return NGX_HTTP_INTERNAL_SERVER_ERROR;
-            }
-
-            return NGX_AGAIN;
-        }
-    }
-
-    if (c->read->timer_set) {
-        ngx_del_timer(c->read);
-    }
-
-    if (rb->temp_file || r->request_body_in_file_only) {
-
-        /* save the last part */
-
-        if (ngx_http_write_request_body(r, rb->to_write) != NGX_OK) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
-        }
-
-        b = ngx_calloc_buf(r->pool);
-        if (b == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
-        }
-
-        b->in_file = 1;
-        b->file_pos = 0;
-        b->file_last = rb->temp_file->file.offset;
-        b->file = &rb->temp_file->file;
-
-        if (rb->bufs->next) {
-            rb->bufs->next->buf = b;
-
-        } else {
-            rb->bufs->buf = b;
-        }
-    }
-
-    if (rb->bufs->next
-        && (r->request_body_in_file_only || r->request_body_in_single_buf))
-    {
-        rb->bufs = rb->bufs->next;
-    }
-
-    r->read_event_handler = ngx_http_block_reading;
-
-    rb->post_handler(r);
-
-    return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_write_request_body(ngx_http_request_t *r, ngx_chain_t *body)
-{
-    ssize_t                    n;
-    ngx_temp_file_t           *tf;
-    ngx_http_request_body_t   *rb;
-    ngx_http_core_loc_conf_t  *clcf;
-
-    rb = r->request_body;
-
-    if (rb->temp_file == NULL) {
-        tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
-        if (tf == NULL) {
-            return NGX_ERROR;
-        }
-
-        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
-        tf->file.fd = NGX_INVALID_FILE;
-        tf->file.log = r->connection->log;
-        tf->path = clcf->client_body_temp_path;
-        tf->pool = r->pool;
-        tf->warn = "a client request body is buffered to a temporary file";
-        tf->log_level = r->request_body_file_log_level;
-        tf->persistent = r->request_body_in_persistent_file;
-        tf->clean = r->request_body_in_clean_file;
-
-        if (r->request_body_file_group_access) {
-            tf->access = 0660;
-        }
-
-        rb->temp_file = tf;
-
-        if (body == NULL) {
-            /* empty body with r->request_body_in_file_only */
-
-            if (ngx_create_temp_file(&tf->file, tf->path, tf->pool,
-                                     tf->persistent, tf->clean, tf->access)
-                != NGX_OK)
-            {
-                return NGX_ERROR;
-            }
-
-            return NGX_OK;
-        }
-    }
-
-    n = ngx_write_chain_to_temp_file(rb->temp_file, body);
-
-    /* TODO: n == 0 or not complete and level event */
-
-    if (n == NGX_ERROR) {
-        return NGX_ERROR;
-    }
-
-    rb->temp_file->offset += n;
-
-    return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_discard_request_body(ngx_http_request_t *r)
-{
-    ssize_t       size;
-    ngx_event_t  *rev;
-
-    if (r != r->main || r->discard_body) {
-        return NGX_OK;
-    }
-
-    if (ngx_http_test_expect(r) != NGX_OK) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
-    }
-
-    rev = r->connection->read;
-
-    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http set discard body");
-
-    if (rev->timer_set) {
-        ngx_del_timer(rev);
-    }
-
-    if (r->headers_in.content_length_n <= 0 || r->request_body) {
-        return NGX_OK;
-    }
-
-    size = r->header_in->last - r->header_in->pos;
-
-    if (size) {
-        if (r->headers_in.content_length_n > size) {
-            r->header_in->pos += size;
-            r->headers_in.content_length_n -= size;
-
-        } else {
-            r->header_in->pos += (size_t) r->headers_in.content_length_n;
-            r->headers_in.content_length_n = 0;
-            return NGX_OK;
-        }
-    }
-
-    if (ngx_http_read_discarded_request_body(r) == NGX_OK) {
-        r->lingering_close = 0;
-        return NGX_OK;
-    }
-
-    /* == NGX_AGAIN */
-
-    r->read_event_handler = ngx_http_discarded_request_body_handler;
-
-    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
-    }
-
-    r->count++;
-    r->discard_body = 1;
-
-    return NGX_OK;
-}
-
-
-void
-ngx_http_discarded_request_body_handler(ngx_http_request_t *r)
-{
-    ngx_int_t                  rc;
-    ngx_msec_t                 timer;
-    ngx_event_t               *rev;
-    ngx_connection_t          *c;
-    ngx_http_core_loc_conf_t  *clcf;
-
-    c = r->connection;
-    rev = c->read;
-
-    if (rev->timedout) {
-        c->timedout = 1;
-        c->error = 1;
-        ngx_http_finalize_request(r, NGX_ERROR);
-        return;
-    }
-
-    if (r->lingering_time) {
-        timer = (ngx_msec_t) (r->lingering_time - ngx_time());
-
-        if (timer <= 0) {
-            r->discard_body = 0;
-            r->lingering_close = 0;
-            ngx_http_finalize_request(r, NGX_ERROR);
-            return;
-        }
-
-    } else {
-        timer = 0;
-    }
-
-    rc = ngx_http_read_discarded_request_body(r);
-
-    if (rc == NGX_OK) {
-        r->discard_body = 0;
-        r->lingering_close = 0;
-        ngx_http_finalize_request(r, NGX_DONE);
-        return;
-    }
-
-    /* rc == NGX_AGAIN */
-
-    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
-        c->error = 1;
-        ngx_http_finalize_request(r, NGX_ERROR);
-        return;
-    }
-
-    if (timer) {
-
-        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
-        timer *= 1000;
-
-        if (timer > clcf->lingering_timeout) {
-            timer = clcf->lingering_timeout;
-        }
-
-        ngx_add_timer(rev, timer);
-    }
-}
-
-
-static ngx_int_t
-ngx_http_read_discarded_request_body(ngx_http_request_t *r)
-{
-    size_t   size;
-    ssize_t  n;
-    u_char   buffer[NGX_HTTP_DISCARD_BUFFER_SIZE];
-
-    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http read discarded body");
-
-    for ( ;; ) {
-        if (r->headers_in.content_length_n == 0) {
-            r->read_event_handler = ngx_http_block_reading;
-            return NGX_OK;
-        }
-
-        if (!r->connection->read->ready) {
-            return NGX_AGAIN;
-        }
-
-        size = (r->headers_in.content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
-                   NGX_HTTP_DISCARD_BUFFER_SIZE:
-                   (size_t) r->headers_in.content_length_n;
-
-        n = r->connection->recv(r->connection, buffer, size);
-
-        if (n == NGX_ERROR) {
-            r->connection->error = 1;
-            return NGX_OK;
-        }
-
-        if (n == NGX_AGAIN) {
-            return NGX_AGAIN;
-        }
-
-        if (n == 0) {
-            return NGX_OK;
-        }
-
-        r->headers_in.content_length_n -= n;
-    }
-}
-
-
-static ngx_int_t
-ngx_http_test_expect(ngx_http_request_t *r)
-{
-    ngx_int_t   n;
-    ngx_str_t  *expect;
-
-    if (r->expect_tested
-        || r->headers_in.expect == NULL
-        || r->http_version < NGX_HTTP_VERSION_11)
-    {
-        return NGX_OK;
-    }
-
-    r->expect_tested = 1;
-
-    expect = &r->headers_in.expect->value;
-
-    if (expect->len != sizeof("100-continue") - 1
-        || ngx_strncasecmp(expect->data, (u_char *) "100-continue",
-                           sizeof("100-continue") - 1)
-           != 0)
-    {
-        return NGX_OK;
-    }
-
-    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "send 100 Continue");
-
-    n = r->connection->send(r->connection,
-                            (u_char *) "HTTP/1.1 100 Continue" CRLF CRLF,
-                            sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1);
-
-    if (n == sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1) {
-        return NGX_OK;
-    }
-
-    /* we assume that such small packet should be send successfully */
-
-    return NGX_ERROR;
-}

  Renamed: vendor/nginx-1.4.2/CHANGES (+296 -35) 95%
===================================================================
--- vendor/nginx-1.2.6/CHANGES    2013-07-22 11:05:55 +0900 (ca47aee)
+++ vendor/nginx-1.4.2/CHANGES    2013-07-22 13:32:39 +0900 (bbc3eb9)
@@ -1,5 +1,228 @@
 
-Changes with nginx 1.2.6                                         11 Dec 2012
+Changes with nginx 1.4.2                                         17 Jul 2013
+
+    *) 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: 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: the "fail_timeout" parameter of the "server" directive in the
+       "upstream" context might not work if "max_fails" parameter was used;
+       the bug had appeared in 1.3.0.
+
+    *) Bugfix: a segmentation fault might occur in a worker process if the
+       "ssl_stapling" directive was used.
+       Thanks to Piotr Sikora.
+
+    *) Bugfix: nginx/Windows might stop accepting connections if several
+       worker processes were used.
+
+
+Changes with nginx 1.4.1                                         07 May 2013
+
+    *) Security: a stack-based buffer overflow might occur in a worker
+       process while handling a specially crafted request, potentially
+       resulting in arbitrary code execution (CVE-2013-2028); the bug had
+       appeared in 1.3.9.
+       Thanks to Greg MacManus, iSIGHT Partners Labs.
+
+
+Changes with nginx 1.4.0                                         24 Apr 2013
+
+    *) Bugfix: nginx could not be built with the ngx_http_perl_module if the
+       --with-openssl option was used; the bug had appeared in 1.3.16.
+
+    *) Bugfix: in a request body handling in the ngx_http_perl_module; the
+       bug had appeared in 1.3.9.
+
+
+Changes with nginx 1.3.16                                        16 Apr 2013
+
+    *) Bugfix: a segmentation fault might occur in a worker process if
+       subrequests were used; the bug had appeared in 1.3.9.
+
+    *) Bugfix: the "tcp_nodelay" directive caused an error if a WebSocket
+       connection was proxied into a unix domain socket.
+
+    *) Bugfix: the $upstream_response_length variable has an incorrect value
+       "0" if buffering was not used.
+       Thanks to Piotr Sikora.
+
+    *) Bugfix: in the eventport and /dev/poll methods.
+
+
+Changes with nginx 1.3.15                                        26 Mar 2013
+
+    *) Change: opening and closing a connection without sending any data in
+       it is no longer logged to access_log with error code 400.
+
+    *) Feature: the ngx_http_spdy_module.
+       Thanks to Automattic for sponsoring this work.
+
+    *) Feature: the "limit_req_status" and "limit_conn_status" directives.
+       Thanks to Nick Marden.
+
+    *) Feature: the "image_filter_interlace" directive.
+       Thanks to Ian Babrou.
+
+    *) Feature: $connections_waiting variable in the
+       ngx_http_stub_status_module.
+
+    *) Feature: the mail proxy module now supports IPv6 backends.
+
+    *) Bugfix: request body might be transmitted incorrectly when retrying a
+       request to the next upstream server; the bug had appeared in 1.3.9.
+       Thanks to Piotr Sikora.
+
+    *) Bugfix: in the "client_body_in_file_only" directive; the bug had
+       appeared in 1.3.9.
+
+    *) Bugfix: responses might hang if subrequests were used and a DNS error
+       happened during subrequest processing.
+       Thanks to Lanshun Zhou.
+
+    *) Bugfix: in backend usage accounting.
+
+
+Changes with nginx 1.3.14                                        05 Mar 2013
+
+    *) Feature: $connections_active, $connections_reading, and
+       $connections_writing variables in the ngx_http_stub_status_module.
+
+    *) Feature: support of WebSocket connections in the
+       ngx_http_uwsgi_module and ngx_http_scgi_module.
+
+    *) Bugfix: in virtual servers handling with SNI.
+
+    *) Bugfix: new sessions were not always stored if the "ssl_session_cache
+       shared" directive was used and there was no free space in shared
+       memory.
+       Thanks to Piotr Sikora.
+
+    *) Bugfix: multiple X-Forwarded-For headers were handled incorrectly.
+       Thanks to Neal Poole for sponsoring this work.
+
+    *) Bugfix: in the ngx_http_mp4_module.
+       Thanks to Gernot Vormayr.
+
+
+Changes with nginx 1.3.13                                        19 Feb 2013
+
+    *) Change: a compiler with name "cc" is now used by default.
+
+    *) Feature: support for proxying of WebSocket connections.
+       Thanks to Apcera and CloudBees for sponsoring this work.
+
+    *) Feature: the "auth_basic_user_file" directive supports "{SHA}"
+       password encryption method.
+       Thanks to Louis Opter.
+
+
+Changes with nginx 1.3.12                                        05 Feb 2013
+
+    *) Feature: variables support in the "proxy_bind", "fastcgi_bind",
+       "memcached_bind", "scgi_bind", and "uwsgi_bind" directives.
+
+    *) Feature: the $pipe, $request_length, $time_iso8601, and $time_local
+       variables can now be used not only in the "log_format" directive.
+       Thanks to Kiril Kalchev.
+
+    *) Feature: IPv6 support in the ngx_http_geoip_module.
+       Thanks to Gregor Kališnik.
+
+    *) Bugfix: in the "proxy_method" directive.
+
+    *) Bugfix: a segmentation fault might occur in a worker process if
+       resolver was used with the poll method.
+
+    *) Bugfix: nginx might hog CPU during SSL handshake with a backend if
+       the select, poll, or /dev/poll methods were used.
+
+    *) Bugfix: the "[crit] SSL_write() failed (SSL:)" error.
+
+    *) Bugfix: in the "client_body_in_file_only" directive; the bug had
+       appeared in 1.3.9.
+
+    *) Bugfix: in the "fastcgi_keep_conn" directive.
+
+
+Changes with nginx 1.3.11                                        10 Jan 2013
+
+    *) Bugfix: a segmentation fault might occur if logging was used; the bug
+       had appeared in 1.3.10.
+
+    *) Bugfix: the "proxy_pass" directive did not work with IP addresses
+       without port specified; the bug had appeared in 1.3.10.
+
+    *) Bugfix: a segmentation fault occurred on start or during
+       reconfiguration if the "keepalive" directive was specified more than
+       once in a single upstream block.
+
+    *) Bugfix: parameter "default" of the "geo" directive did not set
+       default value for IPv6 addresses.
+
+
+Changes with nginx 1.3.10                                        25 Dec 2012
+
+    *) Change: domain names specified in configuration file are now resolved
+       to IPv6 addresses as well as IPv4 ones.
+
+    *) Change: now if the "include" directive with mask is used on Unix
+       systems, included files are sorted in alphabetical order.
+
+    *) Change: the "add_header" directive adds headers to 201 responses.
+
+    *) Feature: the "geo" directive now supports IPv6 addresses in CIDR
+       notation.
+
+    *) Feature: the "flush" and "gzip" parameters of the "access_log"
+       directive.
+
+    *) Feature: variables support in the "auth_basic" directive.
+
+    *) Bugfix: nginx could not be built with the ngx_http_perl_module in
+       some cases.
+
+    *) Bugfix: a segmentation fault might occur in a worker process if the
+       ngx_http_xslt_module was used.
+
+    *) Bugfix: nginx could not be built on MacOSX in some cases.
+       Thanks to Piotr Sikora.
+
+    *) Bugfix: the "limit_rate" directive with high rates might result in
+       truncated responses on 32-bit platforms.
+       Thanks to Alexey Antropov.
+
+    *) Bugfix: a segmentation fault might occur in a worker process if the
+       "if" directive was used.
+       Thanks to Piotr Sikora.
+
+    *) Bugfix: a "100 Continue" response was issued with "413 Request Entity
+       Too Large" responses.
+
+    *) Bugfix: the "image_filter", "image_filter_jpeg_quality" and
+       "image_filter_sharpen" directives might be inherited incorrectly.
+       Thanks to Ian Babrou.
+
+    *) Bugfix: "crypt_r() failed" errors might appear if the "auth_basic"
+       directive was used on Linux.
+
+    *) Bugfix: in backup servers handling.
+       Thanks to Thomas Chen.
+
+    *) Bugfix: proxied HEAD requests might return incorrect response if the
+       "gzip" directive was used.
+
+
+Changes with nginx 1.3.9                                         27 Nov 2012
+
+    *) Feature: support for chunked transfer encoding while reading client
+       request body.
 
     *) Feature: the $request_time and $msec variables can now be used not
        only in the "log_format" directive.
@@ -10,7 +233,7 @@ Changes with nginx 1.2.6                                         11 Dec 2012
     *) Bugfix: in the ngx_http_dav_module.
 
 
-Changes with nginx 1.2.5                                         13 Nov 2012
+Changes with nginx 1.3.8                                         30 Oct 2012
 
     *) Feature: the "optional_no_ca" parameter of the "ssl_verify_client"
        directive.
@@ -20,17 +243,35 @@ Changes with nginx 1.2.5                                         13 Nov 2012
        variables can now be used not only in the "log_format" directive.
        Thanks to Benjamin Grössing.
 
-    *) Feature: resolver now randomly rotates addresses returned from cache.
-       Thanks to Anton Jouline.
-
     *) Feature: the "auto" parameter of the "worker_processes" directive.
 
     *) Bugfix: "cache file ... has md5 collision" alert.
 
+    *) Bugfix: in the ngx_http_gunzip_filter_module.
+
+    *) Bugfix: in the "ssl_stapling" directive.
+
+
+Changes with nginx 1.3.7                                         02 Oct 2012
+
+    *) Feature: OCSP stapling support.
+       Thanks to Comodo, DigiCert and GlobalSign for sponsoring this work.
+
+    *) Feature: the "ssl_trusted_certificate" directive.
+
+    *) Feature: resolver now randomly rotates addresses returned from cache.
+       Thanks to Anton Jouline.
+
     *) Bugfix: OpenSSL 0.9.7 compatibility.
 
 
-Changes with nginx 1.2.4                                         25 Sep 2012
+Changes with nginx 1.3.6                                         12 Sep 2012
+
+    *) Feature: the ngx_http_gunzip_filter_module.
+
+    *) Feature: the "memcached_gzip_flag" directive.
+
+    *) Feature: the "always" parameter of the "gzip_static" directive.
 
     *) Bugfix: in the "limit_req" directive; the bug had appeared in 1.1.14.
        Thanks to Charles Chen.
@@ -38,6 +279,12 @@ Changes with nginx 1.2.4                                         25 Sep 2012
     *) Bugfix: nginx could not be built by gcc 4.7 with -O2 optimization if
        the --with-ipv6 option was used.
 
+
+Changes with nginx 1.3.5                                         21 Aug 2012
+
+    *) Change: the ngx_http_mp4_module module no longer skips tracks in
+       formats other than H.264 and AAC.
+
     *) Bugfix: a segmentation fault might occur in a worker process if the
        "map" directive was used with variables as values.
 
@@ -58,7 +305,10 @@ Changes with nginx 1.2.4                                         25 Sep 2012
        Thanks to HAYASHI Kentaro.
 
 
-Changes with nginx 1.2.3                                         07 Aug 2012
+Changes with nginx 1.3.4                                         31 Jul 2012
+
+    *) Change: the "ipv6only" parameter is now turned on by default for
+       listening IPv6 sockets.
 
     *) Feature: the Clang compiler support.
 
@@ -74,6 +324,11 @@ Changes with nginx 1.2.3                                         07 Aug 2012
        "fastcgi_hide_header", "scgi_hide_header", and "uwsgi_hide_header"
        directives might be inherited incorrectly.
 
+
+Changes with nginx 1.3.3                                         10 Jul 2012
+
+    *) Feature: entity tags support and the "etag" directive.
+
     *) Bugfix: trailing dot in a source value was not ignored if the "map"
        directive was used with the "hostnames" parameter.
 
@@ -82,7 +337,7 @@ Changes with nginx 1.2.3                                         07 Aug 2012
        to a named location.
 
 
-Changes with nginx 1.2.2                                         03 Jul 2012
+Changes with nginx 1.3.2                                         26 Jun 2012
 
     *) Change: the "single" parameter of the "keepalive" directive is now
        ignored.
@@ -90,6 +345,36 @@ Changes with nginx 1.2.2                                         03 Jul 2012
     *) Change: SSL compression is now disabled when using all versions of
        OpenSSL, including ones prior to 1.0.0.
 
+    *) Feature: it is now possible to use the "ip_hash" directive to balance
+       IPv6 clients.
+
+    *) Feature: the $status variable can now be used not only in the
+       "log_format" directive.
+
+    *) Bugfix: a segmentation fault might occur in a worker process on
+       shutdown if the "resolver" directive was used.
+
+    *) Bugfix: a segmentation fault might occur in a worker process if the
+       ngx_http_mp4_module was used.
+
+    *) Bugfix: in the ngx_http_mp4_module.
+
+    *) Bugfix: a segmentation fault might occur in a worker process if
+       conflicting wildcard server names were used.
+
+    *) Bugfix: nginx might be terminated abnormally on a SIGBUS signal on
+       ARM platform.
+
+    *) Bugfix: an alert "sendmsg() failed (9: Bad file number)" on HP-UX
+       while reconfiguration.
+
+
+Changes with nginx 1.3.1                                         05 Jun 2012
+
+    *) Security: now nginx/Windows ignores trailing dot in URI path
+       component, and does not allow URIs with ":$" in it.
+       Thanks to Vladimir Kochetkov, Positive Research Center.
+
     *) Feature: the "proxy_pass", "fastcgi_pass", "scgi_pass", "uwsgi_pass"
        directives, and the "server" directive inside the "upstream" block,
        now support IPv6 addresses.
@@ -102,11 +387,8 @@ Changes with nginx 1.2.2                                         03 Jul 2012
     *) Feature: it is now possible to specify a weight for servers while
        using the "ip_hash" directive.
 
-    *) Feature: it is now possible to use the "ip_hash" directive to balance
-       IPv6 clients.
-
-    *) Feature: the $status variable can now be used not only in the
-       "log_format" directive.
+    *) Bugfix: a segmentation fault might occur in a worker process if the
+       "image_filter" directive was used; the bug had appeared in 1.3.0.
 
     *) Bugfix: nginx could not be built with ngx_cpp_test_module; the bug
        had appeared in 1.1.12.
@@ -124,29 +406,8 @@ Changes with nginx 1.2.2                                         03 Jul 2012
     *) Bugfix: in the "proxy_cookie_domain" and "proxy_cookie_path"
        directives.
 
-    *) Bugfix: a segmentation fault might occur in a worker process on
-       shutdown if the "resolver" directive was used.
-
-    *) Bugfix: a segmentation fault might occur in a worker process if the
-       ngx_http_mp4_module was used.
-
-    *) Bugfix: in the ngx_http_mp4_module.
-
-    *) Bugfix: a segmentation fault might occur in a worker process if
-       conflicting wildcard server names were used.
-
-    *) Bugfix: nginx might be terminated abnormally on a SIGBUS signal on
-       ARM platform.
-
-    *) Bugfix: an alert "sendmsg() failed (9: Bad file number)" on HP-UX
-       while reconfiguration.
 
-
-Changes with nginx 1.2.1                                         05 Jun 2012
-
-    *) Security: now nginx/Windows ignores trailing dot in URI path
-       component, and does not allow URIs with ":$" in it.
-       Thanks to Vladimir Kochetkov, Positive Research Center.
+Changes with nginx 1.3.0                                         15 May 2012
 
     *) Feature: the "debug_connection" directive now supports IPv6 addresses
        and the "unix:" parameter.

  Renamed: vendor/nginx-1.4.2/CHANGES.ru (+303 -35) 95%
===================================================================
--- vendor/nginx-1.2.6/CHANGES.ru    2013-07-22 11:05:55 +0900 (d6c774e)
+++ vendor/nginx-1.4.2/CHANGES.ru    2013-07-22 13:32:39 +0900 (18f1371)
@@ -1,5 +1,235 @@
 
-Изменения в nginx 1.2.6                                           11.12.2012
+Изменения в nginx 1.4.2                                           17.07.2013
+
+    *) Исправление: метод $r->header_in() встроенного перла не возвращал
+       значения строк "Cookie" и "X-Forwarded-For" из заголовка запроса;
+       ошибка появилась в 1.3.14.
+
+    *) Исправление: nginx не собирался с модулем ngx_mail_ssl_module, но без
+       модуля ngx_http_ssl_module; ошибка появилась в 1.3.14.
+
+    *) Исправление: в директиве proxy_set_body.
+       Спасибо Lanshun Zhou.
+
+    *) Исправление: параметр fail_timeout директивы server в блоке upstream
+       мог не работать, если использовался параметр max_fails; ошибка
+       появилась в 1.3.0.
+
+    *) Исправление: в рабочем процессе мог произойти segmentation fault,
+       если использовалась директива ssl_stapling.
+       Спасибо Piotr Sikora.
+
+    *) Исправление: nginx/Windows мог перестать принимать соединения, если
+       использовалось несколько рабочих процессов.
+
+
+Изменения в nginx 1.4.1                                           07.05.2013
+
+    *) Безопасность: при обработке специально созданного запроса мог
+       перезаписываться стек рабочего процесса, что могло приводить к
+       выполнению произвольного кода (CVE-2013-2028); ошибка появилась в
+       1.3.9.
+       Спасибо Greg MacManus, iSIGHT Partners Labs.
+
+
+Изменения в nginx 1.4.0                                           24.04.2013
+
+    *) Исправление: nginx не собирался с модулем ngx_http_perl_module, если
+       использовался параметр --with-openssl; ошибка появилась в 1.3.16.
+
+    *) Исправление: в работе с телом запроса из модуля ngx_http_perl_module;
+       ошибка появилась в 1.3.9.
+
+
+Изменения в nginx 1.3.16                                          16.04.2013
+
+    *) Исправление: в рабочем процессе мог произойти segmentation fault,
+       если использовались подзапросы; ошибка появилась в 1.3.9.
+
+    *) Исправление: директива tcp_nodelay вызывала ошибку при проксировании
+       WebSocket-соединений в unix domain сокет.
+
+    *) Исправление: переменная $upstream_response_length возвращала значение
+       "0", если не использовалась буферизация.
+       Спасибо Piotr Sikora.
+
+    *) Исправление: в методах обработки соединений eventport и /dev/poll.
+
+
+Изменения в nginx 1.3.15                                          26.03.2013
+
+    *) Изменение: открытие и закрытие соединения без отправки в нём
+       каких-либо данных больше не записывается в access_log с кодом ошибки
+       400.
+
+    *) Добавление: модуль ngx_http_spdy_module.
+       Спасибо Automattic за спонсирование разработки.
+
+    *) Добавление: директивы limit_req_status и limit_conn_status.
+       Спасибо Nick Marden.
+
+    *) Добавление: директива image_filter_interlace.
+       Спасибо Ивану Боброву.
+
+    *) Добавление: переменная $connections_waiting в модуле
+       ngx_http_stub_status_module.
+
+    *) Добавление: теперь почтовый прокси-сервер поддерживает IPv6-бэкенды.
+
+    *) Исправление: при повторной отправке запроса на бэкенд тело запроса
+       могло передаваться неправильно; ошибка появилась в 1.3.9.
+       Спасибо Piotr Sikora.
+
+    *) Исправление: в директиве client_body_in_file_only; ошибка появилась в
+       1.3.9.
+
+    *) Исправление: ответы могли зависать, если использовались подзапросы и
+       при обработке подзапроса происходила DNS-ошибка.
+       Спасибо Lanshun Zhou.
+
+    *) Исправление: в процедуре учёта использования бэкендов.
+
+
+Изменения в nginx 1.3.14                                          05.03.2013
+
+    *) Добавление: переменные $connections_active, $connections_reading и
+       $connections_writing в модуле ngx_http_stub_status_module.
+
+    *) Добавление: поддержка WebSocket-соединений в модулях
+       ngx_http_uwsgi_module и ngx_http_scgi_module.
+
+    *) Исправление: в обработке виртуальных серверов при использовании SNI.
+
+    *) Исправление: при использовании директивы "ssl_session_cache shared"
+       новые сессии могли не сохраняться, если заканчивалось место в
+       разделяемой памяти.
+       Спасибо Piotr Sikora.
+
+    *) Исправление: несколько заголовков X-Forwarded-For обрабатывались
+       неправильно.
+       Спасибо Neal Poole за спонсирование разработки.
+
+    *) Исправление: в модуле ngx_http_mp4_module.
+       Спасибо Gernot Vormayr.
+
+
+Изменения в nginx 1.3.13                                          19.02.2013
+
+    *) Изменение: теперь для сборки по умолчанию используется компилятор с
+       именем "cc".
+
+    *) Добавление: поддержка проксирования WebSocket-соединений.
+       Спасибо Apcera и CloudBees за спонсирование разработки.
+
+    *) Добавление: директива auth_basic_user_file поддерживает шифрование
+       паролей методом "{SHA}".
+       Спасибо Louis Opter.
+
+
+Изменения в nginx 1.3.12                                          05.02.2013
+
+    *) Добавление: директивы proxy_bind, fastcgi_bind, memcached_bind,
+       scgi_bind и uwsgi_bind поддерживают переменные.
+
+    *) Добавление: переменные $pipe, $request_length, $time_iso8601 и
+       $time_local теперь можно использовать не только в директиве
+       log_format.
+       Спасибо Kiril Kalchev.
+
+    *) Добавление: поддержка IPv6 в модуле ngx_http_geoip_module.
+       Спасибо Gregor Kališnik.
+
+    *) Исправление: директива proxy_method работала неверно, если была
+       указана на уровне http.
+
+    *) Исправление: в рабочем процессе мог произойти segmentation fault,
+       если использовался resolver и метод poll.
+
+    *) Исправление: nginx мог нагружать процессор во время SSL handshake с
+       бэкендом при использовании методов обработки соединений select, poll
+       и /dev/poll.
+
+    *) Исправление: ошибка "[crit] SSL_write() failed (SSL:)".
+
+    *) Исправление: в директиве client_body_in_file_only; ошибка появилась в
+       1.3.9.
+
+    *) Исправление: в директиве fastcgi_keep_conn.
+
+
+Изменения в nginx 1.3.11                                          10.01.2013
+
+    *) Исправление: при записи в лог мог происходить segmentation fault;
+       ошибка появилась в 1.3.10.
+
+    *) Исправление: директива proxy_pass не работала с IP-адресами без
+       явного указания порта; ошибка появилась в 1.3.10.
+
+    *) Исправление: на старте или во время переконфигурации происходил
+       segmentation fault, если директива keepalive была указана несколько
+       раз в одном блоке upstream.
+
+    *) Исправление: параметр default директивы geo не определял значение по
+       умолчанию для IPv6-адресов.
+
+
+Изменения в nginx 1.3.10                                          25.12.2012
+
+    *) Изменение: для указанных в конфигурационном файле доменных имён
+       теперь используются не только IPv4, но и IPv6 адреса.
+
+    *) Изменение: теперь при использовании директивы include с маской на
+       Unix-системах включаемые файлы сортируются в алфавитном порядке.
+
+    *) Изменение: директива add_header добавляет строки в ответы с кодом
+       201.
+
+    *) Добавление: директива geo теперь поддерживает IPv6 адреса в формате
+       CIDR.
+
+    *) Добавление: параметры flush и gzip в директиве access_log.
+
+    *) Добавление: директива auth_basic поддерживает переменные.
+
+    *) Исправление: nginx в некоторых случаях не собирался с модулем
+       ngx_http_perl_module.
+
+    *) Исправление: в рабочем процессе мог произойти segmentation fault,
+       если использовался модуль ngx_http_xslt_module.
+
+    *) Исправление: nginx мог не собираться на MacOSX.
+       Спасибо Piotr Sikora.
+
+    *) Исправление: при использовании директивы limit_rate с большими
+       значениями скорости на 32-битных системах ответ мог возвращаться не
+       целиком.
+       Спасибо Алексею Антропову.
+
+    *) Исправление: в рабочем процессе мог произойти segmentation fault,
+       если использовалась директива if.
+       Спасибо Piotr Sikora.
+
+    *) Исправление: ответ "100 Continue" выдавался вместе с ответом "413
+       Request Entity Too Large".
+
+    *) Исправление: директивы image_filter, image_filter_jpeg_quality и
+       image_filter_sharpen могли наследоваться некорректно.
+       Спасибо Ивану Боброву.
+
+    *) Исправление: при использовании директивы auth_basic под Linux могли
+       возникать ошибки "crypt_r() failed".
+
+    *) Исправление: в обработке backup-серверов.
+       Спасибо Thomas Chen.
+
+    *) Исправление: при проксировании HEAD-запросов мог возвращаться
+       некорректный ответ, если использовалась директива gzip.
+
+
+Изменения в nginx 1.3.9                                           27.11.2012
+
+    *) Добавление: поддержка chunked transfer encoding при получении тела
+       запроса.
 
     *) Добавление: переменные $request_time и $msec теперь можно
        использовать не только в директиве log_format.
@@ -10,7 +240,7 @@
     *) Исправление: в модуле ngx_http_dav_module.
 
 
-Изменения в nginx 1.2.5                                           13.11.2012
+Изменения в nginx 1.3.8                                           30.10.2012
 
     *) Добавление: параметр optional_no_ca директивы ssl_verify_client.
        Спасибо Михаилу Казанцеву и Eric O'Connor.
@@ -20,18 +250,36 @@
        log_format.
        Спасибо Benjamin Grössing.
 
+    *) Добавление: параметр auto директивы worker_processes.
+
+    *) Исправление: сообщения "cache file ... has md5 collision".
+
+    *) Исправление: в модуле ngx_http_gunzip_filter_module.
+
+    *) Исправление: в директиве ssl_stapling.
+
+
+Изменения в nginx 1.3.7                                           02.10.2012
+
+    *) Добавление: поддержка OCSP stapling.
+       Спасибо Comodo, DigiCert и GlobalSign за спонсирование разработки.
+
+    *) Добавление: директива ssl_trusted_certificate.
+
     *) Добавление: теперь resolver случайным образом меняет порядок
        возвращаемых закэшированных адресов.
        Спасибо Антону Жулину.
 
-    *) Добавление: параметр auto директивы worker_processes.
+    *) Исправление: совместимость с OpenSSL 0.9.7.
 
-    *) Исправление: сообщения "cache file ... has md5 collision".
 
-    *) Исправление: совместимость с OpenSSL 0.9.7.
+Изменения в nginx 1.3.6                                           12.09.2012
 
+    *) Добавление: модуль ngx_http_gunzip_filter_module.
 
-Изменения в nginx 1.2.4                                           25.09.2012
+    *) Добавление: директива memcached_gzip_flag.
+
+    *) Добавление: параметр always директивы gzip_static.
 
     *) Исправление: в директиве "limit_req"; ошибка появилась в 1.1.14.
        Спасибо Charles Chen.
@@ -39,6 +287,12 @@
     *) Исправление: nginx не собирался gcc 4.7 с оптимизацией -O2 если
        использовался параметр --with-ipv6.
 
+
+Изменения в nginx 1.3.5                                           21.08.2012
+
+    *) Изменение: модуль ngx_http_mp4_module больше не отфильтровывает
+       дорожки в форматах, отличных от H.264 и AAC.
+
     *) Исправление: в рабочем процессе мог произойти segmentation fault,
        если в директиве map в качестве значений использовались переменные.
 
@@ -58,7 +312,10 @@
        Спасибо HAYASHI Kentaro.
 
 
-Изменения в nginx 1.2.3                                           07.08.2012
+Изменения в nginx 1.3.4                                           31.07.2012
+
+    *) Изменение: теперь на слушающих IPv6-сокетах параметр ipv6only включён
+       по умолчанию.
 
     *) Добавление: поддержка компилятора Clang.
 
@@ -74,6 +331,11 @@
        fastcgi_hide_header, scgi_hide_header и uwsgi_hide_header могли
        наследоваться некорректно.
 
+
+Изменения в nginx 1.3.3                                           10.07.2012
+
+    *) Добавление: поддержка entity tags и директива etag.
+
     *) Исправление: при использовании директивы map с параметром hostnames
        не игнорировалась конечная точка в исходном значении.
 
@@ -82,45 +344,19 @@
        изменения URI с помощью директивы rewrite.
 
 
-Изменения в nginx 1.2.2                                           03.07.2012
+Изменения в nginx 1.3.2                                           26.06.2012
 
     *) Изменение: параметр single директивы keepalive теперь игнорируется.
 
     *) Изменение: сжатие SSL теперь отключено в том числе при использовании
        OpenSSL cтарее 1.0.0.
 
-    *) Добавление: директивы proxy_pass, fastcgi_pass, scgi_pass, uwsgi_pass
-       и директива server в блоке upstream теперь поддерживают IPv6-адреса.
-
-    *) Добавление: в директиве resolver теперь можно указывать порт и
-       задавать IPv6-адреса DNS-серверов.
-
-    *) Добавление: директива least_conn в блоке upstream.
-
-    *) Добавление: при использовании директивы ip_hash теперь можно задавать
-       веса серверов.
-
     *) Добавление: директиву "ip_hash" теперь можно использовать для
        балансировки IPv6 клиентов.
 
     *) Добавление: переменную $status теперь можно использовать не только в
        директиве log_format.
 
-    *) Исправление: nginx не собирался с модулем ngx_cpp_test_module; ошибка
-       появилась в 1.1.12.
-
-    *) Исправление: доступ к переменным из SSI и встроенного перла мог не
-       работать после переконфигурации.
-       Спасибо Yichun Zhang.
-
-    *) Исправление: в модуле ngx_http_xslt_filter_module.
-       Спасибо Kuramoto Eiji.
-
-    *) Исправление: утечки памяти при использовании переменной $geoip_org.
-       Спасибо Денису Латыпову.
-
-    *) Исправление: в директивах proxy_cookie_domain и proxy_cookie_path.
-
     *) Исправление: при завершении рабочего процесса мог произойти
        segmentation fault, если использовалась директива resolver.
 
@@ -139,13 +375,45 @@
        alert "sendmsg() failed (9: Bad file number)".
 
 
-Изменения в nginx 1.2.1                                           05.06.2012
+Изменения в nginx 1.3.1                                           05.06.2012
 
     *) Безопасность: теперь nginx/Windows игнорирует точку в конце
        компонента URI и не разрешает URI, содержащие последовательность
        ":$".
        Спасибо Владимиру Кочеткову, Positive Research Center.
 
+    *) Добавление: директивы proxy_pass, fastcgi_pass, scgi_pass, uwsgi_pass
+       и директива server в блоке upstream теперь поддерживают IPv6-адреса.
+
+    *) Добавление: в директиве resolver теперь можно указывать порт и
+       задавать IPv6-адреса DNS-серверов.
+
+    *) Добавление: директива least_conn в блоке upstream.
+
+    *) Добавление: при использовании директивы ip_hash теперь можно задавать
+       веса серверов.
+
+    *) Исправление: в рабочем процессе мог произойти segmentation fault,
+       если использовалась директива image_filter; ошибка появилась в 1.3.0.
+
+    *) Исправление: nginx не собирался с модулем ngx_cpp_test_module; ошибка
+       появилась в 1.1.12.
+
+    *) Исправление: доступ к переменным из SSI и встроенного перла мог не
+       работать после переконфигурации.
+       Спасибо Yichun Zhang.
+
+    *) Исправление: в модуле ngx_http_xslt_filter_module.
+       Спасибо Kuramoto Eiji.
+
+    *) Исправление: утечки памяти при использовании переменной $geoip_org.
+       Спасибо Денису Латыпову.
+
+    *) Исправление: в директивах proxy_cookie_domain и proxy_cookie_path.
+
+
+Изменения в nginx 1.3.0                                           15.05.2012
+
     *) Добавление: директива debug_connection теперь поддерживает
        IPv6-адреса и параметр "unix:".
 

  Renamed: vendor/nginx-1.4.2/LICENSE (+2 -2) 94%
===================================================================
--- vendor/nginx-1.2.6/LICENSE    2013-07-22 11:05:55 +0900 (c78be7e)
+++ vendor/nginx-1.4.2/LICENSE    2013-07-22 13:32:39 +0900 (5d80970)
@@ -1,6 +1,6 @@
 /* 
- * Copyright (C) 2002-2012 Igor Sysoev
- * Copyright (C) 2011,2012 Nginx, Inc.
+ * Copyright (C) 2002-2013 Igor Sysoev
+ * Copyright (C) 2011-2013 Nginx, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without

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

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

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

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

  Renamed: vendor/nginx-1.4.2/auto/cc/clang (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.4.2/auto/cc/conf (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.4.2/auto/cc/gcc (+0 -0) 100%
===================================================================

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

  Renamed: vendor/nginx-1.4.2/auto/cc/msvc (+0 -3) 99%
===================================================================
--- vendor/nginx-1.2.6/auto/cc/msvc    2013-07-22 11:05:55 +0900 (a99d5a9)
+++ vendor/nginx-1.4.2/auto/cc/msvc    2013-07-22 13:32:39 +0900 (1bf675e)
@@ -73,9 +73,6 @@ CFLAGS="$CFLAGS -WX"
 # disable logo
 CFLAGS="$CFLAGS -nologo"
 
-
-LINK="\$(CC)"
-
 # the link flags
 CORE_LINK="$CORE_LINK -link -verbose:lib"
 

  Renamed: vendor/nginx-1.4.2/auto/cc/name (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.4.2/auto/cc/owc (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.4.2/auto/cc/sunc (+0 -0) 100%
===================================================================

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

  Renamed: vendor/nginx-1.4.2/auto/endianness (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.4.2/auto/feature (+0 -0) 100%
===================================================================

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

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

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

  Renamed: vendor/nginx-1.4.2/auto/include (+0 -0) 100%
===================================================================

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

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

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

  Renamed: vendor/nginx-1.4.2/auto/lib/geoip/conf (+17 -2) 71%
===================================================================
--- vendor/nginx-1.2.6/auto/lib/geoip/conf    2013-07-22 11:05:55 +0900 (3764d76)
+++ vendor/nginx-1.4.2/auto/lib/geoip/conf    2013-07-22 13:32:39 +0900 (53c274d)
@@ -6,7 +6,7 @@
     ngx_feature="GeoIP library"
     ngx_feature_name=
     ngx_feature_run=no
-    ngx_feature_incs=
+    ngx_feature_incs="#include <GeoIP.h>"
     ngx_feature_path=
     ngx_feature_libs="-lGeoIP"
     ngx_feature_test="GeoIP_open(NULL, 0)"
@@ -18,6 +18,7 @@ if [ $ngx_found = no ]; then
     # FreeBSD port
 
     ngx_feature="GeoIP library in /usr/local/"
+    ngx_feature_path="/usr/local/include"
 
     if [ $NGX_RPATH = YES ]; then
         ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lGeoIP"
@@ -34,7 +35,7 @@ if [ $ngx_found = no ]; then
     # NetBSD port
 
     ngx_feature="GeoIP library in /usr/pkg/"
-    ngx_feature_path="/usr/pkg/include/"
+    ngx_feature_path="/usr/pkg/include"
 
     if [ $NGX_RPATH = YES ]; then
         ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lGeoIP"
@@ -64,8 +65,22 @@ fi
 
 
 if [ $ngx_found = yes ]; then
+
+    CORE_INCS="$CORE_INCS $ngx_feature_path"
     CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
 
+    if [ $NGX_IPV6 = YES ]; then
+        ngx_feature="GeoIP IPv6 support"
+        ngx_feature_name="NGX_HAVE_GEOIP_V6"
+        ngx_feature_run=no
+        ngx_feature_incs="#include <stdio.h>
+                          #include <GeoIP.h>"
+        #ngx_feature_path=
+        #ngx_feature_libs=
+        ngx_feature_test="printf(\"%d\", GEOIP_CITY_EDITION_REV0_V6);"
+        . auto/feature
+    fi
+
 else
 
 cat << END

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

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

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

  Renamed: vendor/nginx-1.4.2/auto/lib/libgd/conf (+1 -1) 97%
===================================================================
--- vendor/nginx-1.2.6/auto/lib/libgd/conf    2013-07-22 11:05:55 +0900 (b0bc74c)
+++ vendor/nginx-1.4.2/auto/lib/libgd/conf    2013-07-22 13:32:39 +0900 (ff99054)
@@ -35,7 +35,7 @@ if [ $ngx_found = no ]; then
     # NetBSD port
 
     ngx_feature="GD library in /usr/pkg/"
-    ngx_feature_path="/usr/pkg/include/"
+    ngx_feature_path="/usr/pkg/include"
 
     if [ $NGX_RPATH = YES ]; then
         ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lgd"

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

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

  Renamed: vendor/nginx-1.4.2/auto/lib/md5/conf (+3 -3) 93%
===================================================================
--- vendor/nginx-1.2.6/auto/lib/md5/conf    2013-07-22 11:05:55 +0900 (f9c1ed9)
+++ vendor/nginx-1.4.2/auto/lib/md5/conf    2013-07-22 13:32:39 +0900 (eb5dfd1)
@@ -52,7 +52,7 @@ else
 
             # FreeBSD, Solaris 10
 
-            ngx_feature="system md library"
+            ngx_feature="md5 in system md library"
             ngx_feature_name=NGX_HAVE_MD5
             ngx_feature_run=no
             ngx_feature_incs="#include <md5.h>"
@@ -67,7 +67,7 @@ else
 
             # Solaris 8/9
 
-            ngx_feature="system md5 library"
+            ngx_feature="md5 in system md5 library"
             ngx_feature_libs="-lmd5"
             . auto/feature
 
@@ -78,7 +78,7 @@ else
 
             # OpenSSL crypto library
 
-            ngx_feature="OpenSSL md5 crypto library"
+            ngx_feature="md5 in system OpenSSL crypto library"
             ngx_feature_name="NGX_OPENSSL_MD5"
             ngx_feature_incs="#include <openssl/md5.h>"
             ngx_feature_libs="-lcrypto"

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

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

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

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

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

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

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

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

  Renamed: vendor/nginx-1.4.2/auto/lib/pcre/conf (+1 -0) 99%
===================================================================
--- vendor/nginx-1.2.6/auto/lib/pcre/conf    2013-07-22 11:05:55 +0900 (6a8c326)
+++ vendor/nginx-1.4.2/auto/lib/pcre/conf    2013-07-22 13:32:39 +0900 (3458600)
@@ -172,6 +172,7 @@ else
             ngx_feature="PCRE JIT support"
             ngx_feature_name="NGX_HAVE_PCRE_JIT"
             ngx_feature_test="int jit = 0;
+                              pcre_free_study(NULL);
                               pcre_config(PCRE_CONFIG_JIT, &jit);
                               if (jit != 1) return 1;"
             . auto/feature

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

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

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

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

  Renamed: vendor/nginx-1.4.2/auto/lib/perl/conf (+3 -1) 94%
===================================================================
--- vendor/nginx-1.2.6/auto/lib/perl/conf    2013-07-22 11:05:55 +0900 (5ce6c91)
+++ vendor/nginx-1.4.2/auto/lib/perl/conf    2013-07-22 13:32:39 +0900 (2fbaa76)
@@ -40,6 +40,8 @@ if test -n "$NGX_PERL_VER"; then
 
     ngx_perl_ldopts=`$NGX_PERL -MExtUtils::Embed -e ldopts`
 
+    ngx_perl_dlext=`$NGX_PERL -MConfig -e 'print $Config{dlext}'`
+
     if $NGX_PERL -V:usemultiplicity | grep define > /dev/null; then
         have=NGX_HAVE_PERL_MULTIPLICITY . auto/have
         echo " + perl interpreter multiplicity found"
@@ -51,7 +53,7 @@ if test -n "$NGX_PERL_VER"; then
     fi
 
     CORE_LINK="$CORE_LINK $ngx_perl_ldopts"
-    LINK_DEPS="$LINK_DEPS $NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.so"
+    LINK_DEPS="$LINK_DEPS $NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.$ngx_perl_dlext"
 
     if test -n "$NGX_PERL_MODULES"; then
         have=NGX_PERL_MODULES value="(u_char *) \"$NGX_PERL_MODULES\""

  Added: vendor/nginx-1.4.2/auto/lib/perl/make (+40 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.4.2/auto/lib/perl/make    2013-07-22 13:32:39 +0900 (260bd95)
@@ -0,0 +1,40 @@
+
+# Copyright (C) Igor Sysoev
+# Copyright (C) Nginx, Inc.
+
+
+v=`grep 'define NGINX_VERSION' src/core/nginx.h | sed -e 's/^.*"\(.*\)".*/\1/'`
+
+
+cat << END                                                    >> $NGX_MAKEFILE
+
+$NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.$ngx_perl_dlext: \\
+		\$(CORE_DEPS) \$(HTTP_DEPS) \\
+		src/http/modules/perl/ngx_http_perl_module.h \\
+		$NGX_OBJS/src/http/modules/perl/Makefile
+	cd $NGX_OBJS/src/http/modules/perl && \$(MAKE)
+
+	rm -rf $NGX_OBJS/install_perl
+
+
+$NGX_OBJS/src/http/modules/perl/Makefile: \\
+		src/core/nginx.h \\
+		src/http/modules/perl/Makefile.PL \\
+		src/http/modules/perl/nginx.pm \\
+		src/http/modules/perl/nginx.xs \\
+		src/http/modules/perl/typemap
+	sed "s/%%VERSION%%/$v/" src/http/modules/perl/nginx.pm > \\
+		$NGX_OBJS/src/http/modules/perl/nginx.pm
+	cp -p src/http/modules/perl/nginx.xs $NGX_OBJS/src/http/modules/perl/
+	cp -p src/http/modules/perl/typemap $NGX_OBJS/src/http/modules/perl/
+	cp -p src/http/modules/perl/Makefile.PL $NGX_OBJS/src/http/modules/perl/
+
+	cd $NGX_OBJS/src/http/modules/perl \\
+		&& NGX_PM_CFLAGS="\$(NGX_PM_CFLAGS) -g $NGX_CC_OPT" \\
+			NGX_INCS="$CORE_INCS $NGX_OBJS $HTTP_INCS" \\
+			NGX_DEPS="\$(CORE_DEPS) \$(HTTP_DEPS)" \\
+		$NGX_PERL Makefile.PL \\
+			LIB=$NGX_PERL_MODULES \\
+			INSTALLSITEMAN3DIR=$NGX_PERL_MODULES_MAN
+
+END

  Renamed: vendor/nginx-1.4.2/auto/lib/sha1/conf (+1 -1) 96%
===================================================================
--- vendor/nginx-1.2.6/auto/lib/sha1/conf    2013-07-22 11:05:55 +0900 (1e644c0)
+++ vendor/nginx-1.4.2/auto/lib/sha1/conf    2013-07-22 13:32:39 +0900 (fd69afd)
@@ -57,7 +57,7 @@ else
 
             # OpenSSL crypto library
 
-            ngx_feature="OpenSSL sha1 crypto library"
+            ngx_feature="sha1 in system OpenSSL crypto library"
             ngx_feature_incs="#include <openssl/sha.h>"
             ngx_feature_libs="-lcrypto"
             . auto/feature

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

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

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

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

  Renamed: vendor/nginx-1.4.2/auto/lib/test (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.4.2/auto/lib/zlib/conf (+4 -1) 92%
===================================================================
--- vendor/nginx-1.2.6/auto/lib/zlib/conf    2013-07-22 11:05:55 +0900 (cefc874)
+++ vendor/nginx-1.4.2/auto/lib/zlib/conf    2013-07-22 13:32:39 +0900 (26db642)
@@ -9,11 +9,13 @@ if [ $ZLIB != NONE ]; then
     case "$NGX_CC_NAME" in
 
         msvc* | owc* | bcc)
+            have=NGX_ZLIB . auto/have
             LINK_DEPS="$LINK_DEPS $ZLIB/zlib.lib"
             CORE_LIBS="$CORE_LIBS $ZLIB/zlib.lib"
         ;;
 
         icc*)
+            have=NGX_ZLIB . auto/have
             LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
 
             # to allow -ipo optimization we link with the *.o but not library
@@ -30,6 +32,7 @@ if [ $ZLIB != NONE ]; then
         ;;
 
         *)
+            have=NGX_ZLIB . auto/have
             LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
             CORE_LIBS="$CORE_LIBS $ZLIB/libz.a"
             #CORE_LIBS="$CORE_LIBS -L $ZLIB -lz"
@@ -45,7 +48,7 @@ else
         # FreeBSD, Solaris, Linux
 
         ngx_feature="zlib library"
-        ngx_feature_name=
+        ngx_feature_name="NGX_ZLIB"
         ngx_feature_run=no
         ngx_feature_incs="#include <zlib.h>"
         ngx_feature_path=

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

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

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

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

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

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

  Renamed: vendor/nginx-1.4.2/auto/modules (+25 -4) 94%
===================================================================
--- vendor/nginx-1.2.6/auto/modules    2013-07-22 11:05:55 +0900 (d872c4e)
+++ vendor/nginx-1.4.2/auto/modules    2013-07-22 13:32:39 +0900 (a78e785)
@@ -100,6 +100,7 @@ fi
 #     ngx_http_write_filter
 #     ngx_http_header_filter
 #     ngx_http_chunked_filter
+#     ngx_http_spdy_filter
 #     ngx_http_range_header_filter
 #     ngx_http_gzip_filter
 #     ngx_http_postpone_filter
@@ -109,6 +110,7 @@ fi
 #         ngx_http_image_filter
 #         ngx_http_sub_filter
 #         ngx_http_addition_filter
+#         ngx_http_gunzip_filter
 #         ngx_http_userid_filter
 #         ngx_http_headers_filter
 #     ngx_http_copy_filter
@@ -117,8 +119,13 @@ fi
 
 HTTP_FILTER_MODULES="$HTTP_WRITE_FILTER_MODULE \
                      $HTTP_HEADER_FILTER_MODULE \
-                     $HTTP_CHUNKED_FILTER_MODULE \
-                     $HTTP_RANGE_HEADER_FILTER_MODULE"
+                     $HTTP_CHUNKED_FILTER_MODULE"
+
+if [ $HTTP_SPDY = YES ]; then
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SPDY_FILTER_MODULE"
+fi
+
+HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_RANGE_HEADER_FILTER_MODULE"
 
 if [ $HTTP_GZIP = YES ]; then
     have=NGX_HTTP_GZIP . auto/have
@@ -166,11 +173,27 @@ if [ $HTTP_ADDITION = YES ]; then
     HTTP_SRCS="$HTTP_SRCS $HTTP_ADDITION_SRCS"
 fi
 
+if [ $HTTP_GUNZIP = YES ]; then
+    have=NGX_HTTP_GZIP . auto/have
+    USE_ZLIB=YES
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_GUNZIP_FILTER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_GUNZIP_SRCS"
+fi
+
 if [ $HTTP_USERID = YES ]; then
     HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_USERID_FILTER_MODULE"
     HTTP_SRCS="$HTTP_SRCS $HTTP_USERID_SRCS"
 fi
 
+
+if [ $HTTP_SPDY = YES ]; then
+    have=NGX_HTTP_SPDY . auto/have
+    USE_ZLIB=YES
+    HTTP_MODULES="$HTTP_MODULES $HTTP_SPDY_MODULE"
+    HTTP_DEPS="$HTTP_DEPS $HTTP_SPDY_DEPS"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_SPDY_SRCS"
+fi
+
 HTTP_MODULES="$HTTP_MODULES $HTTP_STATIC_MODULE"
 
 if [ $HTTP_GZIP_STATIC = YES ]; then
@@ -234,7 +257,6 @@ if [ $HTTP_STATUS = YES ]; then
 fi
 
 if [ $HTTP_GEO = YES ]; then
-    have=NGX_HTTP_GEO . auto/have
     have=NGX_HTTP_X_FORWARDED_FOR . auto/have
     HTTP_MODULES="$HTTP_MODULES $HTTP_GEO_MODULE"
     HTTP_SRCS="$HTTP_SRCS $HTTP_GEO_SRCS"
@@ -276,7 +298,6 @@ if [ $HTTP_SSL = YES ]; then
 fi
 
 if [ $HTTP_PROXY = YES ]; then
-    have=NGX_HTTP_PROXY . auto/have
     have=NGX_HTTP_X_FORWARDED_FOR . auto/have
     #USE_MD5=YES
     HTTP_MODULES="$HTTP_MODULES $HTTP_PROXY_MODULE"

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

  Renamed: vendor/nginx-1.4.2/auto/options (+7 -1) 98%
===================================================================
--- vendor/nginx-1.2.6/auto/options    2013-07-22 11:05:55 +0900 (6c3a4db)
+++ vendor/nginx-1.4.2/auto/options    2013-07-22 13:32:39 +0900 (6713379)
@@ -15,7 +15,7 @@ NGX_LOCK_PATH=
 NGX_USER=
 NGX_GROUP=
 
-CC=${CC:-gcc}
+CC=${CC:-cc}
 CPP=
 NGX_OBJS=objs
 
@@ -60,6 +60,7 @@ HTTP_CACHE=YES
 HTTP_CHARSET=YES
 HTTP_GZIP=YES
 HTTP_SSL=NO
+HTTP_SPDY=NO
 HTTP_SSI=YES
 HTTP_POSTPONE=NO
 HTTP_REALIP=NO
@@ -94,6 +95,7 @@ HTTP_SECURE_LINK=NO
 HTTP_DEGRADATION=NO
 HTTP_FLV=NO
 HTTP_MP4=NO
+HTTP_GUNZIP=NO
 HTTP_GZIP_STATIC=NO
 HTTP_UPSTREAM_IP_HASH=YES
 HTTP_UPSTREAM_LEAST_CONN=YES
@@ -201,6 +203,7 @@ do
         --http-scgi-temp-path=*)         NGX_HTTP_SCGI_TEMP_PATH="$value" ;;
 
         --with-http_ssl_module)          HTTP_SSL=YES               ;;
+        --with-http_spdy_module)         HTTP_SPDY=YES              ;;
         --with-http_realip_module)       HTTP_REALIP=YES            ;;
         --with-http_addition_module)     HTTP_ADDITION=YES          ;;
         --with-http_xslt_module)         HTTP_XSLT=YES              ;;
@@ -210,6 +213,7 @@ do
         --with-http_dav_module)          HTTP_DAV=YES               ;;
         --with-http_flv_module)          HTTP_FLV=YES               ;;
         --with-http_mp4_module)          HTTP_MP4=YES               ;;
+        --with-http_gunzip_module)       HTTP_GUNZIP=YES            ;;
         --with-http_gzip_static_module)  HTTP_GZIP_STATIC=YES       ;;
         --with-http_random_index_module) HTTP_RANDOM_INDEX=YES      ;;
         --with-http_secure_link_module)  HTTP_SECURE_LINK=YES       ;;
@@ -347,6 +351,7 @@ cat << END
   --with-ipv6                        enable IPv6 support
 
   --with-http_ssl_module             enable ngx_http_ssl_module
+  --with-http_spdy_module            enable ngx_http_spdy_module
   --with-http_realip_module          enable ngx_http_realip_module
   --with-http_addition_module        enable ngx_http_addition_module
   --with-http_xslt_module            enable ngx_http_xslt_module
@@ -356,6 +361,7 @@ cat << END
   --with-http_dav_module             enable ngx_http_dav_module
   --with-http_flv_module             enable ngx_http_flv_module
   --with-http_mp4_module             enable ngx_http_mp4_module
+  --with-http_gunzip_module          enable ngx_http_gunzip_module
   --with-http_gzip_static_module     enable ngx_http_gzip_static_module
   --with-http_random_index_module    enable ngx_http_random_index_module
   --with-http_secure_link_module     enable ngx_http_secure_link_module

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

  Renamed: vendor/nginx-1.4.2/auto/os/darwin (+0 -0) 100%
===================================================================

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

  Renamed: vendor/nginx-1.4.2/auto/os/linux (+0 -0) 100%
===================================================================

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

  Renamed: vendor/nginx-1.4.2/auto/os/win32 (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.4.2/auto/sources (+15 -1) 96%
===================================================================
--- vendor/nginx-1.2.6/auto/sources    2013-07-22 11:05:55 +0900 (522d722)
+++ vendor/nginx-1.4.2/auto/sources    2013-07-22 13:32:39 +0900 (90465c3)
@@ -77,7 +77,8 @@ REGEX_SRCS=src/core/ngx_regex.c
 
 OPENSSL_MODULE=ngx_openssl_module
 OPENSSL_DEPS=src/event/ngx_event_openssl.h
-OPENSSL_SRCS=src/event/ngx_event_openssl.c
+OPENSSL_SRCS="src/event/ngx_event_openssl.c \
+              src/event/ngx_event_openssl_stapling.c"
 
 
 EVENT_MODULES="ngx_events_module ngx_event_core_module"
@@ -323,6 +324,15 @@ HTTP_POSTPONE_FILTER_SRCS=src/http/ngx_http_postpone_filter_module.c
 HTTP_FILE_CACHE_SRCS=src/http/ngx_http_file_cache.c
 
 
+HTTP_SPDY_MODULE=ngx_http_spdy_module
+HTTP_SPDY_FILTER_MODULE=ngx_http_spdy_filter_module
+HTTP_SPDY_DEPS="src/http/ngx_http_spdy.h \
+                src/http/ngx_http_spdy_module.h"
+HTTP_SPDY_SRCS="src/http/ngx_http_spdy.c \
+                src/http/ngx_http_spdy_module.c \
+                src/http/ngx_http_spdy_filter_module.c"
+
+
 HTTP_CHARSET_FILTER_MODULE=ngx_http_charset_filter_module
 HTTP_CHARSET_SRCS=src/http/modules/ngx_http_charset_filter_module.c
 
@@ -331,6 +341,10 @@ HTTP_GZIP_FILTER_MODULE=ngx_http_gzip_filter_module
 HTTP_GZIP_SRCS=src/http/modules/ngx_http_gzip_filter_module.c
 
 
+HTTP_GUNZIP_FILTER_MODULE=ngx_http_gunzip_filter_module
+HTTP_GUNZIP_SRCS=src/http/modules/ngx_http_gunzip_filter_module.c
+
+
 HTTP_SSI_FILTER_MODULE=ngx_http_ssi_filter_module
 HTTP_SSI_DEPS=src/http/modules/ngx_http_ssi_filter_module.h
 HTTP_SSI_SRCS=src/http/modules/ngx_http_ssi_filter_module.c

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

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

  Renamed: vendor/nginx-1.4.2/auto/types/sizeof (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.4.2/auto/types/typedef (+0 -0) 100%
===================================================================

  Renamed: vendor/nginx-1.4.2/auto/types/uintptr_t (+0 -0) 100%
===================================================================

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

  Renamed: vendor/nginx-1.4.2/auto/unix (+14 -0) 97%
===================================================================
--- vendor/nginx-1.2.6/auto/unix    2013-07-22 11:05:55 +0900 (b0a0e4c)
+++ vendor/nginx-1.4.2/auto/unix    2013-07-22 13:32:39 +0900 (cd4209e)
@@ -778,3 +778,17 @@ ngx_feature_test="struct stat sb;
                   openat(AT_FDCWD, \".\", O_RDONLY|O_NOFOLLOW);
                   fstatat(AT_FDCWD, \".\", &sb, AT_SYMLINK_NOFOLLOW);"
 . auto/feature
+
+
+ngx_feature="getaddrinfo()"
+ngx_feature_name="NGX_HAVE_GETADDRINFO"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/types.h>
+                  #include <sys/socket.h>
+                  #include <netdb.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test='struct addrinfo *res;
+                  if (getaddrinfo("localhost", NULL, NULL, &res) != 0) return 1;
+                  freeaddrinfo(res)'
+. auto/feature

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

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

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

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

  Renamed: vendor/nginx-1.4.2/conf/mime.types (+0 -0) 100%
===================================================================

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

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

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

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

  Renamed: vendor/nginx-1.4.2/configure (+0 -0) 100%
===================================================================

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

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

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

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

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

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

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

  Renamed: vendor/nginx-1.4.2/man/nginx.8 (+2 -2) 98%
===================================================================
--- vendor/nginx-1.2.6/man/nginx.8    2013-07-22 11:05:55 +0900 (8fcb0b0)
+++ vendor/nginx-1.4.2/man/nginx.8    2013-07-22 13:32:39 +0900 (f119a23)
@@ -1,6 +1,6 @@
 .\"
-.\" Copyright (c) 2010 Sergey A. Osokin
-.\" Copyright (c) 2011,2012 Nginx, Inc.
+.\" Copyright (C) 2010 Sergey A. Osokin
+.\" Copyright (C) Nginx, Inc.
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without

  Renamed: vendor/nginx-1.4.2/src/core/nginx.c (+8 -2) 99%
===================================================================
--- vendor/nginx-1.2.6/src/core/nginx.c    2013-07-22 11:05:55 +0900 (d02f911)
+++ vendor/nginx-1.4.2/src/core/nginx.c    2013-07-22 13:32:39 +0900 (94df9bf)
@@ -594,6 +594,10 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
     var = ngx_alloc(sizeof(NGINX_VAR)
                     + cycle->listening.nelts * (NGX_INT32_LEN + 1) + 2,
                     cycle->log);
+    if (var == NULL) {
+        ngx_free(env);
+        return NGX_INVALID_PID;
+    }
 
     p = ngx_cpymem(var, NGINX_VAR "=", sizeof(NGINX_VAR));
 
@@ -633,7 +637,7 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
 
     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
 
-    if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) != NGX_OK) {
+    if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) == NGX_FILE_ERROR) {
         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                       ngx_rename_file_n " %s to %s failed "
                       "before executing new binary process \"%s\"",
@@ -648,7 +652,9 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
     pid = ngx_execute(cycle, &ctx);
 
     if (pid == NGX_INVALID_PID) {
-        if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data) != NGX_OK) {
+        if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data)
+            == NGX_FILE_ERROR)
+        {
             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                           ngx_rename_file_n " %s back to %s failed after "
                           "an attempt to execute new binary process \"%s\"",

  Renamed: vendor/nginx-1.4.2/src/core/nginx.h (+2 -2) 80%
===================================================================
--- vendor/nginx-1.2.6/src/core/nginx.h    2013-07-22 11:05:55 +0900 (4d59895)
+++ vendor/nginx-1.4.2/src/core/nginx.h    2013-07-22 13:32:39 +0900 (b1107ad)
@@ -9,8 +9,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version      1002006
-#define NGINX_VERSION      "1.2.6"
+#define nginx_version      1004002
+#define NGINX_VERSION      "1.4.2"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"

  Renamed: vendor/nginx-1.4.2/src/core/ngx_array.c (+1 -7) 94%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_array.c    2013-07-22 11:05:55 +0900 (4627a99)
+++ vendor/nginx-1.4.2/src/core/ngx_array.c    2013-07-22 13:32:39 +0900 (4ea226f)
@@ -19,16 +19,10 @@ ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
         return NULL;
     }
 
-    a->elts = ngx_palloc(p, n * size);
-    if (a->elts == NULL) {
+    if (ngx_array_init(a, p, n, size) != NGX_OK) {
         return NULL;
     }
 
-    a->nelts = 0;
-    a->size = size;
-    a->nalloc = n;
-    a->pool = p;
-
     return a;
 }
 

  Renamed: vendor/nginx-1.4.2/src/core/ngx_array.h (+2 -2) 97%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_array.h    2013-07-22 11:05:55 +0900 (6a60e30)
+++ vendor/nginx-1.4.2/src/core/ngx_array.h    2013-07-22 13:32:39 +0900 (a0f2a74)
@@ -13,13 +13,13 @@
 #include <ngx_core.h>
 
 
-struct ngx_array_s {
+typedef struct {
     void        *elts;
     ngx_uint_t   nelts;
     size_t       size;
     ngx_uint_t   nalloc;
     ngx_pool_t  *pool;
-};
+} ngx_array_t;
 
 
 ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);

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

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

  Renamed: vendor/nginx-1.4.2/src/core/ngx_conf_file.c (+5 -20) 97%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_conf_file.c    2013-07-22 11:05:55 +0900 (6da2dae)
+++ vendor/nginx-1.4.2/src/core/ngx_conf_file.c    2013-07-22 13:32:39 +0900 (a262672)
@@ -133,7 +133,7 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
 
         cf->conf_file = &conf_file;
 
-        if (ngx_fd_info(fd, &cf->conf_file->file.info) == -1) {
+        if (ngx_fd_info(fd, &cf->conf_file->file.info) == NGX_FILE_ERROR) {
             ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
                           ngx_fd_info_n " \"%s\" failed", filename->data);
         }
@@ -945,7 +945,8 @@ ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
         file->name = *name;
     }
 
-    file->buffer = NULL;
+    file->flush = NULL;
+    file->data = NULL;
 
     return file;
 }
@@ -954,7 +955,6 @@ ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
 static void
 ngx_conf_flush_files(ngx_cycle_t *cycle)
 {
-    ssize_t           n, len;
     ngx_uint_t        i;
     ngx_list_part_t  *part;
     ngx_open_file_t  *file;
@@ -975,23 +975,8 @@ ngx_conf_flush_files(ngx_cycle_t *cycle)
             i = 0;
         }
 
-        len = file[i].pos - file[i].buffer;
-
-        if (file[i].buffer == NULL || len == 0) {
-            continue;
-        }
-
-        n = ngx_write_fd(file[i].fd, file[i].buffer, len);
-
-        if (n == NGX_FILE_ERROR) {
-            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
-                          ngx_write_fd_n " to \"%s\" failed",
-                          file[i].name.data);
-
-        } else if (n != len) {
-            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
-                          ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
-                          file[i].name.data, n, len);
+        if (file[i].flush) {
+            file[i].flush(&file[i], cycle->log);
         }
     }
 }

  Renamed: vendor/nginx-1.4.2/src/core/ngx_conf_file.h (+1 -10) 97%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_conf_file.h    2013-07-22 11:05:55 +0900 (64a9e8f)
+++ vendor/nginx-1.4.2/src/core/ngx_conf_file.h    2013-07-22 13:32:39 +0900 (237e6ec)
@@ -91,17 +91,8 @@ struct ngx_open_file_s {
     ngx_fd_t              fd;
     ngx_str_t             name;
 
-    u_char               *buffer;
-    u_char               *pos;
-    u_char               *last;
-
-#if 0
-    /* e.g. append mode, error_log */
-    ngx_uint_t            flags;
-    /* e.g. reopen db file */
-    ngx_uint_t          (*handler)(void *data, ngx_open_file_t *file);
+    void                (*flush)(ngx_open_file_t *file, ngx_log_t *log);
     void                 *data;
-#endif
 };
 
 

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

  Renamed: vendor/nginx-1.4.2/src/core/ngx_connection.c (+15 -9) 98%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_connection.c    2013-07-22 11:05:55 +0900 (3ba5e76)
+++ vendor/nginx-1.4.2/src/core/ngx_connection.c    2013-07-22 13:32:39 +0900 (7ed781e)
@@ -336,10 +336,10 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
 
 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
 
-            if (ls[i].sockaddr->sa_family == AF_INET6 && ls[i].ipv6only) {
+            if (ls[i].sockaddr->sa_family == AF_INET6) {
                 int  ipv6only;
 
-                ipv6only = (ls[i].ipv6only == 1);
+                ipv6only = ls[i].ipv6only;
 
                 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
                                (const void *) &ipv6only, sizeof(int))
@@ -412,7 +412,7 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
                 }
 
                 if (ngx_test_config) {
-                    if (ngx_delete_file(name) == -1) {
+                    if (ngx_delete_file(name) == NGX_FILE_ERROR) {
                         ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                                       ngx_delete_file_n " %s failed", name);
                     }
@@ -739,7 +739,7 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
         {
             u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;
 
-            if (ngx_delete_file(name) == -1) {
+            if (ngx_delete_file(name) == NGX_FILE_ERROR) {
                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
                               ngx_delete_file_n " %s failed", name);
             }
@@ -900,11 +900,9 @@ ngx_close_connection(ngx_connection_t *c)
     c->read->closed = 1;
     c->write->closed = 1;
 
-    if (c->single_connection) {
-        ngx_unlock(&c->lock);
-        c->read->locked = 0;
-        c->write->locked = 0;
-    }
+    ngx_unlock(&c->lock);
+    c->read->locked = 0;
+    c->write->locked = 0;
 
     ngx_mutex_unlock(ngx_posted_events_mutex);
 
@@ -972,6 +970,10 @@ ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
 
     if (c->reusable) {
         ngx_queue_remove(&c->queue);
+
+#if (NGX_STAT_STUB)
+        (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1);
+#endif
     }
 
     c->reusable = reusable;
@@ -981,6 +983,10 @@ ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
 
         ngx_queue_insert_head(
             (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);
+
+#if (NGX_STAT_STUB)
+        (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1);
+#endif
     }
 }
 

  Renamed: vendor/nginx-1.4.2/src/core/ngx_connection.h (+1 -2) 98%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_connection.h    2013-07-22 11:05:55 +0900 (34af12e)
+++ vendor/nginx-1.4.2/src/core/ngx_connection.h    2013-07-22 13:32:39 +0900 (3daf2ee)
@@ -64,7 +64,7 @@ struct ngx_listening_s {
     unsigned            addr_ntop:1;
 
 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
-    unsigned            ipv6only:2;
+    unsigned            ipv6only:1;
 #endif
     unsigned            keepalive:2;
 
@@ -152,7 +152,6 @@ struct ngx_connection_s {
 
     unsigned            log_error:3;     /* ngx_connection_log_error_e */
 
-    unsigned            single_connection:1;
     unsigned            unexpected_eof:1;
     unsigned            timedout:1;
     unsigned            error:1;

  Renamed: vendor/nginx-1.4.2/src/core/ngx_core.h (+1 -2) 98%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_core.h    2013-07-22 11:05:55 +0900 (435ce64)
+++ vendor/nginx-1.4.2/src/core/ngx_core.h    2013-07-22 13:32:39 +0900 (dfcf2d5)
@@ -15,7 +15,6 @@ typedef struct ngx_cycle_s       ngx_cycle_t;
 typedef struct ngx_pool_s        ngx_pool_t;
 typedef struct ngx_chain_s       ngx_chain_t;
 typedef struct ngx_log_s         ngx_log_t;
-typedef struct ngx_array_s       ngx_array_t;
 typedef struct ngx_open_file_s   ngx_open_file_t;
 typedef struct ngx_command_s     ngx_command_t;
 typedef struct ngx_file_s        ngx_file_t;
@@ -69,12 +68,12 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
 #include <ngx_slab.h>
 #include <ngx_inet.h>
 #include <ngx_cycle.h>
+#include <ngx_resolver.h>
 #if (NGX_OPENSSL)
 #include <ngx_event_openssl.h>
 #endif
 #include <ngx_process_cycle.h>
 #include <ngx_conf_file.h>
-#include <ngx_resolver.h>
 #include <ngx_open_file_cache.h>
 #include <ngx_os.h>
 #include <ngx_connection.h>

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

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

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

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

  Renamed: vendor/nginx-1.4.2/src/core/ngx_crypt.c (+37 -0) 85%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_crypt.c    2013-07-22 11:05:55 +0900 (b2e25b9)
+++ vendor/nginx-1.4.2/src/core/ngx_crypt.c    2013-07-22 13:32:39 +0900 (629d160)
@@ -24,6 +24,8 @@ static ngx_int_t ngx_crypt_plain(ngx_pool_t *pool, u_char *key, u_char *salt,
 
 static ngx_int_t ngx_crypt_ssha(ngx_pool_t *pool, u_char *key, u_char *salt,
     u_char **encrypted);
+static ngx_int_t ngx_crypt_sha(ngx_pool_t *pool, u_char *key, u_char *salt,
+    u_char **encrypted);
 
 #endif
 
@@ -43,6 +45,9 @@ ngx_crypt(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
 #if (NGX_HAVE_SHA1)
     } else if (ngx_strncmp(salt, "{SSHA}", sizeof("{SSHA}") - 1) == 0) {
         return ngx_crypt_ssha(pool, key, salt, encrypted);
+
+    } else if (ngx_strncmp(salt, "{SHA}", sizeof("{SHA}") - 1) == 0) {
+        return ngx_crypt_sha(pool, key, salt, encrypted);
 #endif
     }
 
@@ -241,6 +246,38 @@ ngx_crypt_ssha(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
     return NGX_OK;
 }
 
+
+static ngx_int_t
+ngx_crypt_sha(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
+{
+    size_t      len;
+    ngx_str_t   encoded, decoded;
+    ngx_sha1_t  sha1;
+    u_char      digest[20];
+
+    /* "{SHA}" base64(SHA1(key)) */
+
+    decoded.len = sizeof(digest);
+    decoded.data = digest;
+
+    ngx_sha1_init(&sha1);
+    ngx_sha1_update(&sha1, key, ngx_strlen(key));
+    ngx_sha1_final(digest, &sha1);
+
+    len = sizeof("{SHA}") - 1 + ngx_base64_encoded_length(decoded.len) + 1;
+
+    *encrypted = ngx_pnalloc(pool, len);
+    if (*encrypted == NULL) {
+        return NGX_ERROR;
+    }
+
+    encoded.data = ngx_cpymem(*encrypted, "{SHA}", sizeof("{SHA}") - 1);
+    ngx_encode_base64(&encoded, &decoded);
+    encoded.data[encoded.len] = '\0';
+
+    return NGX_OK;
+}
+
 #endif /* NGX_HAVE_SHA1 */
 
 #endif /* NGX_CRYPT */

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

  Renamed: vendor/nginx-1.4.2/src/core/ngx_cycle.c (+3 -20) 97%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_cycle.c    2013-07-22 11:05:55 +0900 (e8b1559)
+++ vendor/nginx-1.4.2/src/core/ngx_cycle.c    2013-07-22 13:32:39 +0900 (87b6d7d)
@@ -679,7 +679,7 @@ old_shm_zone_done:
             ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
                           "deleting socket %s", name);
 
-            if (ngx_delete_file(name) == -1) {
+            if (ngx_delete_file(name) == NGX_FILE_ERROR) {
                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
                               ngx_delete_file_n " %s failed", name);
             }
@@ -1115,7 +1115,6 @@ ngx_test_lockfile(u_char *file, ngx_log_t *log)
 void
 ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
 {
-    ssize_t           n, len;
     ngx_fd_t          fd;
     ngx_uint_t        i;
     ngx_list_part_t  *part;
@@ -1139,24 +1138,8 @@ ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
             continue;
         }
 
-        len = file[i].pos - file[i].buffer;
-
-        if (file[i].buffer && len != 0) {
-
-            n = ngx_write_fd(file[i].fd, file[i].buffer, len);
-
-            if (n == NGX_FILE_ERROR) {
-                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
-                              ngx_write_fd_n " to \"%s\" failed",
-                              file[i].name.data);
-
-            } else if (n != len) {
-                ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
-                          ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
-                          file[i].name.data, n, len);
-            }
-
-            file[i].pos = file[i].buffer;
+        if (file[i].flush) {
+            file[i].flush(&file[i], cycle->log);
         }
 
         fd = ngx_open_file(file[i].name.data, NGX_FILE_APPEND,

  Renamed: vendor/nginx-1.4.2/src/core/ngx_cycle.h (+1 -1) 98%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_cycle.h    2013-07-22 11:05:55 +0900 (b55fee0)
+++ vendor/nginx-1.4.2/src/core/ngx_cycle.h    2013-07-22 13:32:39 +0900 (2e4bc4b)
@@ -14,7 +14,7 @@
 
 
 #ifndef NGX_CYCLE_POOL_SIZE
-#define NGX_CYCLE_POOL_SIZE     16384
+#define NGX_CYCLE_POOL_SIZE     NGX_DEFAULT_POOL_SIZE
 #endif
 
 

  Renamed: vendor/nginx-1.4.2/src/core/ngx_file.c (+4 -4) 99%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_file.c    2013-07-22 11:05:55 +0900 (f13fb49)
+++ vendor/nginx-1.4.2/src/core/ngx_file.c    2013-07-22 13:32:39 +0900 (35f5f8d)
@@ -732,14 +732,14 @@ ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
 
         n = ngx_read_fd(fd, buf, len);
 
-        if (n == NGX_FILE_ERROR) {
+        if (n == -1) {
             ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
                           ngx_read_fd_n " \"%s\" failed", from);
             goto failed;
         }
 
         if ((size_t) n != len) {
-            ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+            ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
                           ngx_read_fd_n " has read only %z of %uz from %s",
                           n, size, from);
             goto failed;
@@ -747,14 +747,14 @@ ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
 
         n = ngx_write_fd(nfd, buf, len);
 
-        if (n == NGX_FILE_ERROR) {
+        if (n == -1) {
             ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
                           ngx_write_fd_n " \"%s\" failed", to);
             goto failed;
         }
 
         if ((size_t) n != len) {
-            ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+            ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
                           ngx_write_fd_n " has written only %z of %uz to %s",
                           n, size, to);
             goto failed;

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

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

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

  Renamed: vendor/nginx-1.4.2/src/core/ngx_inet.c (+220 -49) 79%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_inet.c    2013-07-22 11:05:55 +0900 (3db0136)
+++ vendor/nginx-1.4.2/src/core/ngx_inet.c    2013-07-22 13:32:39 +0900 (7757ab7)
@@ -465,7 +465,7 @@ ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len)
      * prevent MSVC8 warning:
      *    potentially uninitialized local variable 'inaddr6' used
      */
-    ngx_memzero(inaddr6.s6_addr, sizeof(struct in6_addr));
+    ngx_memzero(&inaddr6, sizeof(struct in6_addr));
 #endif
 
     inaddr = ngx_inet_addr(text, len);
@@ -611,11 +611,13 @@ ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)
 static ngx_int_t
 ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
 {
-    u_char              *p, *host, *port, *last, *uri, *args;
-    size_t               len;
-    ngx_int_t            n;
-    struct hostent      *h;
-    struct sockaddr_in  *sin;
+    u_char               *p, *host, *port, *last, *uri, *args;
+    size_t                len;
+    ngx_int_t             n;
+    struct sockaddr_in   *sin;
+#if (NGX_HAVE_INET6)
+    struct sockaddr_in6  *sin6;
+#endif
 
     u->socklen = sizeof(struct sockaddr_in);
     sin = (struct sockaddr_in *) &u->sockaddr;
@@ -705,6 +707,8 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
         }
 
         u->no_port = 1;
+        u->port = u->default_port;
+        sin->sin_port = htons(u->default_port);
     }
 
     len = last - host;
@@ -714,59 +718,88 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
         return NGX_ERROR;
     }
 
-    if (len == 1 && *host == '*') {
-        len = 0;
-    }
-
     u->host.len = len;
     u->host.data = host;
 
-    if (u->no_resolve) {
+    if (u->listen && len == 1 && *host == '*') {
+        sin->sin_addr.s_addr = INADDR_ANY;
+        u->wildcard = 1;
         return NGX_OK;
     }
 
-    if (len) {
-        sin->sin_addr.s_addr = ngx_inet_addr(host, len);
+    sin->sin_addr.s_addr = ngx_inet_addr(host, len);
 
-        if (sin->sin_addr.s_addr == INADDR_NONE) {
-            p = ngx_alloc(++len, pool->log);
-            if (p == NULL) {
-                return NGX_ERROR;
-            }
+    if (sin->sin_addr.s_addr != INADDR_NONE) {
 
-            (void) ngx_cpystrn(p, host, len);
-
-            h = gethostbyname((const char *) p);
+        if (sin->sin_addr.s_addr == INADDR_ANY) {
+            u->wildcard = 1;
+        }
 
-            ngx_free(p);
+        u->naddrs = 1;
 
-            if (h == NULL || h->h_addr_list[0] == NULL) {
-                u->err = "host not found";
-                return NGX_ERROR;
-            }
+        u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
+        if (u->addrs == NULL) {
+            return NGX_ERROR;
+        }
 
-            sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[0]);
+        sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
+        if (sin == NULL) {
+            return NGX_ERROR;
         }
 
-        if (sin->sin_addr.s_addr == INADDR_ANY) {
-            u->wildcard = 1;
+        ngx_memcpy(sin, u->sockaddr, sizeof(struct sockaddr_in));
+
+        u->addrs[0].sockaddr = (struct sockaddr *) sin;
+        u->addrs[0].socklen = sizeof(struct sockaddr_in);
+
+        p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
+        if (p == NULL) {
+            return NGX_ERROR;
         }
 
-    } else {
-        sin->sin_addr.s_addr = INADDR_ANY;
-        u->wildcard = 1;
-    }
+        u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
+                                           &u->host, u->port) - p;
+        u->addrs[0].name.data = p;
 
-    if (u->no_port) {
-        u->port = u->default_port;
-        sin->sin_port = htons(u->default_port);
+        return NGX_OK;
     }
 
-    if (u->listen) {
+    if (u->no_resolve) {
         return NGX_OK;
     }
 
-    return ngx_inet_resolve_host(pool, u);
+    if (ngx_inet_resolve_host(pool, u) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    u->family = u->addrs[0].sockaddr->sa_family;
+    u->socklen = u->addrs[0].socklen;
+    ngx_memcpy(u->sockaddr, u->addrs[0].sockaddr, u->addrs[0].socklen);
+
+    switch (u->family) {
+
+#if (NGX_HAVE_INET6)
+    case AF_INET6:
+        sin6 = (struct sockaddr_in6 *) &u->sockaddr;
+
+        if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+            u->wildcard = 1;
+        }
+
+        break;
+#endif
+
+    default: /* AF_INET */
+        sin = (struct sockaddr_in *) &u->sockaddr;
+
+        if (sin->sin_addr.s_addr == INADDR_ANY) {
+            u->wildcard = 1;
+        }
+
+        break;
+    }
+
+    return NGX_OK;
 }
 
 
@@ -832,6 +865,8 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
 
         } else {
             u->no_port = 1;
+            u->port = u->default_port;
+            sin6->sin6_port = htons(u->default_port);
         }
     }
 
@@ -854,11 +889,6 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
         u->wildcard = 1;
     }
 
-    if (u->no_port) {
-        u->port = u->default_port;
-        sin6->sin6_port = htons(u->default_port);
-    }
-
     u->family = AF_INET6;
     u->naddrs = 1;
 
@@ -898,6 +928,150 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
 }
 
 
+#if (NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6)
+
+ngx_int_t
+ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
+{
+    u_char               *p, *host;
+    size_t                len;
+    in_port_t             port;
+    ngx_uint_t            i;
+    struct addrinfo       hints, *res, *rp;
+    struct sockaddr_in   *sin;
+    struct sockaddr_in6  *sin6;
+
+    port = htons(u->port);
+
+    host = ngx_alloc(u->host.len + 1, pool->log);
+    if (host == NULL) {
+        return NGX_ERROR;
+    }
+
+    (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
+
+    ngx_memzero(&hints, sizeof(struct addrinfo));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+
+    if (getaddrinfo((char *) host, NULL, &hints, &res) != 0) {
+        u->err = "host not found";
+        ngx_free(host);
+        return NGX_ERROR;
+    }
+
+    ngx_free(host);
+
+    for (i = 0, rp = res; rp != NULL; rp = rp->ai_next) {
+
+        switch (rp->ai_family) {
+
+        case AF_INET:
+        case AF_INET6:
+            break;
+
+        default:
+            continue;
+        }
+
+        i++;
+    }
+
+    if (i == 0) {
+        u->err = "host not found";
+        goto failed;
+    }
+
+    /* MP: ngx_shared_palloc() */
+
+    u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
+    if (u->addrs == NULL) {
+        goto failed;
+    }
+
+    u->naddrs = i;
+
+    i = 0;
+
+    /* AF_INET addresses first */
+
+    for (rp = res; rp != NULL; rp = rp->ai_next) {
+
+        if (rp->ai_family != AF_INET) {
+            continue;
+        }
+
+        sin = ngx_pcalloc(pool, rp->ai_addrlen);
+        if (sin == NULL) {
+            goto failed;
+        }
+
+        ngx_memcpy(sin, rp->ai_addr, rp->ai_addrlen);
+
+        sin->sin_port = port;
+
+        u->addrs[i].sockaddr = (struct sockaddr *) sin;
+        u->addrs[i].socklen = rp->ai_addrlen;
+
+        len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
+
+        p = ngx_pnalloc(pool, len);
+        if (p == NULL) {
+            goto failed;
+        }
+
+        len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1);
+
+        u->addrs[i].name.len = len;
+        u->addrs[i].name.data = p;
+
+        i++;
+    }
+
+    for (rp = res; rp != NULL; rp = rp->ai_next) {
+
+        if (rp->ai_family != AF_INET6) {
+            continue;
+        }
+
+        sin6 = ngx_pcalloc(pool, rp->ai_addrlen);
+        if (sin6 == NULL) {
+            goto failed;
+        }
+
+        ngx_memcpy(sin6, rp->ai_addr, rp->ai_addrlen);
+
+        sin6->sin6_port = port;
+
+        u->addrs[i].sockaddr = (struct sockaddr *) sin6;
+        u->addrs[i].socklen = rp->ai_addrlen;
+
+        len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
+
+        p = ngx_pnalloc(pool, len);
+        if (p == NULL) {
+            goto failed;
+        }
+
+        len = ngx_sock_ntop((struct sockaddr *) sin6, p, len, 1);
+
+        u->addrs[i].name.len = len;
+        u->addrs[i].name.data = p;
+
+        i++;
+    }
+
+    freeaddrinfo(res);
+    return NGX_OK;
+
+failed:
+
+    freeaddrinfo(res);
+    return NGX_ERROR;
+}
+
+#else /* !NGX_HAVE_GETADDRINFO || !NGX_HAVE_INET6 */
+
 ngx_int_t
 ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
 {
@@ -932,12 +1106,7 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
             return NGX_ERROR;
         }
 
-        if (u->one_addr == 0) {
-            for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
-
-        } else {
-            i = 1;
-        }
+        for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
 
         /* MP: ngx_shared_palloc() */
 
@@ -1010,3 +1179,5 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
 
     return NGX_OK;
 }
+
+#endif /* NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6 */

  Renamed: vendor/nginx-1.4.2/src/core/ngx_inet.h (+2 -2) 95%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_inet.h    2013-07-22 11:05:55 +0900 (c5a3d76)
+++ vendor/nginx-1.4.2/src/core/ngx_inet.h    2013-07-22 13:32:39 +0900 (6a5a368)
@@ -30,7 +30,7 @@
 #if (NGX_HAVE_UNIX_DOMAIN)
 #define NGX_SOCKADDR_STRLEN   (sizeof("unix:") - 1 + NGX_UNIX_ADDRSTRLEN)
 #else
-#define NGX_SOCKADDR_STRLEN   (NGX_INET6_ADDRSTRLEN + sizeof(":65535") - 1)
+#define NGX_SOCKADDR_STRLEN   (NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1)
 #endif
 
 #if (NGX_HAVE_UNIX_DOMAIN)
@@ -87,7 +87,7 @@ typedef struct {
     unsigned                  listen:1;
     unsigned                  uri_part:1;
     unsigned                  no_resolve:1;
-    unsigned                  one_addr:1;
+    unsigned                  one_addr:1;  /* compatibility */
 
     unsigned                  no_port:1;
     unsigned                  wildcard:1;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  Renamed: vendor/nginx-1.4.2/src/core/ngx_radix_tree.c (+202 -5) 61%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_radix_tree.c    2013-07-22 11:05:55 +0900 (5b35d1e)
+++ vendor/nginx-1.4.2/src/core/ngx_radix_tree.c    2013-07-22 13:32:39 +0900 (c1d8737)
@@ -9,7 +9,7 @@
 #include <ngx_core.h>
 
 
-static void *ngx_radix_alloc(ngx_radix_tree_t *tree);
+static ngx_radix_node_t *ngx_radix_alloc(ngx_radix_tree_t *tree);
 
 
 ngx_radix_tree_t *
@@ -263,13 +263,210 @@ ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key)
 }
 
 
-static void *
+#if (NGX_HAVE_INET6)
+
+ngx_int_t
+ngx_radix128tree_insert(ngx_radix_tree_t *tree, u_char *key, u_char *mask,
+    uintptr_t value)
+{
+    u_char             bit;
+    ngx_uint_t         i;
+    ngx_radix_node_t  *node, *next;
+
+    i = 0;
+    bit = 0x80;
+
+    node = tree->root;
+    next = tree->root;
+
+    while (bit & mask[i]) {
+        if (key[i] & bit) {
+            next = node->right;
+
+        } else {
+            next = node->left;
+        }
+
+        if (next == NULL) {
+            break;
+        }
+
+        bit >>= 1;
+        node = next;
+
+        if (bit == 0) {
+            if (++i == 16) {
+                break;
+            }
+
+            bit = 0x80;
+        }
+    }
+
+    if (next) {
+        if (node->value != NGX_RADIX_NO_VALUE) {
+            return NGX_BUSY;
+        }
+
+        node->value = value;
+        return NGX_OK;
+    }
+
+    while (bit & mask[i]) {
+        next = ngx_radix_alloc(tree);
+        if (next == NULL) {
+            return NGX_ERROR;
+        }
+
+        next->right = NULL;
+        next->left = NULL;
+        next->parent = node;
+        next->value = NGX_RADIX_NO_VALUE;
+
+        if (key[i] & bit) {
+            node->right = next;
+
+        } else {
+            node->left = next;
+        }
+
+        bit >>= 1;
+        node = next;
+
+        if (bit == 0) {
+            if (++i == 16) {
+                break;
+            }
+
+            bit = 0x80;
+        }
+    }
+
+    node->value = value;
+
+    return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_radix128tree_delete(ngx_radix_tree_t *tree, u_char *key, u_char *mask)
+{
+    u_char             bit;
+    ngx_uint_t         i;
+    ngx_radix_node_t  *node;
+
+    i = 0;
+    bit = 0x80;
+    node = tree->root;
+
+    while (node && (bit & mask[i])) {
+        if (key[i] & bit) {
+            node = node->right;
+
+        } else {
+            node = node->left;
+        }
+
+        bit >>= 1;
+
+        if (bit == 0) {
+            if (++i == 16) {
+                break;
+            }
+
+            bit = 0x80;
+        }
+    }
+
+    if (node == NULL) {
+        return NGX_ERROR;
+    }
+
+    if (node->right || node->left) {
+        if (node->value != NGX_RADIX_NO_VALUE) {
+            node->value = NGX_RADIX_NO_VALUE;
+            return NGX_OK;
+        }
+
+        return NGX_ERROR;
+    }
+
+    for ( ;; ) {
+        if (node->parent->right == node) {
+            node->parent->right = NULL;
+
+        } else {
+            node->parent->left = NULL;
+        }
+
+        node->right = tree->free;
+        tree->free = node;
+
+        node = node->parent;
+
+        if (node->right || node->left) {
+            break;
+        }
+
+        if (node->value != NGX_RADIX_NO_VALUE) {
+            break;
+        }
+
+        if (node->parent == NULL) {
+            break;
+        }
+    }
+
+    return NGX_OK;
+}
+
+
+uintptr_t
+ngx_radix128tree_find(ngx_radix_tree_t *tree, u_char *key)
+{
+    u_char             bit;
+    uintptr_t          value;
+    ngx_uint_t         i;
+    ngx_radix_node_t  *node;
+
+    i = 0;
+    bit = 0x80;
+    value = NGX_RADIX_NO_VALUE;
+    node = tree->root;
+
+    while (node) {
+        if (node->value != NGX_RADIX_NO_VALUE) {
+            value = node->value;
+        }
+
+        if (key[i] & bit) {
+            node = node->right;
+
+        } else {
+            node = node->left;
+        }
+
+        bit >>= 1;
+
+        if (bit == 0) {
+            i++;
+            bit = 0x80;
+        }
+    }
+
+    return value;
+}
+
+#endif
+
+
+static ngx_radix_node_t *
 ngx_radix_alloc(ngx_radix_tree_t *tree)
 {
-    char  *p;
+    ngx_radix_node_t  *p;
 
     if (tree->free) {
-        p = (char *) tree->free;
+        p = tree->free;
         tree->free = tree->free->right;
         return p;
     }
@@ -283,7 +480,7 @@ ngx_radix_alloc(ngx_radix_tree_t *tree)
         tree->size = ngx_pagesize;
     }
 
-    p = tree->start;
+    p = (ngx_radix_node_t *) tree->start;
     tree->start += sizeof(ngx_radix_node_t);
     tree->size -= sizeof(ngx_radix_node_t);
 

  Renamed: vendor/nginx-1.4.2/src/core/ngx_radix_tree.h (+9 -0) 77%
===================================================================
--- vendor/nginx-1.2.6/src/core/ngx_radix_tree.h    2013-07-22 11:05:55 +0900 (65ee69b)
+++ vendor/nginx-1.4.2/src/core/ngx_radix_tree.h    2013-07-22 13:32:39 +0900 (4fe06e0)
@@ -36,11 +36,20 @@ typedef struct {
 
 ngx_radix_tree_t *ngx_radix_tree_create(ngx_pool_t *pool,
     ngx_int_t preallocate);
+
 ngx_int_t ngx_radix32tree_insert(ngx_radix_tree_t *tree,
     uint32_t key, uint32_t mask, uintptr_t value);
 ngx_int_t ngx_radix32tree_delete(ngx_radix_tree_t *tree,
     uint32_t key, uint32_t mask);
 uintptr_t ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key);
 
+#if (NGX_HAVE_INET6)
+ngx_int_t ngx_radix128tree_insert(ngx_radix_tree_t *tree,
+    u_char *key, u_char *mask, uintptr_t value);
+ngx_int_t ngx_radix128tree_delete(ngx_radix_tree_t *tree,
+    u_char *key, u_char *mask);
+uintptr_t ngx_radix128tree_find(ngx_radix_tree_t *tree, u_char *key);
+#endif
+
 
 #endif /* _NGX_RADIX_TREE_H_INCLUDED_ */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  Renamed: vendor/nginx-1.4.2/src/event/modules/ngx_devpoll_module.c (+7 -1) 98%
===================================================================
--- vendor/nginx-1.2.6/src/event/modules/ngx_devpoll_module.c    2013-07-22 11:05:55 +0900 (d09b5bc)
+++ vendor/nginx-1.4.2/src/event/modules/ngx_devpoll_module.c    2013-07-22 13:32:39 +0900 (6fdd002)
@@ -343,7 +343,7 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
     ngx_fd_t            fd;
     ngx_err_t           err;
     ngx_int_t           i;
-    ngx_uint_t          level;
+    ngx_uint_t          level, instance;
     ngx_event_t        *rev, *wev, **queue;
     ngx_connection_t   *c;
     struct pollfd       pfd;
@@ -510,7 +510,13 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
                 ngx_locked_post_event(rev, queue);
 
             } else {
+                instance = rev->instance;
+
                 rev->handler(rev);
+
+                if (c->fd == -1 || rev->instance != instance) {
+                    continue;
+                }
             }
         }
 

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

  Renamed: vendor/nginx-1.4.2/src/event/modules/ngx_eventport_module.c (+1 -1) 99%
===================================================================
--- vendor/nginx-1.2.6/src/event/modules/ngx_eventport_module.c    2013-07-22 11:05:55 +0900 (d6dcb0b)
+++ vendor/nginx-1.4.2/src/event/modules/ngx_eventport_module.c    2013-07-22 13:32:39 +0900 (5f9cf4e)
@@ -551,7 +551,7 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
                 } else {
                     rev->handler(rev);
 
-                    if (ev->closed) {
+                    if (ev->closed || ev->instance != instance) {
                         continue;
                     }
                 }

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

  Renamed: vendor/nginx-1.4.2/src/event/modules/ngx_poll_module.c (+2 -2) 99%
===================================================================
--- vendor/nginx-1.2.6/src/event/modules/ngx_poll_module.c    2013-07-22 11:05:55 +0900 (ed64bc5)
+++ vendor/nginx-1.4.2/src/event/modules/ngx_poll_module.c    2013-07-22 13:32:39 +0900 (4d45218)
@@ -371,7 +371,7 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
 
         found = 0;
 
-        if (revents & POLLIN) {
+        if ((revents & POLLIN) && c->read->active) {
             found = 1;
 
             ev = c->read;
@@ -388,7 +388,7 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
             ngx_locked_post_event(ev, queue);
         }
 
-        if (revents & POLLOUT) {
+        if ((revents & POLLOUT) && c->write->active) {
             found = 1;
             ev = c->write;
 

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

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

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

  Renamed: vendor/nginx-1.4.2/src/event/ngx_event.c (+20 -1) 98%
===================================================================
--- vendor/nginx-1.2.6/src/event/ngx_event.c    2013-07-22 11:05:55 +0900 (976bd64)
+++ vendor/nginx-1.4.2/src/event/ngx_event.c    2013-07-22 13:32:39 +0900 (c4c6120)
@@ -73,6 +73,8 @@ ngx_atomic_t   ngx_stat_reading0;
 ngx_atomic_t  *ngx_stat_reading = &ngx_stat_reading0;
 ngx_atomic_t   ngx_stat_writing0;
 ngx_atomic_t  *ngx_stat_writing = &ngx_stat_writing0;
+ngx_atomic_t   ngx_stat_waiting0;
+ngx_atomic_t  *ngx_stat_waiting = &ngx_stat_waiting0;
 
 #endif
 
@@ -511,7 +513,8 @@ ngx_event_module_init(ngx_cycle_t *cycle)
            + cl          /* ngx_stat_requests */
            + cl          /* ngx_stat_active */
            + cl          /* ngx_stat_reading */
-           + cl;         /* ngx_stat_writing */
+           + cl          /* ngx_stat_writing */
+           + cl;         /* ngx_stat_waiting */
 
 #endif
 
@@ -558,6 +561,7 @@ ngx_event_module_init(ngx_cycle_t *cycle)
     ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl);
     ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl);
     ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl);
+    ngx_stat_waiting = (ngx_atomic_t *) (shared + 9 * cl);
 
 #endif
 
@@ -603,6 +607,17 @@ ngx_event_process_init(ngx_cycle_t *cycle)
         ngx_use_accept_mutex = 0;
     }
 
+#if (NGX_WIN32)
+
+    /*
+     * disable accept mutex on win32 as it may cause deadlock if
+     * grabbed by a process which can't accept connections
+     */
+
+    ngx_use_accept_mutex = 0;
+
+#endif
+
 #if (NGX_THREADS)
     ngx_posted_events_mutex = ngx_mutex_init(cycle->log, 0);
     if (ngx_posted_events_mutex == NULL) {
@@ -892,6 +907,10 @@ ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     ngx_conf_t            pcf;
     ngx_event_module_t   *m;
 
+    if (*(void **) conf) {
+        return "is duplicate";
+    }
+
     /* count the number of the event modules and set up their indices */
 
     ngx_event_max_module = 0;

  Renamed: vendor/nginx-1.4.2/src/event/ngx_event.h (+1 -0) 99%
===================================================================
--- vendor/nginx-1.2.6/src/event/ngx_event.h    2013-07-22 11:05:55 +0900 (2096da2)
+++ vendor/nginx-1.4.2/src/event/ngx_event.h    2013-07-22 13:32:39 +0900 (93c457c)
@@ -511,6 +511,7 @@ extern ngx_atomic_t  *ngx_stat_requests;
 extern ngx_atomic_t  *ngx_stat_active;
 extern ngx_atomic_t  *ngx_stat_reading;
 extern ngx_atomic_t  *ngx_stat_writing;
+extern ngx_atomic_t  *ngx_stat_waiting;
 
 #endif
 

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

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

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

  Renamed: vendor/nginx-1.4.2/src/event/ngx_event_connect.c (+1 -1) 99%
===================================================================
--- vendor/nginx-1.2.6/src/event/ngx_event_connect.c    2013-07-22 11:05:55 +0900 (978f39b)
+++ vendor/nginx-1.4.2/src/event/ngx_event_connect.c    2013-07-22 13:32:39 +0900 (e6ae656)
@@ -84,7 +84,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
 
     c->log_error = pc->log_error;
 
-    if (pc->sockaddr->sa_family != AF_INET) {
+    if (pc->sockaddr->sa_family == AF_UNIX) {
         c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
         c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
 

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

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

  Renamed: vendor/nginx-1.4.2/src/event/ngx_event_openssl.c (+184 -24) 92%
===================================================================
--- vendor/nginx-1.2.6/src/event/ngx_event_openssl.c    2013-07-22 11:05:55 +0900 (5e25b01)
+++ vendor/nginx-1.4.2/src/event/ngx_event_openssl.c    2013-07-22 13:32:39 +0900 (62ce12c)
@@ -82,6 +82,8 @@ 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_certificate_index;
+int  ngx_ssl_stapling_index;
 
 
 ngx_int_t
@@ -137,6 +139,22 @@ ngx_ssl_init(ngx_log_t *log)
         return NGX_ERROR;
     }
 
+    ngx_ssl_certificate_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
+                                                         NULL);
+    if (ngx_ssl_certificate_index == -1) {
+        ngx_ssl_error(NGX_LOG_ALERT, log, 0,
+                      "SSL_CTX_get_ex_new_index() failed");
+        return NGX_ERROR;
+    }
+
+    ngx_ssl_stapling_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
+                                                      NULL);
+    if (ngx_ssl_stapling_index == -1) {
+        ngx_ssl_error(NGX_LOG_ALERT, log, 0,
+                      "SSL_CTX_get_ex_new_index() failed");
+        return NGX_ERROR;
+    }
+
     return NGX_OK;
 }
 
@@ -218,19 +236,89 @@ ngx_int_t
 ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
     ngx_str_t *key)
 {
+    BIO     *bio;
+    X509    *x509;
+    u_long   n;
+
     if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
         return NGX_ERROR;
     }
 
-    if (SSL_CTX_use_certificate_chain_file(ssl->ctx, (char *) cert->data)
+    /*
+     * we can't use SSL_CTX_use_certificate_chain_file() as it doesn't
+     * allow to access certificate later from SSL_CTX, so we reimplement
+     * it here
+     */
+
+    bio = BIO_new_file((char *) cert->data, "r");
+    if (bio == NULL) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "BIO_new_file(\"%s\") failed", cert->data);
+        return NGX_ERROR;
+    }
+
+    x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
+    if (x509 == NULL) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "PEM_read_bio_X509_AUX(\"%s\") failed", cert->data);
+        BIO_free(bio);
+        return NGX_ERROR;
+    }
+
+    if (SSL_CTX_use_certificate(ssl->ctx, x509) == 0) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "SSL_CTX_use_certificate(\"%s\") failed", cert->data);
+        X509_free(x509);
+        BIO_free(bio);
+        return NGX_ERROR;
+    }
+
+    if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509)
         == 0)
     {
         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
-                      "SSL_CTX_use_certificate_chain_file(\"%s\") failed",
-                      cert->data);
+                      "SSL_CTX_set_ex_data() failed");
         return NGX_ERROR;
     }
 
+    X509_free(x509);
+
+    /* read rest of the chain */
+
+    for ( ;; ) {
+
+        x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
+        if (x509 == NULL) {
+            n = ERR_peek_last_error();
+
+            if (ERR_GET_LIB(n) == ERR_LIB_PEM
+                && ERR_GET_REASON(n) == PEM_R_NO_START_LINE)
+            {
+                /* end of file */
+                ERR_clear_error();
+                break;
+            }
+
+            /* some real error */
+
+            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                          "PEM_read_bio_X509(\"%s\") failed", cert->data);
+            BIO_free(bio);
+            return NGX_ERROR;
+        }
+
+        if (SSL_CTX_add_extra_chain_cert(ssl->ctx, x509) == 0) {
+            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                          "SSL_CTX_add_extra_chain_cert(\"%s\") failed",
+                          cert->data);
+            X509_free(x509);
+            BIO_free(bio);
+            return NGX_ERROR;
+        }
+    }
+
+    BIO_free(bio);
+
     if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) {
         return NGX_ERROR;
     }
@@ -297,6 +385,33 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
 
 
 ngx_int_t
+ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
+    ngx_int_t depth)
+{
+    SSL_CTX_set_verify_depth(ssl->ctx, depth);
+
+    if (cert->len == 0) {
+        return NGX_OK;
+    }
+
+    if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL)
+        == 0)
+    {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "SSL_CTX_load_verify_locations(\"%s\") failed",
+                      cert->data);
+        return NGX_ERROR;
+    }
+
+    return NGX_OK;
+}
+
+
+ngx_int_t
 ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
 {
     X509_STORE   *store;
@@ -528,10 +643,10 @@ ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
         return NGX_ERROR;
     }
 
-    SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
-
     SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);
 
+    SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
+
     EC_KEY_free(ecdh);
 #endif
 #endif
@@ -693,6 +808,10 @@ ngx_ssl_handshake(ngx_connection_t *c)
             return NGX_ERROR;
         }
 
+        if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
         return NGX_AGAIN;
     }
 
@@ -701,6 +820,10 @@ ngx_ssl_handshake(ngx_connection_t *c)
         c->read->handler = ngx_ssl_handshake_handler;
         c->write->handler = ngx_ssl_handshake_handler;
 
+        if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
             return NGX_ERROR;
         }
@@ -1053,8 +1176,8 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
         buf->end = buf->start + NGX_SSL_BUFSIZE;
     }
 
-    send = 0;
-    flush = (in == NULL) ? 1 : 0;
+    send = buf->last - buf->pos;
+    flush = (in == NULL) ? 1 : buf->flush;
 
     for ( ;; ) {
 
@@ -1076,7 +1199,6 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 
             if (send + size > limit) {
                 size = (ssize_t) (limit - send);
-                flush = 1;
             }
 
             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
@@ -1093,10 +1215,16 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
             }
         }
 
+        if (!flush && send < limit && buf->last < buf->end) {
+            break;
+        }
+
         size = buf->last - buf->pos;
 
-        if (!flush && buf->last < buf->end && c->ssl->buffer) {
-            break;
+        if (size == 0) {
+            buf->flush = 0;
+            c->buffered &= ~NGX_SSL_BUFFERED;
+            return in;
         }
 
         n = ngx_ssl_write(c, buf->pos, size);
@@ -1106,8 +1234,7 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
         }
 
         if (n == NGX_AGAIN) {
-            c->buffered |= NGX_SSL_BUFFERED;
-            return in;
+            break;
         }
 
         buf->pos += n;
@@ -1117,16 +1244,18 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
             break;
         }
 
-        if (buf->pos == buf->last) {
-            buf->pos = buf->start;
-            buf->last = buf->start;
-        }
+        flush = 0;
+
+        buf->pos = buf->start;
+        buf->last = buf->start;
 
         if (in == NULL || send == limit) {
             break;
         }
     }
 
+    buf->flush = flush;
+
     if (buf->pos < buf->last) {
         c->buffered |= NGX_SSL_BUFFERED;
 
@@ -1475,10 +1604,12 @@ ngx_ssl_clear_error(ngx_log_t *log)
 void ngx_cdecl
 ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
 {
-    u_long    n;
-    va_list   args;
-    u_char   *p, *last;
-    u_char    errstr[NGX_MAX_CONF_ERRSTR];
+    int          flags;
+    u_long       n;
+    va_list      args;
+    u_char      *p, *last;
+    u_char       errstr[NGX_MAX_CONF_ERRSTR];
+    const char  *data;
 
     last = errstr + NGX_MAX_CONF_ERRSTR;
 
@@ -1490,14 +1621,14 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
 
     for ( ;; ) {
 
-        n = ERR_get_error();
+        n = ERR_peek_error_line_data(NULL, NULL, &data, &flags);
 
         if (n == 0) {
             break;
         }
 
         if (p >= last) {
-            continue;
+            goto next;
         }
 
         *p++ = ' ';
@@ -1507,6 +1638,15 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
         while (p < last && *p) {
             p++;
         }
+
+        if (p < last && *data && (flags & ERR_TXT_STRING)) {
+            *p++ = ':';
+            p = ngx_cpystrn(p, (u_char *) data, last - p);
+        }
+
+    next:
+
+        (void) ERR_get_error();
     }
 
     ngx_log_error(level, log, err, "%s)", errstr);
@@ -1702,8 +1842,18 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
     }
 
     sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t));
+
     if (sess_id == NULL) {
-        goto failed;
+
+        /* drop the oldest non-expired session and try once more */
+
+        ngx_ssl_expire_sessions(cache, shpool, 0);
+
+        sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t));
+
+        if (sess_id == NULL) {
+            goto failed;
+        }
     }
 
 #if (NGX_PTR_SIZE == 8)
@@ -1713,8 +1863,18 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
 #else
 
     id = ngx_slab_alloc_locked(shpool, sess->session_id_length);
+
     if (id == NULL) {
-        goto failed;
+
+        /* drop the oldest non-expired session and try once more */
+
+        ngx_ssl_expire_sessions(cache, shpool, 0);
+
+        id = ngx_slab_alloc_locked(shpool, sess->session_id_length);
+
+        if (id == NULL) {
+            goto failed;
+        }
     }
 
 #endif

  Renamed: vendor/nginx-1.4.2/src/event/ngx_event_openssl.h (+9 -0) 92%
===================================================================
--- vendor/nginx-1.2.6/src/event/ngx_event_openssl.h    2013-07-22 11:05:55 +0900 (b8061f0)
+++ vendor/nginx-1.4.2/src/event/ngx_event_openssl.h    2013-07-22 13:32:39 +0900 (bf81d25)
@@ -17,6 +17,7 @@
 #include <openssl/conf.h>
 #include <openssl/engine.h>
 #include <openssl/evp.h>
+#include <openssl/ocsp.h>
 
 #define NGX_SSL_NAME     "OpenSSL"
 
@@ -101,7 +102,13 @@ ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
     ngx_str_t *cert, ngx_str_t *key);
 ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
     ngx_str_t *cert, ngx_int_t depth);
+ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
+    ngx_str_t *cert, ngx_int_t depth);
 ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl);
+ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl,
+    ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify);
+ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
+    ngx_resolver_t *resolver, ngx_msec_t resolver_timeout);
 RSA *ngx_ssl_rsa512_key_callback(SSL *ssl, 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);
@@ -164,6 +171,8 @@ 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_certificate_index;
+extern int  ngx_ssl_stapling_index;
 
 
 #endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */

  Added: vendor/nginx-1.4.2/src/event/ngx_event_openssl_stapling.c (+1748 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.4.2/src/event/ngx_event_openssl_stapling.c    2013-07-22 13:32:39 +0900 (77baeb9)
@@ -0,0 +1,1748 @@
+
+/*
+ * Copyright (C) Maxim Dounin
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+#include <ngx_event_connect.h>
+
+
+#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
+
+
+typedef struct {
+    ngx_str_t                    staple;
+    ngx_msec_t                   timeout;
+
+    ngx_resolver_t              *resolver;
+    ngx_msec_t                   resolver_timeout;
+
+    ngx_addr_t                  *addrs;
+    ngx_str_t                    host;
+    ngx_str_t                    uri;
+    in_port_t                    port;
+
+    SSL_CTX                     *ssl_ctx;
+
+    X509                        *cert;
+    X509                        *issuer;
+
+    time_t                       valid;
+
+    unsigned                     verify:1;
+    unsigned                     loading:1;
+} ngx_ssl_stapling_t;
+
+
+typedef struct ngx_ssl_ocsp_ctx_s  ngx_ssl_ocsp_ctx_t;
+
+struct ngx_ssl_ocsp_ctx_s {
+    X509                        *cert;
+    X509                        *issuer;
+
+    ngx_uint_t                   naddrs;
+
+    ngx_addr_t                  *addrs;
+    ngx_str_t                    host;
+    ngx_str_t                    uri;
+    in_port_t                    port;
+
+    ngx_resolver_t              *resolver;
+    ngx_msec_t                   resolver_timeout;
+
+    ngx_msec_t                   timeout;
+
+    void                       (*handler)(ngx_ssl_ocsp_ctx_t *r);
+    void                        *data;
+
+    ngx_buf_t                   *request;
+    ngx_buf_t                   *response;
+    ngx_peer_connection_t        peer;
+
+    ngx_int_t                  (*process)(ngx_ssl_ocsp_ctx_t *r);
+
+    ngx_uint_t                   state;
+
+    ngx_uint_t                   code;
+    ngx_uint_t                   count;
+
+    ngx_uint_t                   done;
+
+    u_char                      *header_name_start;
+    u_char                      *header_name_end;
+    u_char                      *header_start;
+    u_char                      *header_end;
+
+    ngx_pool_t                  *pool;
+    ngx_log_t                   *log;
+};
+
+
+static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl,
+    ngx_str_t *file);
+static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl);
+static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl,
+    ngx_str_t *responder);
+
+static int ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn,
+    void *data);
+static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple);
+static void ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx);
+
+static void ngx_ssl_stapling_cleanup(void *data);
+
+static ngx_ssl_ocsp_ctx_t *ngx_ssl_ocsp_start(void);
+static void ngx_ssl_ocsp_done(ngx_ssl_ocsp_ctx_t *ctx);
+static void ngx_ssl_ocsp_request(ngx_ssl_ocsp_ctx_t *ctx);
+static void ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve);
+static void ngx_ssl_ocsp_connect(ngx_ssl_ocsp_ctx_t *ctx);
+static void ngx_ssl_ocsp_write_handler(ngx_event_t *wev);
+static void ngx_ssl_ocsp_read_handler(ngx_event_t *rev);
+static void ngx_ssl_ocsp_dummy_handler(ngx_event_t *ev);
+
+static ngx_int_t ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx);
+static ngx_int_t ngx_ssl_ocsp_process_status_line(ngx_ssl_ocsp_ctx_t *ctx);
+static ngx_int_t ngx_ssl_ocsp_parse_status_line(ngx_ssl_ocsp_ctx_t *ctx);
+static ngx_int_t ngx_ssl_ocsp_process_headers(ngx_ssl_ocsp_ctx_t *ctx);
+static ngx_int_t ngx_ssl_ocsp_parse_header_line(ngx_ssl_ocsp_ctx_t *ctx);
+static ngx_int_t ngx_ssl_ocsp_process_body(ngx_ssl_ocsp_ctx_t *ctx);
+
+static u_char *ngx_ssl_ocsp_log_error(ngx_log_t *log, u_char *buf, size_t len);
+
+
+ngx_int_t
+ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file,
+    ngx_str_t *responder, ngx_uint_t verify)
+{
+    ngx_int_t                  rc;
+    ngx_pool_cleanup_t        *cln;
+    ngx_ssl_stapling_t        *staple;
+
+    staple = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_stapling_t));
+    if (staple == NULL) {
+        return NGX_ERROR;
+    }
+
+    cln = ngx_pool_cleanup_add(cf->pool, 0);
+    if (cln == NULL) {
+        return NGX_ERROR;
+    }
+
+    cln->handler = ngx_ssl_stapling_cleanup;
+    cln->data = staple;
+
+    if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_stapling_index, staple)
+        == 0)
+    {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "SSL_CTX_set_ex_data() failed");
+        return NGX_ERROR;
+    }
+
+    staple->ssl_ctx = ssl->ctx;
+    staple->timeout = 60000;
+    staple->verify = verify;
+
+    if (file->len) {
+        /* use OCSP response from the file */
+
+        if (ngx_ssl_stapling_file(cf, ssl, file) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
+        goto done;
+    }
+
+    rc = ngx_ssl_stapling_issuer(cf, ssl);
+
+    if (rc == NGX_DECLINED) {
+        return NGX_OK;
+    }
+
+    if (rc != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    rc = ngx_ssl_stapling_responder(cf, ssl, responder);
+
+    if (rc == NGX_DECLINED) {
+        return NGX_OK;
+    }
+
+    if (rc != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+done:
+
+    SSL_CTX_set_tlsext_status_cb(ssl->ctx, ngx_ssl_certificate_status_callback);
+    SSL_CTX_set_tlsext_status_arg(ssl->ctx, staple);
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
+{
+    BIO                 *bio;
+    int                  len;
+    u_char              *p, *buf;
+    OCSP_RESPONSE       *response;
+    ngx_ssl_stapling_t  *staple;
+
+    staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
+
+    if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    bio = BIO_new_file((char *) file->data, "r");
+    if (bio == NULL) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "BIO_new_file(\"%s\") failed", file->data);
+        return NGX_ERROR;
+    }
+
+    response = d2i_OCSP_RESPONSE_bio(bio, NULL);
+    if (response == NULL) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "d2i_OCSP_RESPONSE_bio(\"%s\") failed", file->data);
+        BIO_free(bio);
+        return NGX_ERROR;
+    }
+
+    len = i2d_OCSP_RESPONSE(response, NULL);
+    if (len <= 0) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "i2d_OCSP_RESPONSE(\"%s\") failed", file->data);
+        goto failed;
+    }
+
+    buf = ngx_alloc(len, ssl->log);
+    if (buf == NULL) {
+        goto failed;
+    }
+
+    p = buf;
+    len = i2d_OCSP_RESPONSE(response, &p);
+    if (len <= 0) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "i2d_OCSP_RESPONSE(\"%s\") failed", file->data);
+        ngx_free(buf);
+        goto failed;
+    }
+
+    OCSP_RESPONSE_free(response);
+    BIO_free(bio);
+
+    staple->staple.data = buf;
+    staple->staple.len = len;
+
+    return NGX_OK;
+
+failed:
+
+    OCSP_RESPONSE_free(response);
+    BIO_free(bio);
+
+    return NGX_ERROR;
+}
+
+
+static ngx_int_t
+ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl)
+{
+    int                  i, n, rc;
+    X509                *cert, *issuer;
+    X509_STORE          *store;
+    X509_STORE_CTX      *store_ctx;
+    STACK_OF(X509)      *chain;
+    ngx_ssl_stapling_t  *staple;
+
+    staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
+    cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
+
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L
+    SSL_CTX_get_extra_chain_certs(ssl->ctx, &chain);
+#else
+    chain = ssl->ctx->extra_certs;
+#endif
+
+    n = sk_X509_num(chain);
+
+    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0,
+                   "SSL get issuer: %d extra certs", n);
+
+    for (i = 0; i < n; i++) {
+        issuer = sk_X509_value(chain, i);
+        if (X509_check_issued(issuer, cert) == X509_V_OK) {
+            CRYPTO_add(&issuer->references, 1, CRYPTO_LOCK_X509);
+
+            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0,
+                           "SSL get issuer: found %p in extra certs", issuer);
+
+            staple->cert = cert;
+            staple->issuer = issuer;
+
+            return NGX_OK;
+        }
+    }
+
+    store = SSL_CTX_get_cert_store(ssl->ctx);
+    if (store == NULL) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "SSL_CTX_get_cert_store() failed");
+        return NGX_ERROR;
+    }
+
+    store_ctx = X509_STORE_CTX_new();
+    if (store_ctx == NULL) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "X509_STORE_CTX_new() failed");
+        return NGX_ERROR;
+    }
+
+    if (X509_STORE_CTX_init(store_ctx, store, NULL, NULL) == 0) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "X509_STORE_CTX_init() failed");
+        return NGX_ERROR;
+    }
+
+    rc = X509_STORE_CTX_get1_issuer(&issuer, store_ctx, cert);
+
+    if (rc == -1) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "X509_STORE_CTX_get1_issuer() failed");
+        X509_STORE_CTX_free(store_ctx);
+        return NGX_ERROR;
+    }
+
+    if (rc == 0) {
+        ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
+                      "\"ssl_stapling\" ignored, issuer certificate not found");
+        X509_STORE_CTX_free(store_ctx);
+        return NGX_DECLINED;
+    }
+
+    X509_STORE_CTX_free(store_ctx);
+
+    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0,
+                   "SSL get issuer: found %p in cert store", issuer);
+
+    staple->cert = cert;
+    staple->issuer = issuer;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder)
+{
+    ngx_url_t                  u;
+    char                      *s;
+    ngx_ssl_stapling_t        *staple;
+    STACK_OF(OPENSSL_STRING)  *aia;
+
+    staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
+
+    if (responder->len == 0) {
+
+        /* extract OCSP responder URL from certificate */
+
+        aia = X509_get1_ocsp(staple->cert);
+        if (aia == NULL) {
+            ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
+                          "\"ssl_stapling\" ignored, "
+                          "no OCSP responder URL in the certificate");
+            return NGX_DECLINED;
+        }
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+        s = sk_OPENSSL_STRING_value(aia, 0);
+#else
+        s = sk_value(aia, 0);
+#endif
+        if (s == NULL) {
+            ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
+                          "\"ssl_stapling\" ignored, "
+                          "no OCSP responder URL in the certificate");
+            X509_email_free(aia);
+            return NGX_DECLINED;
+        }
+
+        responder->len = ngx_strlen(s);
+        responder->data = ngx_palloc(cf->pool, responder->len);
+        if (responder->data == NULL) {
+            X509_email_free(aia);
+            return NGX_ERROR;
+        }
+
+        ngx_memcpy(responder->data, s, responder->len);
+        X509_email_free(aia);
+    }
+
+    ngx_memzero(&u, sizeof(ngx_url_t));
+
+    u.url = *responder;
+    u.default_port = 80;
+    u.uri_part = 1;
+
+    if (u.url.len > 7
+        && ngx_strncasecmp(u.url.data, (u_char *) "http://", 7) == 0)
+    {
+        u.url.len -= 7;
+        u.url.data += 7;
+
+    } else {
+        ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
+                      "\"ssl_stapling\" ignored, "
+                      "invalid URL prefix in OCSP responder \"%V\"", &u.url);
+        return NGX_DECLINED;
+    }
+
+    if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
+        if (u.err) {
+            ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
+                          "\"ssl_stapling\" ignored, "
+                          "%s in OCSP responder \"%V\"", u.err, &u.url);
+            return NGX_DECLINED;
+        }
+
+        return NGX_ERROR;
+    }
+
+    staple->addrs = u.addrs;
+    staple->host = u.host;
+    staple->uri = u.uri;
+    staple->port = u.port;
+
+    if (staple->uri.len == 0) {
+        ngx_str_set(&staple->uri, "/");
+    }
+
+    return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
+    ngx_resolver_t *resolver, ngx_msec_t resolver_timeout)
+{
+    ngx_ssl_stapling_t  *staple;
+
+    staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
+
+    staple->resolver = resolver;
+    staple->resolver_timeout = resolver_timeout;
+
+    return NGX_OK;
+}
+
+
+static int
+ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn, void *data)
+{
+    int                  rc;
+    u_char              *p;
+    ngx_connection_t    *c;
+    ngx_ssl_stapling_t  *staple;
+
+    c = ngx_ssl_get_connection(ssl_conn);
+
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                   "SSL certificate status callback");
+
+    staple = data;
+    rc = SSL_TLSEXT_ERR_NOACK;
+
+    if (staple->staple.len) {
+        /* we have to copy ocsp response as OpenSSL will free it by itself */
+
+        p = OPENSSL_malloc(staple->staple.len);
+        if (p == NULL) {
+            ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "OPENSSL_malloc() failed");
+            return SSL_TLSEXT_ERR_NOACK;
+        }
+
+        ngx_memcpy(p, staple->staple.data, staple->staple.len);
+
+        SSL_set_tlsext_status_ocsp_resp(ssl_conn, p, staple->staple.len);
+
+        rc = SSL_TLSEXT_ERR_OK;
+    }
+
+    ngx_ssl_stapling_update(staple);
+
+    return rc;
+}
+
+
+static void
+ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple)
+{
+    ngx_ssl_ocsp_ctx_t  *ctx;
+
+    if (staple->host.len == 0
+        || staple->loading || staple->valid >= ngx_time())
+    {
+        return;
+    }
+
+    staple->loading = 1;
+
+    ctx = ngx_ssl_ocsp_start();
+    if (ctx == NULL) {
+        return;
+    }
+
+    ctx->cert = staple->cert;
+    ctx->issuer = staple->issuer;
+
+    ctx->addrs = staple->addrs;
+    ctx->host = staple->host;
+    ctx->uri = staple->uri;
+    ctx->port = staple->port;
+    ctx->timeout = staple->timeout;
+
+    ctx->resolver = staple->resolver;
+    ctx->resolver_timeout = staple->resolver_timeout;
+
+    ctx->handler = ngx_ssl_stapling_ocsp_handler;
+    ctx->data = staple;
+
+    ngx_ssl_ocsp_request(ctx);
+
+    return;
+}
+
+
+static void
+ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x0090707fL
+    const
+#endif
+    u_char                *p;
+    int                    n;
+    size_t                 len;
+    ngx_str_t              response;
+    X509_STORE            *store;
+    STACK_OF(X509)        *chain;
+    OCSP_CERTID           *id;
+    OCSP_RESPONSE         *ocsp;
+    OCSP_BASICRESP        *basic;
+    ngx_ssl_stapling_t    *staple;
+    ASN1_GENERALIZEDTIME  *thisupdate, *nextupdate;
+
+    staple = ctx->data;
+    ocsp = NULL;
+    basic = NULL;
+    id = NULL;
+
+    if (ctx->code != 200) {
+        goto error;
+    }
+
+    /* check the response */
+
+    len = ctx->response->last - ctx->response->pos;
+    p = ctx->response->pos;
+
+    ocsp = d2i_OCSP_RESPONSE(NULL, &p, len);
+    if (ocsp == NULL) {
+        ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
+                      "d2i_OCSP_RESPONSE() failed");
+        goto error;
+    }
+
+    n = OCSP_response_status(ocsp);
+
+    if (n != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+        ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
+                      "OCSP response not successful (%d: %s)",
+                      n, OCSP_response_status_str(n));
+        goto error;
+    }
+
+    basic = OCSP_response_get1_basic(ocsp);
+    if (basic == NULL) {
+        ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
+                      "OCSP_response_get1_basic() failed");
+        goto error;
+    }
+
+    store = SSL_CTX_get_cert_store(staple->ssl_ctx);
+    if (store == NULL) {
+        ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
+                      "SSL_CTX_get_cert_store() failed");
+        goto error;
+    }
+
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L
+    SSL_CTX_get_extra_chain_certs(staple->ssl_ctx, &chain);
+#else
+    chain = staple->ssl_ctx->extra_certs;
+#endif
+
+    if (OCSP_basic_verify(basic, chain, store,
+                          staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY)
+        != 1)
+    {
+        ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
+                      "OCSP_basic_verify() failed");
+        goto error;
+    }
+
+    id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer);
+    if (id == NULL) {
+        ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
+                      "OCSP_cert_to_id() failed");
+        goto error;
+    }
+
+    if (OCSP_resp_find_status(basic, id, &n, NULL, NULL,
+                              &thisupdate, &nextupdate)
+        != 1)
+    {
+        ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
+                      "certificate status not found in the OCSP response");
+        goto error;
+    }
+
+    if (n != V_OCSP_CERTSTATUS_GOOD) {
+        ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
+                      "certificate status \"%s\" in the OCSP response",
+                      OCSP_cert_status_str(n));
+        goto error;
+    }
+
+    if (OCSP_check_validity(thisupdate, nextupdate, 300, -1) != 1) {
+        ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
+                      "OCSP_check_validity() failed");
+        goto error;
+    }
+
+    OCSP_CERTID_free(id);
+    OCSP_BASICRESP_free(basic);
+    OCSP_RESPONSE_free(ocsp);
+
+    /* copy the response to memory not in ctx->pool */
+
+    response.len = len;
+    response.data = ngx_alloc(response.len, ctx->log);
+
+    if (response.data == NULL) {
+        goto done;
+    }
+
+    ngx_memcpy(response.data, ctx->response->pos, response.len);
+
+    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                   "ssl ocsp response, %s, %uz",
+                   OCSP_cert_status_str(n), response.len);
+
+    if (staple->staple.data) {
+        ngx_free(staple->staple.data);
+    }
+
+    staple->staple = response;
+
+done:
+
+    staple->loading = 0;
+    staple->valid = ngx_time() + 3600; /* ssl_stapling_valid */
+
+    ngx_ssl_ocsp_done(ctx);
+    return;
+
+error:
+
+    staple->loading = 0;
+    staple->valid = ngx_time() + 300; /* ssl_stapling_err_valid */
+
+    if (id) {
+        OCSP_CERTID_free(id);
+    }
+
+    if (basic) {
+        OCSP_BASICRESP_free(basic);
+    }
+
+    if (ocsp) {
+        OCSP_RESPONSE_free(ocsp);
+    }
+
+    ngx_ssl_ocsp_done(ctx);
+}
+
+
+static void
+ngx_ssl_stapling_cleanup(void *data)
+{
+    ngx_ssl_stapling_t  *staple = data;
+
+    if (staple->issuer) {
+        X509_free(staple->issuer);
+    }
+
+    if (staple->staple.data) {
+        ngx_free(staple->staple.data);
+    }
+}
+
+
+static ngx_ssl_ocsp_ctx_t *
+ngx_ssl_ocsp_start(void)
+{
+    ngx_log_t           *log;
+    ngx_pool_t          *pool;
+    ngx_ssl_ocsp_ctx_t  *ctx;
+
+    pool = ngx_create_pool(2048, ngx_cycle->log);
+    if (pool == NULL) {
+        return NULL;
+    }
+
+    ctx = ngx_pcalloc(pool, sizeof(ngx_ssl_ocsp_ctx_t));
+    if (ctx == NULL) {
+        ngx_destroy_pool(pool);
+        return NULL;
+    }
+
+    log = ngx_palloc(pool, sizeof(ngx_log_t));
+    if (log == NULL) {
+        ngx_destroy_pool(pool);
+        return NULL;
+    }
+
+    ctx->pool = pool;
+
+    *log = *ctx->pool->log;
+
+    ctx->pool->log = log;
+    ctx->log = log;
+
+    log->handler = ngx_ssl_ocsp_log_error;
+    log->data = ctx;
+    log->action = "requesting certificate status";
+
+    return ctx;
+}
+
+
+static void
+ngx_ssl_ocsp_done(ngx_ssl_ocsp_ctx_t *ctx)
+{
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                   "ssl ocsp done");
+
+    if (ctx->peer.connection) {
+        ngx_close_connection(ctx->peer.connection);
+    }
+
+    ngx_destroy_pool(ctx->pool);
+}
+
+
+static void
+ngx_ssl_ocsp_error(ngx_ssl_ocsp_ctx_t *ctx)
+{
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                   "ssl ocsp error");
+
+    ctx->code = 0;
+    ctx->handler(ctx);
+}
+
+
+static void
+ngx_ssl_ocsp_request(ngx_ssl_ocsp_ctx_t *ctx)
+{
+    ngx_resolver_ctx_t  *resolve, temp;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                   "ssl ocsp request");
+
+    if (ngx_ssl_ocsp_create_request(ctx) != NGX_OK) {
+        ngx_ssl_ocsp_error(ctx);
+        return;
+    }
+
+    if (ctx->resolver) {
+        /* resolve OCSP responder hostname */
+
+        temp.name = ctx->host;
+
+        resolve = ngx_resolve_start(ctx->resolver, &temp);
+        if (resolve == NULL) {
+            ngx_ssl_ocsp_error(ctx);
+            return;
+        }
+
+        if (resolve == NGX_NO_RESOLVER) {
+            ngx_log_error(NGX_LOG_WARN, ctx->log, 0,
+                          "no resolver defined to resolve %V", &ctx->host);
+            goto connect;
+        }
+
+        resolve->name = ctx->host;
+        resolve->type = NGX_RESOLVE_A;
+        resolve->handler = ngx_ssl_ocsp_resolve_handler;
+        resolve->data = ctx;
+        resolve->timeout = ctx->resolver_timeout;
+
+        if (ngx_resolve_name(resolve) != NGX_OK) {
+            ngx_ssl_ocsp_error(ctx);
+            return;
+        }
+
+        return;
+    }
+
+connect:
+
+    ngx_ssl_ocsp_connect(ctx);
+}
+
+
+static void
+ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve)
+{
+    ngx_ssl_ocsp_ctx_t *ctx = resolve->data;
+
+    u_char              *p;
+    size_t               len;
+    in_port_t            port;
+    ngx_uint_t           i;
+    struct sockaddr_in  *sin;
+
+    ngx_log_debug0(NGX_LOG_ALERT, ctx->log, 0,
+                   "ssl ocsp resolve handler");
+
+    if (resolve->state) {
+        ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
+                      "%V could not be resolved (%i: %s)",
+                      &resolve->name, resolve->state,
+                      ngx_resolver_strerror(resolve->state));
+        goto failed;
+    }
+
+#if (NGX_DEBUG)
+    {
+    in_addr_t   addr;
+
+    for (i = 0; i < resolve->naddrs; i++) {
+        addr = ntohl(resolve->addrs[i]);
+
+        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
+
+    ctx->naddrs = resolve->naddrs;
+    ctx->addrs = ngx_pcalloc(ctx->pool, ctx->naddrs * sizeof(ngx_addr_t));
+
+    if (ctx->addrs == NULL) {
+        goto failed;
+    }
+
+    port = htons(ctx->port);
+
+    for (i = 0; i < resolve->naddrs; i++) {
+
+        sin = ngx_pcalloc(ctx->pool, sizeof(struct sockaddr_in));
+        if (sin == NULL) {
+            goto failed;
+        }
+
+        sin->sin_family = AF_INET;
+        sin->sin_port = port;
+        sin->sin_addr.s_addr = resolve->addrs[i];
+
+        ctx->addrs[i].sockaddr = (struct sockaddr *) sin;
+        ctx->addrs[i].socklen = sizeof(struct sockaddr_in);
+
+        len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
+
+        p = ngx_pnalloc(ctx->pool, len);
+        if (p == NULL) {
+            goto failed;
+        }
+
+        len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1);
+
+        ctx->addrs[i].name.len = len;
+        ctx->addrs[i].name.data = p;
+    }
+
+    ngx_resolve_name_done(resolve);
+
+    ngx_ssl_ocsp_connect(ctx);
+    return;
+
+failed:
+
+    ngx_resolve_name_done(resolve);
+    ngx_ssl_ocsp_error(ctx);
+}
+
+
+static void
+ngx_ssl_ocsp_connect(ngx_ssl_ocsp_ctx_t *ctx)
+{
+    ngx_int_t    rc;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                   "ssl ocsp connect");
+
+    /* TODO: use all ip addresses */
+
+    ctx->peer.sockaddr = ctx->addrs[0].sockaddr;
+    ctx->peer.socklen = ctx->addrs[0].socklen;
+    ctx->peer.name = &ctx->addrs[0].name;
+    ctx->peer.get = ngx_event_get_peer;
+    ctx->peer.log = ctx->log;
+    ctx->peer.log_error = NGX_ERROR_ERR;
+
+    rc = ngx_event_connect_peer(&ctx->peer);
+
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                   "ssl ocsp connect peer done");
+
+    if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {
+        ngx_ssl_ocsp_error(ctx);
+        return;
+    }
+
+    ctx->peer.connection->data = ctx;
+    ctx->peer.connection->pool = ctx->pool;
+
+    ctx->peer.connection->read->handler = ngx_ssl_ocsp_read_handler;
+    ctx->peer.connection->write->handler = ngx_ssl_ocsp_write_handler;
+
+    ctx->process = ngx_ssl_ocsp_process_status_line;
+
+    ngx_add_timer(ctx->peer.connection->read, ctx->timeout);
+    ngx_add_timer(ctx->peer.connection->write, ctx->timeout);
+
+    if (rc == NGX_OK) {
+        ngx_ssl_ocsp_write_handler(ctx->peer.connection->write);
+        return;
+    }
+}
+
+
+static void
+ngx_ssl_ocsp_write_handler(ngx_event_t *wev)
+{
+    ssize_t              n, size;
+    ngx_connection_t    *c;
+    ngx_ssl_ocsp_ctx_t  *ctx;
+
+    c = wev->data;
+    ctx = c->data;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, wev->log, 0,
+                   "ssl ocsp write handler");
+
+    if (wev->timedout) {
+        ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT,
+                      "OCSP responder timed out");
+        ngx_ssl_ocsp_error(ctx);
+        return;
+    }
+
+    size = ctx->request->last - ctx->request->pos;
+
+    n = ngx_send(c, ctx->request->pos, size);
+
+    if (n == NGX_ERROR) {
+        ngx_ssl_ocsp_error(ctx);
+        return;
+    }
+
+    if (n > 0) {
+        ctx->request->pos += n;
+
+        if (n == size) {
+            wev->handler = ngx_ssl_ocsp_dummy_handler;
+
+            if (wev->timer_set) {
+                ngx_del_timer(wev);
+            }
+
+            if (ngx_handle_write_event(wev, 0) != NGX_OK) {
+                ngx_ssl_ocsp_error(ctx);
+            }
+
+            return;
+        }
+    }
+
+    if (!wev->timer_set) {
+        ngx_add_timer(wev, ctx->timeout);
+    }
+}
+
+
+static void
+ngx_ssl_ocsp_read_handler(ngx_event_t *rev)
+{
+    ssize_t            n, size;
+    ngx_int_t          rc;
+    ngx_ssl_ocsp_ctx_t    *ctx;
+    ngx_connection_t  *c;
+
+    c = rev->data;
+    ctx = c->data;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, rev->log, 0,
+                   "ssl ocsp read handler");
+
+    if (rev->timedout) {
+        ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
+                      "OCSP responder timed out");
+        ngx_ssl_ocsp_error(ctx);
+        return;
+    }
+
+    if (ctx->response == NULL) {
+        ctx->response = ngx_create_temp_buf(ctx->pool, 16384);
+        if (ctx->response == NULL) {
+            ngx_ssl_ocsp_error(ctx);
+            return;
+        }
+    }
+
+    for ( ;; ) {
+
+        size = ctx->response->end - ctx->response->last;
+
+        n = ngx_recv(c, ctx->response->last, size);
+
+        if (n > 0) {
+            ctx->response->last += n;
+
+            rc = ctx->process(ctx);
+
+            if (rc == NGX_ERROR) {
+                ngx_ssl_ocsp_error(ctx);
+                return;
+            }
+
+            continue;
+        }
+
+        if (n == NGX_AGAIN) {
+
+            if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+                ngx_ssl_ocsp_error(ctx);
+            }
+
+            return;
+        }
+
+        break;
+    }
+
+    ctx->done = 1;
+
+    rc = ctx->process(ctx);
+
+    if (rc == NGX_DONE) {
+        /* ctx->handler() was called */
+        return;
+    }
+
+    ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
+                  "OCSP responder prematurely closed connection");
+
+    ngx_ssl_ocsp_error(ctx);
+}
+
+
+static void
+ngx_ssl_ocsp_dummy_handler(ngx_event_t *ev)
+{
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0,
+                   "ssl ocsp dummy handler");
+}
+
+
+static ngx_int_t
+ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx)
+{
+    int            len;
+    u_char        *p;
+    uintptr_t      escape;
+    ngx_str_t      binary, base64;
+    ngx_buf_t     *b;
+    OCSP_CERTID   *id;
+    OCSP_REQUEST  *ocsp;
+
+    ocsp = OCSP_REQUEST_new();
+    if (ocsp == NULL) {
+        ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
+                      "OCSP_REQUEST_new() failed");
+        return NGX_ERROR;
+    }
+
+    id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer);
+    if (id == NULL) {
+        ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
+                      "OCSP_cert_to_id() failed");
+        goto failed;
+    }
+
+    if (OCSP_request_add0_id(ocsp, id) == NULL) {
+        ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
+                      "OCSP_request_add0_id() failed");
+        goto failed;
+    }
+
+    len = i2d_OCSP_REQUEST(ocsp, NULL);
+    if (len <= 0) {
+        ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
+                      "i2d_OCSP_REQUEST() failed");
+        goto failed;
+    }
+
+    binary.len = len;
+    binary.data = ngx_palloc(ctx->pool, len);
+    if (binary.data == NULL) {
+        goto failed;
+    }
+
+    p = binary.data;
+    len = i2d_OCSP_REQUEST(ocsp, &p);
+    if (len <= 0) {
+        ngx_ssl_error(NGX_LOG_EMERG, ctx->log, 0,
+                      "i2d_OCSP_REQUEST() failed");
+        goto failed;
+    }
+
+    base64.len = ngx_base64_encoded_length(binary.len);
+    base64.data = ngx_palloc(ctx->pool, base64.len);
+    if (base64.data == NULL) {
+        goto failed;
+    }
+
+    ngx_encode_base64(&base64, &binary);
+
+    escape = ngx_escape_uri(NULL, base64.data, base64.len,
+                            NGX_ESCAPE_URI_COMPONENT);
+
+    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                   "ssl ocsp request length %z, escape %d",
+                   base64.len, escape);
+
+    len = sizeof("GET ") - 1 + ctx->uri.len + sizeof("/") - 1
+          + base64.len + 2 * escape + sizeof(" HTTP/1.0" CRLF) - 1
+          + sizeof("Host: ") - 1 + ctx->host.len + sizeof(CRLF) - 1
+          + sizeof(CRLF) - 1;
+
+    b = ngx_create_temp_buf(ctx->pool, len);
+    if (b == NULL) {
+        goto failed;
+    }
+
+    p = b->last;
+
+    p = ngx_cpymem(p, "GET ", sizeof("GET ") - 1);
+    p = ngx_cpymem(p, ctx->uri.data, ctx->uri.len);
+
+    if (ctx->uri.data[ctx->uri.len - 1] != '/') {
+        *p++ = '/';
+    }
+
+    if (escape == 0) {
+        p = ngx_cpymem(p, base64.data, base64.len);
+
+    } else {
+        p = (u_char *) ngx_escape_uri(p, base64.data, base64.len,
+                                      NGX_ESCAPE_URI_COMPONENT);
+    }
+
+    p = ngx_cpymem(p, " HTTP/1.0" CRLF, sizeof(" HTTP/1.0" CRLF) - 1);
+    p = ngx_cpymem(p, "Host: ", sizeof("Host: ") - 1);
+    p = ngx_cpymem(p, ctx->host.data, ctx->host.len);
+    *p++ = CR; *p++ = LF;
+
+    /* add "\r\n" at the header end */
+    *p++ = CR; *p++ = LF;
+
+    b->last = p;
+    ctx->request = b;
+
+    return NGX_OK;
+
+failed:
+
+    OCSP_REQUEST_free(ocsp);
+
+    return NGX_ERROR;
+}
+
+
+static ngx_int_t
+ngx_ssl_ocsp_process_status_line(ngx_ssl_ocsp_ctx_t *ctx)
+{
+    ngx_int_t  rc;
+
+    rc = ngx_ssl_ocsp_parse_status_line(ctx);
+
+    if (rc == NGX_OK) {
+#if 0
+        ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                       "ssl ocsp status line \"%*s\"",
+                       ctx->response->pos - ctx->response->start,
+                       ctx->response->start);
+#endif
+
+        ctx->process = ngx_ssl_ocsp_process_headers;
+        return ctx->process(ctx);
+    }
+
+    if (rc == NGX_AGAIN) {
+        return NGX_AGAIN;
+    }
+
+    /* rc == NGX_ERROR */
+
+    ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
+                  "OCSP responder sent invalid response");
+
+    return NGX_ERROR;
+}
+
+
+static ngx_int_t
+ngx_ssl_ocsp_parse_status_line(ngx_ssl_ocsp_ctx_t *ctx)
+{
+    u_char      ch;
+    u_char     *p;
+    ngx_buf_t  *b;
+    enum {
+        sw_start = 0,
+        sw_H,
+        sw_HT,
+        sw_HTT,
+        sw_HTTP,
+        sw_first_major_digit,
+        sw_major_digit,
+        sw_first_minor_digit,
+        sw_minor_digit,
+        sw_status,
+        sw_space_after_status,
+        sw_status_text,
+        sw_almost_done
+    } state;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                   "ssl ocsp process status line");
+
+    state = ctx->state;
+    b = ctx->response;
+
+    for (p = b->pos; p < b->last; p++) {
+        ch = *p;
+
+        switch (state) {
+
+        /* "HTTP/" */
+        case sw_start:
+            switch (ch) {
+            case 'H':
+                state = sw_H;
+                break;
+            default:
+                return NGX_ERROR;
+            }
+            break;
+
+        case sw_H:
+            switch (ch) {
+            case 'T':
+                state = sw_HT;
+                break;
+            default:
+                return NGX_ERROR;
+            }
+            break;
+
+        case sw_HT:
+            switch (ch) {
+            case 'T':
+                state = sw_HTT;
+                break;
+            default:
+                return NGX_ERROR;
+            }
+            break;
+
+        case sw_HTT:
+            switch (ch) {
+            case 'P':
+                state = sw_HTTP;
+                break;
+            default:
+                return NGX_ERROR;
+            }
+            break;
+
+        case sw_HTTP:
+            switch (ch) {
+            case '/':
+                state = sw_first_major_digit;
+                break;
+            default:
+                return NGX_ERROR;
+            }
+            break;
+
+        /* the first digit of major HTTP version */
+        case sw_first_major_digit:
+            if (ch < '1' || ch > '9') {
+                return NGX_ERROR;
+            }
+
+            state = sw_major_digit;
+            break;
+
+        /* the major HTTP version or dot */
+        case sw_major_digit:
+            if (ch == '.') {
+                state = sw_first_minor_digit;
+                break;
+            }
+
+            if (ch < '0' || ch > '9') {
+                return NGX_ERROR;
+            }
+
+            break;
+
+        /* the first digit of minor HTTP version */
+        case sw_first_minor_digit:
+            if (ch < '0' || ch > '9') {
+                return NGX_ERROR;
+            }
+
+            state = sw_minor_digit;
+            break;
+
+        /* the minor HTTP version or the end of the request line */
+        case sw_minor_digit:
+            if (ch == ' ') {
+                state = sw_status;
+                break;
+            }
+
+            if (ch < '0' || ch > '9') {
+                return NGX_ERROR;
+            }
+
+            break;
+
+        /* HTTP status code */
+        case sw_status:
+            if (ch == ' ') {
+                break;
+            }
+
+            if (ch < '0' || ch > '9') {
+                return NGX_ERROR;
+            }
+
+            ctx->code = ctx->code * 10 + ch - '0';
+
+            if (++ctx->count == 3) {
+                state = sw_space_after_status;
+            }
+
+            break;
+
+        /* space or end of line */
+        case sw_space_after_status:
+            switch (ch) {
+            case ' ':
+                state = sw_status_text;
+                break;
+            case '.':                    /* IIS may send 403.1, 403.2, etc */
+                state = sw_status_text;
+                break;
+            case CR:
+                state = sw_almost_done;
+                break;
+            case LF:
+                goto done;
+            default:
+                return NGX_ERROR;
+            }
+            break;
+
+        /* any text until end of line */
+        case sw_status_text:
+            switch (ch) {
+            case CR:
+                state = sw_almost_done;
+                break;
+            case LF:
+                goto done;
+            }
+            break;
+
+        /* end of status line */
+        case sw_almost_done:
+            switch (ch) {
+            case LF:
+                goto done;
+            default:
+                return NGX_ERROR;
+            }
+        }
+    }
+
+    b->pos = p;
+    ctx->state = state;
+
+    return NGX_AGAIN;
+
+done:
+
+    b->pos = p + 1;
+    ctx->state = sw_start;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_ssl_ocsp_process_headers(ngx_ssl_ocsp_ctx_t *ctx)
+{
+    size_t     len;
+    ngx_int_t  rc;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                   "ssl ocsp process headers");
+
+    for ( ;; ) {
+        rc = ngx_ssl_ocsp_parse_header_line(ctx);
+
+        if (rc == NGX_OK) {
+
+            ngx_log_debug4(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                           "ssl ocsp header \"%*s: %*s\"",
+                           ctx->header_name_end - ctx->header_name_start,
+                           ctx->header_name_start,
+                           ctx->header_end - ctx->header_start,
+                           ctx->header_start);
+
+            len = ctx->header_name_end - ctx->header_name_start;
+
+            if (len == sizeof("Content-Type") - 1
+                && ngx_strncasecmp(ctx->header_name_start,
+                                   (u_char *) "Content-Type",
+                                   sizeof("Content-Type") - 1)
+                   == 0)
+            {
+                len = ctx->header_end - ctx->header_start;
+
+                if (len != sizeof("application/ocsp-response") - 1
+                    || ngx_strncasecmp(ctx->header_start,
+                                       (u_char *) "application/ocsp-response",
+                                       sizeof("application/ocsp-response") - 1)
+                       != 0)
+                {
+                    ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
+                                  "OCSP responder sent invalid "
+                                  "\"Content-Type\" header: \"%*s\"",
+                                  ctx->header_end - ctx->header_start,
+                                  ctx->header_start);
+                    return NGX_ERROR;
+                }
+
+                continue;
+            }
+
+            /* TODO: honor Content-Length */
+
+            continue;
+        }
+
+        if (rc == NGX_DONE) {
+            break;
+        }
+
+        if (rc == NGX_AGAIN) {
+            return NGX_AGAIN;
+        }
+
+        /* rc == NGX_ERROR */
+
+        ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
+                      "OCSP responder sent invalid response");
+
+        return NGX_ERROR;
+    }
+
+    ctx->process = ngx_ssl_ocsp_process_body;
+    return ctx->process(ctx);
+}
+
+static ngx_int_t
+ngx_ssl_ocsp_parse_header_line(ngx_ssl_ocsp_ctx_t *ctx)
+{
+    u_char      c, ch, *p;
+    enum {
+        sw_start = 0,
+        sw_name,
+        sw_space_before_value,
+        sw_value,
+        sw_space_after_value,
+        sw_almost_done,
+        sw_header_almost_done
+    } state;
+
+    state = ctx->state;
+
+    for (p = ctx->response->pos; p < ctx->response->last; p++) {
+        ch = *p;
+
+#if 0
+        ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                       "s:%d in:'%02Xd:%c'", state, ch, ch);
+#endif
+
+        switch (state) {
+
+        /* first char */
+        case sw_start:
+
+            switch (ch) {
+            case CR:
+                ctx->header_end = p;
+                state = sw_header_almost_done;
+                break;
+            case LF:
+                ctx->header_end = p;
+                goto header_done;
+            default:
+                state = sw_name;
+                ctx->header_name_start = p;
+
+                c = (u_char) (ch | 0x20);
+                if (c >= 'a' && c <= 'z') {
+                    break;
+                }
+
+                if (ch >= '0' && ch <= '9') {
+                    break;
+                }
+
+                return NGX_ERROR;
+            }
+            break;
+
+        /* header name */
+        case sw_name:
+            c = (u_char) (ch | 0x20);
+            if (c >= 'a' && c <= 'z') {
+                break;
+            }
+
+            if (ch == ':') {
+                ctx->header_name_end = p;
+                state = sw_space_before_value;
+                break;
+            }
+
+            if (ch == '-') {
+                break;
+            }
+
+            if (ch >= '0' && ch <= '9') {
+                break;
+            }
+
+            if (ch == CR) {
+                ctx->header_name_end = p;
+                ctx->header_start = p;
+                ctx->header_end = p;
+                state = sw_almost_done;
+                break;
+            }
+
+            if (ch == LF) {
+                ctx->header_name_end = p;
+                ctx->header_start = p;
+                ctx->header_end = p;
+                goto done;
+            }
+
+            return NGX_ERROR;
+
+        /* space* before header value */
+        case sw_space_before_value:
+            switch (ch) {
+            case ' ':
+                break;
+            case CR:
+                ctx->header_start = p;
+                ctx->header_end = p;
+                state = sw_almost_done;
+                break;
+            case LF:
+                ctx->header_start = p;
+                ctx->header_end = p;
+                goto done;
+            default:
+                ctx->header_start = p;
+                state = sw_value;
+                break;
+            }
+            break;
+
+        /* header value */
+        case sw_value:
+            switch (ch) {
+            case ' ':
+                ctx->header_end = p;
+                state = sw_space_after_value;
+                break;
+            case CR:
+                ctx->header_end = p;
+                state = sw_almost_done;
+                break;
+            case LF:
+                ctx->header_end = p;
+                goto done;
+            }
+            break;
+
+        /* space* before end of header line */
+        case sw_space_after_value:
+            switch (ch) {
+            case ' ':
+                break;
+            case CR:
+                state = sw_almost_done;
+                break;
+            case LF:
+                goto done;
+            default:
+                state = sw_value;
+                break;
+            }
+            break;
+
+        /* end of header line */
+        case sw_almost_done:
+            switch (ch) {
+            case LF:
+                goto done;
+            default:
+                return NGX_ERROR;
+            }
+
+        /* end of header */
+        case sw_header_almost_done:
+            switch (ch) {
+            case LF:
+                goto header_done;
+            default:
+                return NGX_ERROR;
+            }
+        }
+    }
+
+    ctx->response->pos = p;
+    ctx->state = state;
+
+    return NGX_AGAIN;
+
+done:
+
+    ctx->response->pos = p + 1;
+    ctx->state = sw_start;
+
+    return NGX_OK;
+
+header_done:
+
+    ctx->response->pos = p + 1;
+    ctx->state = sw_start;
+
+    return NGX_DONE;
+}
+
+
+static ngx_int_t
+ngx_ssl_ocsp_process_body(ngx_ssl_ocsp_ctx_t *ctx)
+{
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+                   "ssl ocsp process body");
+
+    if (ctx->done) {
+        ctx->handler(ctx);
+        return NGX_DONE;
+    }
+
+    return NGX_AGAIN;
+}
+
+
+static u_char *
+ngx_ssl_ocsp_log_error(ngx_log_t *log, u_char *buf, size_t len)
+{
+    u_char              *p;
+    ngx_ssl_ocsp_ctx_t  *ctx;
+
+    p = buf;
+
+    if (log->action) {
+        p = ngx_snprintf(buf, len, " while %s", log->action);
+        len -= p - buf;
+    }
+
+    ctx = log->data;
+
+    if (ctx) {
+        p = ngx_snprintf(p, len, ", responder: %V", &ctx->host);
+    }
+
+    return p;
+}
+
+
+#else
+
+
+ngx_int_t
+ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file,
+    ngx_str_t *responder, ngx_uint_t verify)
+{
+    ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
+                  "\"ssl_stapling\" ignored, not supported");
+
+    return NGX_OK;
+}
+
+ngx_int_t
+ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
+    ngx_resolver_t *resolver, ngx_msec_t resolver_timeout)
+{
+    return NGX_OK;
+}
+
+
+#endif

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

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

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

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

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

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

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

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_addition_filter_module.c (+1 -0) 99%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_addition_filter_module.c    2013-07-22 11:05:55 +0900 (24747c5)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_addition_filter_module.c    2013-07-22 13:32:39 +0900 (f598cea)
@@ -121,6 +121,7 @@ ngx_http_addition_header_filter(ngx_http_request_t *r)
 
     ngx_http_clear_content_length(r);
     ngx_http_clear_accept_ranges(r);
+    ngx_http_clear_etag(r);
 
     return ngx_http_next_header_filter(r);
 }

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_auth_basic_module.c (+38 -49) 90%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_auth_basic_module.c    2013-07-22 11:05:55 +0900 (ec3b1cf)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_auth_basic_module.c    2013-07-22 13:32:39 +0900 (e8709e5)
@@ -20,8 +20,8 @@ typedef struct {
 
 
 typedef struct {
-    ngx_str_t                 realm;
-    ngx_http_complex_value_t  user_file;
+    ngx_http_complex_value_t  *realm;
+    ngx_http_complex_value_t   user_file;
 } ngx_http_auth_basic_loc_conf_t;
 
 
@@ -35,22 +35,19 @@ static void *ngx_http_auth_basic_create_loc_conf(ngx_conf_t *cf);
 static char *ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf,
     void *parent, void *child);
 static ngx_int_t ngx_http_auth_basic_init(ngx_conf_t *cf);
-static char *ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data);
 static char *ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
 
 
-static ngx_conf_post_handler_pt  ngx_http_auth_basic_p = ngx_http_auth_basic;
-
 static ngx_command_t  ngx_http_auth_basic_commands[] = {
 
     { ngx_string("auth_basic"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF
                         |NGX_CONF_TAKE1,
-      ngx_conf_set_str_slot,
+      ngx_http_set_complex_value_slot,
       NGX_HTTP_LOC_CONF_OFFSET,
       offsetof(ngx_http_auth_basic_loc_conf_t, realm),
-      &ngx_http_auth_basic_p },
+      NULL },
 
     { ngx_string("auth_basic_user_file"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF
@@ -103,7 +100,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
     ngx_fd_t                         fd;
     ngx_int_t                        rc;
     ngx_err_t                        err;
-    ngx_str_t                        pwd, user_file;
+    ngx_str_t                        pwd, realm, user_file;
     ngx_uint_t                       i, level, login, left, passwd;
     ngx_file_t                       file;
     ngx_http_auth_basic_ctx_t       *ctx;
@@ -117,7 +114,15 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
 
     alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_basic_module);
 
-    if (alcf->realm.len == 0 || alcf->user_file.value.len == 0) {
+    if (alcf->realm == NULL || alcf->user_file.value.data == NULL) {
+        return NGX_DECLINED;
+    }
+
+    if (ngx_http_complex_value(r, alcf->realm, &realm) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    if (realm.len == 3 && ngx_strncmp(realm.data, "off", 3) == 0) {
         return NGX_DECLINED;
     }
 
@@ -125,7 +130,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
 
     if (ctx) {
         return ngx_http_auth_basic_crypt_handler(r, ctx, &ctx->passwd,
-                                                 &alcf->realm);
+                                                 &realm);
     }
 
     rc = ngx_http_auth_basic_user(r);
@@ -135,7 +140,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                       "no user/password was provided for basic authentication");
 
-        return ngx_http_auth_basic_set_realm(r, &alcf->realm);
+        return ngx_http_auth_basic_set_realm(r, &realm);
     }
 
     if (rc == NGX_ERROR) {
@@ -233,7 +238,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
                     pwd.data = &buf[passwd];
 
                     return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd,
-                                                             &alcf->realm);
+                                                             &realm);
                 }
 
                 break;
@@ -271,14 +276,14 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
 
         ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1);
 
-        return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &alcf->realm);
+        return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &realm);
     }
 
     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                   "user \"%V\" was not found in \"%V\"",
                   &r->headers_in.user, &user_file);
 
-    return ngx_http_auth_basic_set_realm(r, &alcf->realm);
+    return ngx_http_auth_basic_set_realm(r, &realm);
 }
 
 
@@ -344,14 +349,29 @@ ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r,
 static ngx_int_t
 ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
 {
+    size_t   len;
+    u_char  *basic, *p;
+
     r->headers_out.www_authenticate = ngx_list_push(&r->headers_out.headers);
     if (r->headers_out.www_authenticate == NULL) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
+    len = sizeof("Basic realm=\"\"") - 1 + realm->len;
+
+    basic = ngx_pnalloc(r->pool, len);
+    if (basic == NULL) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    p = ngx_cpymem(basic, "Basic realm=\"", sizeof("Basic realm=\"") - 1);
+    p = ngx_cpymem(p, realm->data, realm->len);
+    *p = '"';
+
     r->headers_out.www_authenticate->hash = 1;
     ngx_str_set(&r->headers_out.www_authenticate->key, "WWW-Authenticate");
-    r->headers_out.www_authenticate->value = *realm;
+    r->headers_out.www_authenticate->value.data = basic;
+    r->headers_out.www_authenticate->value.len = len;
 
     return NGX_HTTP_UNAUTHORIZED;
 }
@@ -386,11 +406,11 @@ ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_http_auth_basic_loc_conf_t  *prev = parent;
     ngx_http_auth_basic_loc_conf_t  *conf = child;
 
-    if (conf->realm.data == NULL) {
+    if (conf->realm == NULL) {
         conf->realm = prev->realm;
     }
 
-    if (conf->user_file.value.len == 0) {
+    if (conf->user_file.value.data == NULL) {
         conf->user_file = prev->user_file;
     }
 
@@ -418,37 +438,6 @@ ngx_http_auth_basic_init(ngx_conf_t *cf)
 
 
 static char *
-ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data)
-{
-    ngx_str_t  *realm = data;
-
-    size_t   len;
-    u_char  *basic, *p;
-
-    if (ngx_strcmp(realm->data, "off") == 0) {
-        ngx_str_set(realm, "");
-        return NGX_CONF_OK;
-    }
-
-    len = sizeof("Basic realm=\"") - 1 + realm->len + 1;
-
-    basic = ngx_pnalloc(cf->pool, len);
-    if (basic == NULL) {
-        return NGX_CONF_ERROR;
-    }
-
-    p = ngx_cpymem(basic, "Basic realm=\"", sizeof("Basic realm=\"") - 1);
-    p = ngx_cpymem(p, realm->data, realm->len);
-    *p = '"';
-
-    realm->len = len;
-    realm->data = basic;
-
-    return NGX_CONF_OK;
-}
-
-
-static char *
 ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
     ngx_http_auth_basic_loc_conf_t *alcf = conf;
@@ -456,7 +445,7 @@ ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     ngx_str_t                         *value;
     ngx_http_compile_complex_value_t   ccv;
 
-    if (alcf->user_file.value.len) {
+    if (alcf->user_file.value.data) {
         return "is duplicate";
     }
 

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_autoindex_module.c (+5 -2) 98%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_autoindex_module.c    2013-07-22 11:05:55 +0900 (450a48e)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_autoindex_module.c    2013-07-22 13:32:39 +0900 (fb46d65)
@@ -489,8 +489,11 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
             }
 
             b->last = ngx_cpymem(b->last, "</a>", sizeof("</a>") - 1);
-            ngx_memset(b->last, ' ', NGX_HTTP_AUTOINDEX_NAME_LEN - len);
-            b->last += NGX_HTTP_AUTOINDEX_NAME_LEN - len;
+
+            if (NGX_HTTP_AUTOINDEX_NAME_LEN - len > 0) {
+                ngx_memset(b->last, ' ', NGX_HTTP_AUTOINDEX_NAME_LEN - len);
+                b->last += NGX_HTTP_AUTOINDEX_NAME_LEN - len;
+            }
         }
 
         *b->last++ = ' ';

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

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

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_chunked_filter_module.c (+1 -0) 99%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_chunked_filter_module.c    2013-07-22 11:05:55 +0900 (94313a8)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_chunked_filter_module.c    2013-07-22 13:32:39 +0900 (a7dc5bf)
@@ -62,6 +62,7 @@ ngx_http_chunked_header_filter(ngx_http_request_t *r)
 
     if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED
         || r->headers_out.status == NGX_HTTP_NO_CONTENT
+        || r->headers_out.status < NGX_HTTP_OK
         || r != r->main
         || (r->method & NGX_HTTP_HEAD))
     {

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

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

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

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_fastcgi_module.c (+49 -59) 98%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_fastcgi_module.c    2013-07-22 11:05:55 +0900 (e8ff24c)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_fastcgi_module.c    2013-07-22 13:32:39 +0900 (f386926)
@@ -1356,11 +1356,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
                 }
 
             } else {
-                if (f->padding) {
-                    f->state = ngx_http_fastcgi_st_padding;
-                } else {
-                    f->state = ngx_http_fastcgi_st_version;
-                }
+                f->state = ngx_http_fastcgi_st_padding;
             }
 
             continue;
@@ -1597,11 +1593,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
         f->length -= u->buffer.pos - start;
 
         if (f->length == 0) {
-            if (f->padding) {
-                f->state = ngx_http_fastcgi_st_padding;
-            } else {
-                f->state = ngx_http_fastcgi_st_version;
-            }
+            f->state = ngx_http_fastcgi_st_padding;
         }
 
         if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
@@ -1696,12 +1688,7 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
             }
 
             if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) {
-
-                if (f->padding) {
-                    f->state = ngx_http_fastcgi_st_padding;
-                } else {
-                    f->state = ngx_http_fastcgi_st_version;
-                }
+                f->state = ngx_http_fastcgi_st_padding;
 
                 if (!flcf->keep_conn) {
                     p->upstream_done = 1;
@@ -1715,27 +1702,38 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
 
             if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
 
-                if (f->padding) {
-                    f->state = ngx_http_fastcgi_st_padding;
-                } else {
-                    f->state = ngx_http_fastcgi_st_version;
+                ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
+                               "http fastcgi sent end request");
+
+                if (!flcf->keep_conn) {
+                    p->upstream_done = 1;
+                    break;
                 }
 
-                p->upstream_done = 1;
+                continue;
+            }
+        }
+
 
-                if (flcf->keep_conn) {
+        if (f->state == ngx_http_fastcgi_st_padding) {
+
+            if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
+
+                if (f->pos + f->padding < f->last) {
+                    p->upstream_done = 1;
+                    break;
+                }
+
+                if (f->pos + f->padding == f->last) {
+                    p->upstream_done = 1;
                     r->upstream->keepalive = 1;
+                    break;
                 }
 
-                ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
-                               "http fastcgi sent end request");
+                f->padding -= f->last - f->pos;
 
                 break;
             }
-        }
-
-
-        if (f->state == ngx_http_fastcgi_st_padding) {
 
             if (f->pos + f->padding < f->last) {
                 f->state = ngx_http_fastcgi_st_version;
@@ -1788,21 +1786,27 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
                               "FastCGI sent in stderr: \"%*s\"",
                               m + 1 - msg, msg);
 
-                if (f->pos == f->last) {
-                    break;
-                }
-
             } else {
-                if (f->padding) {
-                    f->state = ngx_http_fastcgi_st_padding;
-                } else {
-                    f->state = ngx_http_fastcgi_st_version;
-                }
+                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 */
 
@@ -1856,33 +1860,14 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
                        "input buf #%d %p", b->num, b->pos);
 
-        if (f->pos + f->length < f->last) {
-
-            if (f->padding) {
-                f->state = ngx_http_fastcgi_st_padding;
-            } else {
-                f->state = ngx_http_fastcgi_st_version;
-            }
-
+        if (f->pos + f->length <= f->last) {
+            f->state = ngx_http_fastcgi_st_padding;
             f->pos += f->length;
             b->last = f->pos;
 
             continue;
         }
 
-        if (f->pos + f->length == f->last) {
-
-            if (f->padding) {
-                f->state = ngx_http_fastcgi_st_padding;
-            } else {
-                f->state = ngx_http_fastcgi_st_version;
-            }
-
-            b->last = f->last;
-
-            break;
-        }
-
         f->length -= f->last - f->pos;
 
         b->last = f->last;
@@ -2106,6 +2091,8 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
     conf->upstream.buffering = NGX_CONF_UNSET;
     conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
 
+    conf->upstream.local = NGX_CONF_UNSET_PTR;
+
     conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
@@ -2177,6 +2164,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_value(conf->upstream.ignore_client_abort,
                               prev->upstream.ignore_client_abort, 0);
 
+    ngx_conf_merge_ptr_value(conf->upstream.local,
+                              prev->upstream.local, NULL);
+
     ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
                               prev->upstream.connect_timeout, 60000);
 
@@ -3014,7 +3004,7 @@ ngx_http_fastcgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     value = cf->args->elts;
 
-    if (flcf->cache_key.value.len) {
+    if (flcf->cache_key.value.data) {
         return "is duplicate";
     }
 

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_flv_module.c (+4 -0) 98%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_flv_module.c    2013-07-22 11:05:55 +0900 (03a7468)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_flv_module.c    2013-07-22 13:32:39 +0900 (cc25320)
@@ -194,6 +194,10 @@ ngx_http_flv_handler(ngx_http_request_t *r)
     r->headers_out.content_length_n = len;
     r->headers_out.last_modified_time = of.mtime;
 
+    if (ngx_http_set_etag(r) != NGX_OK) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
     if (ngx_http_set_content_type(r) != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_geo_module.c (+313 -107) 80%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_geo_module.c    2013-07-22 11:05:55 +0900 (fce87a8)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_geo_module.c    2013-07-22 13:32:39 +0900 (34c3b19)
@@ -18,6 +18,14 @@ typedef struct {
 
 
 typedef struct {
+    ngx_radix_tree_t                *tree;
+#if (NGX_HAVE_INET6)
+    ngx_radix_tree_t                *tree6;
+#endif
+} ngx_http_geo_trees_t;
+
+
+typedef struct {
     ngx_http_geo_range_t           **low;
     ngx_http_variable_value_t       *default_value;
 } ngx_http_geo_high_ranges_t;
@@ -35,6 +43,9 @@ typedef struct {
     ngx_str_t                       *net;
     ngx_http_geo_high_ranges_t       high;
     ngx_radix_tree_t                *tree;
+#if (NGX_HAVE_INET6)
+    ngx_radix_tree_t                *tree6;
+#endif
     ngx_rbtree_t                     rbtree;
     ngx_rbtree_node_t                sentinel;
     ngx_array_t                     *proxies;
@@ -57,7 +68,7 @@ typedef struct {
 
 typedef struct {
     union {
-        ngx_radix_tree_t            *tree;
+        ngx_http_geo_trees_t         trees;
         ngx_http_geo_high_ranges_t   high;
     } u;
 
@@ -68,8 +79,8 @@ typedef struct {
 } ngx_http_geo_ctx_t;
 
 
-static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r,
-    ngx_http_geo_ctx_t *ctx);
+static ngx_int_t ngx_http_geo_addr(ngx_http_request_t *r,
+    ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr);
 static ngx_int_t ngx_http_geo_real_addr(ngx_http_request_t *r,
     ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr);
 static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
@@ -82,6 +93,8 @@ static ngx_uint_t ngx_http_geo_delete_range(ngx_conf_t *cf,
     ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end);
 static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
     ngx_str_t *value);
+static char *ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
+    ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net);
 static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf,
     ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value);
 static char *ngx_http_geo_add_proxy(ngx_conf_t *cf,
@@ -155,7 +168,7 @@ static ngx_http_geo_header_t  ngx_http_geo_header = {
 };
 
 
-/* AF_INET only */
+/* geo range is AF_INET only */
 
 static ngx_int_t
 ngx_http_geo_cidr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
@@ -163,10 +176,56 @@ ngx_http_geo_cidr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
 {
     ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
 
+    in_addr_t                   inaddr;
+    ngx_addr_t                  addr;
+    struct sockaddr_in         *sin;
     ngx_http_variable_value_t  *vv;
+#if (NGX_HAVE_INET6)
+    u_char                     *p;
+    struct in6_addr            *inaddr6;
+#endif
+
+    if (ngx_http_geo_addr(r, ctx, &addr) != NGX_OK) {
+        vv = (ngx_http_variable_value_t *)
+                  ngx_radix32tree_find(ctx->u.trees.tree, INADDR_NONE);
+        goto done;
+    }
+
+    switch (addr.sockaddr->sa_family) {
+
+#if (NGX_HAVE_INET6)
+    case AF_INET6:
+        inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
+        p = inaddr6->s6_addr;
+
+        if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
+            inaddr = p[12] << 24;
+            inaddr += p[13] << 16;
+            inaddr += p[14] << 8;
+            inaddr += p[15];
+
+            vv = (ngx_http_variable_value_t *)
+                      ngx_radix32tree_find(ctx->u.trees.tree, inaddr);
 
-    vv = (ngx_http_variable_value_t *)
-              ngx_radix32tree_find(ctx->u.tree, ngx_http_geo_addr(r, ctx));
+        } else {
+            vv = (ngx_http_variable_value_t *)
+                      ngx_radix128tree_find(ctx->u.trees.tree6, p);
+        }
+
+        break;
+#endif
+
+    default: /* AF_INET */
+        sin = (struct sockaddr_in *) addr.sockaddr;
+        inaddr = ntohl(sin->sin_addr.s_addr);
+
+        vv = (ngx_http_variable_value_t *)
+                  ngx_radix32tree_find(ctx->u.trees.tree, inaddr);
+
+        break;
+    }
+
+done:
 
     *v = *vv;
 
@@ -183,82 +242,92 @@ ngx_http_geo_range_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
 {
     ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
 
-    in_addr_t              addr;
+    in_addr_t              inaddr;
+    ngx_addr_t             addr;
     ngx_uint_t             n;
+    struct sockaddr_in    *sin;
     ngx_http_geo_range_t  *range;
+#if (NGX_HAVE_INET6)
+    u_char                *p;
+    struct in6_addr       *inaddr6;
+#endif
 
     *v = *ctx->u.high.default_value;
 
-    addr = ngx_http_geo_addr(r, ctx);
+    if (ngx_http_geo_addr(r, ctx, &addr) == NGX_OK) {
 
-    range = ctx->u.high.low[addr >> 16];
+        switch (addr.sockaddr->sa_family) {
 
-    if (range) {
-        n = addr & 0xffff;
-        do {
-            if (n >= (ngx_uint_t) range->start && n <= (ngx_uint_t) range->end)
-            {
-                *v = *range->value;
-                break;
-            }
-        } while ((++range)->value);
-    }
+#if (NGX_HAVE_INET6)
+        case AF_INET6:
+            inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
 
-    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http geo: %v", v);
+            if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
+                p = inaddr6->s6_addr;
 
-    return NGX_OK;
-}
+                inaddr = p[12] << 24;
+                inaddr += p[13] << 16;
+                inaddr += p[14] << 8;
+                inaddr += p[15];
 
+            } else {
+                inaddr = INADDR_NONE;
+            }
 
-static in_addr_t
-ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
-{
-    ngx_addr_t           addr;
-    ngx_table_elt_t     *xfwd;
-    struct sockaddr_in  *sin;
+            break;
+#endif
+
+        default: /* AF_INET */
+            sin = (struct sockaddr_in *) addr.sockaddr;
+            inaddr = ntohl(sin->sin_addr.s_addr);
+            break;
+        }
 
-    if (ngx_http_geo_real_addr(r, ctx, &addr) != NGX_OK) {
-        return INADDR_NONE;
+    } else {
+        inaddr = INADDR_NONE;
     }
 
-    xfwd = r->headers_in.x_forwarded_for;
+    if (ctx->u.high.low) {
+        range = ctx->u.high.low[inaddr >> 16];
 
-    if (xfwd != NULL && ctx->proxies != NULL) {
-        (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
-                                           xfwd->value.len, ctx->proxies,
-                                           ctx->proxy_recursive);
+        if (range) {
+            n = inaddr & 0xffff;
+            do {
+                if (n >= (ngx_uint_t) range->start
+                    && n <= (ngx_uint_t) range->end)
+                {
+                    *v = *range->value;
+                    break;
+                }
+            } while ((++range)->value);
+        }
     }
 
-#if (NGX_HAVE_INET6)
-
-    if (addr.sockaddr->sa_family == AF_INET6) {
-        u_char           *p;
-        in_addr_t         inaddr;
-        struct in6_addr  *inaddr6;
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http geo: %v", v);
 
-        inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
+    return NGX_OK;
+}
 
-        if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
-            p = inaddr6->s6_addr;
 
-            inaddr = p[12] << 24;
-            inaddr += p[13] << 16;
-            inaddr += p[14] << 8;
-            inaddr += p[15];
+static ngx_int_t
+ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx,
+    ngx_addr_t *addr)
+{
+    ngx_array_t  *xfwd;
 
-            return inaddr;
-        }
+    if (ngx_http_geo_real_addr(r, ctx, addr) != NGX_OK) {
+        return NGX_ERROR;
     }
 
-#endif
+    xfwd = &r->headers_in.x_forwarded_for;
 
-    if (addr.sockaddr->sa_family != AF_INET) {
-        return INADDR_NONE;
+    if (xfwd->nelts > 0 && ctx->proxies != NULL) {
+        (void) ngx_http_get_forwarded_addr(r, addr, xfwd, NULL,
+                                           ctx->proxies, ctx->proxy_recursive);
     }
 
-    sin = (struct sockaddr_in *) addr.sockaddr;
-    return ntohl(sin->sin_addr.s_addr);
+    return NGX_OK;
 }
 
 
@@ -303,7 +372,6 @@ static char *
 ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
     char                     *rv;
-    void                    **p;
     size_t                    len;
     ngx_str_t                *value, name;
     ngx_uint_t                i;
@@ -313,6 +381,9 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     ngx_http_variable_t      *var;
     ngx_http_geo_ctx_t       *geo;
     ngx_http_geo_conf_ctx_t   ctx;
+#if (NGX_HAVE_INET6)
+    static struct in6_addr    zero;
+#endif
 
     value = cf->args->elts;
 
@@ -322,6 +393,13 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     }
 
     name = value[1];
+
+    if (name.data[0] != '$') {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "invalid variable name \"%V\"", &name);
+        return NGX_CONF_ERROR;
+    }
+
     name.len--;
     name.data++;
 
@@ -333,6 +411,13 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         }
 
         name = value[2];
+
+        if (name.data[0] != '$') {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "invalid variable name \"%V\"", &name);
+            return NGX_CONF_ERROR;
+        }
+
         name.len--;
         name.data++;
 
@@ -345,14 +430,14 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         return NGX_CONF_ERROR;
     }
 
-    pool = ngx_create_pool(16384, cf->log);
+    pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
     if (pool == NULL) {
         return NGX_CONF_ERROR;
     }
 
     ngx_memzero(&ctx, sizeof(ngx_http_geo_conf_ctx_t));
 
-    ctx.temp_pool = ngx_create_pool(16384, cf->log);
+    ctx.temp_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
     if (ctx.temp_pool == NULL) {
         return NGX_CONF_ERROR;
     }
@@ -378,9 +463,9 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     geo->proxies = ctx.proxies;
     geo->proxy_recursive = ctx.proxy_recursive;
 
-    if (ctx.high.low) {
+    if (ctx.ranges) {
 
-        if (!ctx.binary_include) {
+        if (ctx.high.low && !ctx.binary_include) {
             for (i = 0; i < 0x10000; i++) {
                 a = (ngx_array_t *) ctx.high.low[i];
 
@@ -395,8 +480,8 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                     return NGX_CONF_ERROR;
                 }
 
-                p = (void **) ngx_cpymem(ctx.high.low[i], a->elts, len);
-                *p = NULL;
+                ngx_memcpy(ctx.high.low[i], a->elts, len);
+                ctx.high.low[i][a->nelts].value = NULL;
                 ctx.data_size += len + sizeof(void *);
             }
 
@@ -429,7 +514,18 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
             }
         }
 
-        geo->u.tree = ctx.tree;
+        geo->u.trees.tree = ctx.tree;
+
+#if (NGX_HAVE_INET6)
+        if (ctx.tree6 == NULL) {
+            ctx.tree6 = ngx_radix_tree_create(cf->pool, -1);
+            if (ctx.tree6 == NULL) {
+                return NGX_CONF_ERROR;
+            }
+        }
+
+        geo->u.trees.tree6 = ctx.tree6;
+#endif
 
         var->get_handler = ngx_http_geo_cidr_variable;
         var->data = (uintptr_t) geo;
@@ -437,16 +533,23 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         ngx_destroy_pool(ctx.temp_pool);
         ngx_destroy_pool(pool);
 
-        if (ngx_radix32tree_find(ctx.tree, 0) != NGX_RADIX_NO_VALUE) {
-            return rv;
-        }
-
         if (ngx_radix32tree_insert(ctx.tree, 0, 0,
                                    (uintptr_t) &ngx_http_variable_null_value)
             == NGX_ERROR)
         {
             return NGX_CONF_ERROR;
         }
+
+        /* NGX_BUSY is okay (default was set explicitly) */
+
+#if (NGX_HAVE_INET6)
+        if (ngx_radix128tree_insert(ctx.tree6, zero.s6_addr, zero.s6_addr,
+                                    (uintptr_t) &ngx_http_variable_null_value)
+            == NGX_ERROR)
+        {
+            return NGX_CONF_ERROR;
+        }
+#endif
     }
 
     return rv;
@@ -469,7 +572,12 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
 
         if (ngx_strcmp(value[0].data, "ranges") == 0) {
 
-            if (ctx->tree) {
+            if (ctx->tree
+#if (NGX_HAVE_INET6)
+                || ctx->tree6
+#endif
+               )
+            {
                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                    "the \"ranges\" directive must be "
                                    "the first directive inside \"geo\" block");
@@ -907,11 +1015,10 @@ static char *
 ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
     ngx_str_t *value)
 {
-    ngx_int_t                        rc, del;
-    ngx_str_t                       *net;
-    ngx_uint_t                       i;
-    ngx_cidr_t                       cidr;
-    ngx_http_variable_value_t       *val, *old;
+    char        *rv;
+    ngx_int_t    rc, del;
+    ngx_str_t   *net;
+    ngx_cidr_t   cidr;
 
     if (ctx->tree == NULL) {
         ctx->tree = ngx_radix_tree_create(ctx->pool, -1);
@@ -920,57 +1027,108 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
         }
     }
 
+#if (NGX_HAVE_INET6)
+    if (ctx->tree6 == NULL) {
+        ctx->tree6 = ngx_radix_tree_create(ctx->pool, -1);
+        if (ctx->tree6 == NULL) {
+            return NGX_CONF_ERROR;
+        }
+    }
+#endif
+
     if (ngx_strcmp(value[0].data, "default") == 0) {
-        /* cidr.family = AF_INET; */
+        cidr.family = AF_INET;
         cidr.u.in.addr = 0;
         cidr.u.in.mask = 0;
-        net = &value[0];
 
-    } else {
-        if (ngx_strcmp(value[0].data, "delete") == 0) {
-            net = &value[1];
-            del = 1;
+        rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]);
 
-        } else {
-            net = &value[0];
-            del = 0;
+        if (rv != NGX_CONF_OK) {
+            return rv;
         }
 
-        if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
-            return NGX_CONF_ERROR;
-        }
+#if (NGX_HAVE_INET6)
+        cidr.family = AF_INET6;
+        ngx_memzero(&cidr.u.in6, sizeof(ngx_in6_cidr_t));
 
-        if (cidr.family != AF_INET) {
-            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "\"geo\" supports IPv4 only");
-            return NGX_CONF_ERROR;
+        rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]);
+
+        if (rv != NGX_CONF_OK) {
+            return rv;
         }
+#endif
+
+        return NGX_CONF_OK;
+    }
 
+    if (ngx_strcmp(value[0].data, "delete") == 0) {
+        net = &value[1];
+        del = 1;
+
+    } else {
+        net = &value[0];
+        del = 0;
+    }
+
+    if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
+    if (cidr.family == AF_INET) {
         cidr.u.in.addr = ntohl(cidr.u.in.addr);
         cidr.u.in.mask = ntohl(cidr.u.in.mask);
+    }
 
-        if (del) {
-            if (ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
-                                       cidr.u.in.mask)
-                != NGX_OK)
-            {
-                ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
-                                   "no network \"%V\" to delete", net);
-            }
+    if (del) {
+        switch (cidr.family) {
 
-            return NGX_CONF_OK;
+#if (NGX_HAVE_INET6)
+        case AF_INET6:
+            rc = ngx_radix128tree_delete(ctx->tree6,
+                                         cidr.u.in6.addr.s6_addr,
+                                         cidr.u.in6.mask.s6_addr);
+            break;
+#endif
+
+        default: /* AF_INET */
+            rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
+                                        cidr.u.in.mask);
+            break;
         }
+
+        if (rc != NGX_OK) {
+            ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+                               "no network \"%V\" to delete", net);
+        }
+
+        return NGX_CONF_OK;
     }
 
-    val = ngx_http_geo_value(cf, ctx, &value[1]);
+    return ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], net);
+}
+
+
+static char *
+ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
+    ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net)
+{
+    ngx_int_t                   rc;
+    ngx_http_variable_value_t  *val, *old;
+
+    val = ngx_http_geo_value(cf, ctx, value);
 
     if (val == NULL) {
         return NGX_CONF_ERROR;
     }
 
-    for (i = 2; i; i--) {
-        rc = ngx_radix32tree_insert(ctx->tree, cidr.u.in.addr, cidr.u.in.mask,
-                                    (uintptr_t) val);
+    switch (cidr->family) {
+
+#if (NGX_HAVE_INET6)
+    case AF_INET6:
+        rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr,
+                                     cidr->u.in6.mask.s6_addr,
+                                     (uintptr_t) val);
+
         if (rc == NGX_OK) {
             return NGX_CONF_OK;
         }
@@ -982,18 +1140,66 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
         /* rc == NGX_BUSY */
 
         old = (ngx_http_variable_value_t *)
-              ngx_radix32tree_find(ctx->tree, cidr.u.in.addr & cidr.u.in.mask);
+                   ngx_radix128tree_find(ctx->tree6,
+                                         cidr->u.in6.addr.s6_addr);
 
         ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
-                "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
-                net, val, old);
+              "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
+              net, val, old);
 
-        rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, cidr.u.in.mask);
+        rc = ngx_radix128tree_delete(ctx->tree6,
+                                     cidr->u.in6.addr.s6_addr,
+                                     cidr->u.in6.mask.s6_addr);
 
         if (rc == NGX_ERROR) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
             return NGX_CONF_ERROR;
         }
+
+        rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr,
+                                     cidr->u.in6.mask.s6_addr,
+                                     (uintptr_t) val);
+
+        break;
+#endif
+
+    default: /* AF_INET */
+        rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr,
+                                    cidr->u.in.mask, (uintptr_t) val);
+
+        if (rc == NGX_OK) {
+            return NGX_CONF_OK;
+        }
+
+        if (rc == NGX_ERROR) {
+            return NGX_CONF_ERROR;
+        }
+
+        /* rc == NGX_BUSY */
+
+        old = (ngx_http_variable_value_t *)
+                   ngx_radix32tree_find(ctx->tree, cidr->u.in.addr);
+
+        ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+              "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
+              net, val, old);
+
+        rc = ngx_radix32tree_delete(ctx->tree,
+                                    cidr->u.in.addr, cidr->u.in.mask);
+
+        if (rc == NGX_ERROR) {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
+            return NGX_CONF_ERROR;
+        }
+
+        rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr,
+                                    cidr->u.in.mask, (uintptr_t) val);
+
+        break;
+    }
+
+    if (rc == NGX_OK) {
+        return NGX_CONF_OK;
     }
 
     return NGX_CONF_ERROR;

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_geoip_module.c (+149 -21) 81%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_geoip_module.c    2013-07-22 11:05:55 +0900 (7ff4f10)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_geoip_module.c    2013-07-22 13:32:39 +0900 (576fc5f)
@@ -13,12 +13,22 @@
 #include <GeoIPCity.h>
 
 
+#define NGX_GEOIP_COUNTRY_CODE   0
+#define NGX_GEOIP_COUNTRY_CODE3  1
+#define NGX_GEOIP_COUNTRY_NAME   2
+
+
 typedef struct {
     GeoIP        *country;
     GeoIP        *org;
     GeoIP        *city;
     ngx_array_t  *proxies;    /* array of ngx_cidr_t */
     ngx_flag_t    proxy_recursive;
+#if (NGX_HAVE_GEOIP_V6)
+    unsigned      country_v6:1;
+    unsigned      org_v6:1;
+    unsigned      city_v6:1;
+#endif
 } ngx_http_geoip_conf_t;
 
 
@@ -28,10 +38,32 @@ typedef struct {
 } ngx_http_geoip_var_t;
 
 
-typedef char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr);
+typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *,
+    u_long addr);
+
+
+ngx_http_geoip_variable_handler_pt ngx_http_geoip_country_functions[] = {
+    GeoIP_country_code_by_ipnum,
+    GeoIP_country_code3_by_ipnum,
+    GeoIP_country_name_by_ipnum,
+};
+
+
+#if (NGX_HAVE_GEOIP_V6)
+
+typedef const char *(*ngx_http_geoip_variable_handler_v6_pt)(GeoIP *,
+    geoipv6_t addr);
+
+
+ngx_http_geoip_variable_handler_v6_pt ngx_http_geoip_country_v6_functions[] = {
+    GeoIP_country_code_by_ipnum_v6,
+    GeoIP_country_code3_by_ipnum_v6,
+    GeoIP_country_name_by_ipnum_v6,
+};
+
+#endif
+
 
-static u_long ngx_http_geoip_addr(ngx_http_request_t *r,
-    ngx_http_geoip_conf_t *gcf);
 static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_geoip_org_variable(ngx_http_request_t *r,
@@ -138,19 +170,19 @@ static ngx_http_variable_t  ngx_http_geoip_vars[] = {
 
     { ngx_string("geoip_country_code"), NULL,
       ngx_http_geoip_country_variable,
-      (uintptr_t) GeoIP_country_code_by_ipnum, 0, 0 },
+      NGX_GEOIP_COUNTRY_CODE, 0, 0 },
 
     { ngx_string("geoip_country_code3"), NULL,
       ngx_http_geoip_country_variable,
-      (uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 },
+      NGX_GEOIP_COUNTRY_CODE3, 0, 0 },
 
     { ngx_string("geoip_country_name"), NULL,
       ngx_http_geoip_country_variable,
-      (uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 },
+      NGX_GEOIP_COUNTRY_NAME, 0, 0 },
 
     { ngx_string("geoip_org"), NULL,
       ngx_http_geoip_org_variable,
-      (uintptr_t) GeoIP_name_by_ipnum, 0, 0 },
+      0, 0, 0 },
 
     { ngx_string("geoip_city_continent_code"), NULL,
       ngx_http_geoip_city_variable,
@@ -208,19 +240,18 @@ static u_long
 ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
 {
     ngx_addr_t           addr;
-    ngx_table_elt_t     *xfwd;
+    ngx_array_t         *xfwd;
     struct sockaddr_in  *sin;
 
     addr.sockaddr = r->connection->sockaddr;
     addr.socklen = r->connection->socklen;
     /* addr.name = r->connection->addr_text; */
 
-    xfwd = r->headers_in.x_forwarded_for;
+    xfwd = &r->headers_in.x_forwarded_for;
 
-    if (xfwd != NULL && gcf->proxies != NULL) {
-        (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
-                                           xfwd->value.len, gcf->proxies,
-                                           gcf->proxy_recursive);
+    if (xfwd->nelts > 0 && gcf->proxies != NULL) {
+        (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
+                                           gcf->proxies, gcf->proxy_recursive);
     }
 
 #if (NGX_HAVE_INET6)
@@ -255,12 +286,67 @@ ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
 }
 
 
+#if (NGX_HAVE_GEOIP_V6)
+
+static geoipv6_t
+ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
+{
+    ngx_addr_t            addr;
+    ngx_array_t          *xfwd;
+    in_addr_t             addr4;
+    struct in6_addr       addr6;
+    struct sockaddr_in   *sin;
+    struct sockaddr_in6  *sin6;
+
+    addr.sockaddr = r->connection->sockaddr;
+    addr.socklen = r->connection->socklen;
+    /* addr.name = r->connection->addr_text; */
+
+    xfwd = &r->headers_in.x_forwarded_for;
+
+    if (xfwd->nelts > 0 && gcf->proxies != NULL) {
+        (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
+                                           gcf->proxies, gcf->proxy_recursive);
+    }
+
+    switch (addr.sockaddr->sa_family) {
+
+    case AF_INET:
+        /* Produce IPv4-mapped IPv6 address. */
+        sin = (struct sockaddr_in *) addr.sockaddr;
+        addr4 = ntohl(sin->sin_addr.s_addr);
+
+        ngx_memzero(&addr6, sizeof(struct in6_addr));
+        addr6.s6_addr[10] = 0xff;
+        addr6.s6_addr[11] = 0xff;
+        addr6.s6_addr[12] = addr4 >> 24;
+        addr6.s6_addr[13] = addr4 >> 16;
+        addr6.s6_addr[14] = addr4 >> 8;
+        addr6.s6_addr[15] = addr4;
+        return addr6;
+
+    case AF_INET6:
+        sin6 = (struct sockaddr_in6 *) addr.sockaddr;
+        return sin6->sin6_addr;
+
+    default:
+        return in6addr_any;
+    }
+}
+
+#endif
+
+
 static ngx_int_t
 ngx_http_geoip_country_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
 {
-    ngx_http_geoip_variable_handler_pt  handler =
-        (ngx_http_geoip_variable_handler_pt) data;
+    ngx_http_geoip_variable_handler_pt     handler =
+        ngx_http_geoip_country_functions[data];
+#if (NGX_HAVE_GEOIP_V6)
+    ngx_http_geoip_variable_handler_v6_pt  handler_v6 =
+        ngx_http_geoip_country_v6_functions[data];
+#endif
 
     const char             *val;
     ngx_http_geoip_conf_t  *gcf;
@@ -271,7 +357,13 @@ ngx_http_geoip_country_variable(ngx_http_request_t *r,
         goto not_found;
     }
 
+#if (NGX_HAVE_GEOIP_V6)
+    val = gcf->country_v6
+              ? handler_v6(gcf->country, ngx_http_geoip_addr_v6(r, gcf))
+              : handler(gcf->country, ngx_http_geoip_addr(r, gcf));
+#else
     val = handler(gcf->country, ngx_http_geoip_addr(r, gcf));
+#endif
 
     if (val == NULL) {
         goto not_found;
@@ -297,9 +389,6 @@ static ngx_int_t
 ngx_http_geoip_org_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
 {
-    ngx_http_geoip_variable_handler_pt  handler =
-        (ngx_http_geoip_variable_handler_pt) data;
-
     size_t                  len;
     char                   *val;
     ngx_http_geoip_conf_t  *gcf;
@@ -310,7 +399,15 @@ ngx_http_geoip_org_variable(ngx_http_request_t *r,
         goto not_found;
     }
 
-    val = handler(gcf->org, ngx_http_geoip_addr(r, gcf));
+#if (NGX_HAVE_GEOIP_V6)
+    val = gcf->org_v6
+              ? GeoIP_name_by_ipnum_v6(gcf->org,
+                                       ngx_http_geoip_addr_v6(r, gcf))
+              : GeoIP_name_by_ipnum(gcf->org,
+                                    ngx_http_geoip_addr(r, gcf));
+#else
+    val = GeoIP_name_by_ipnum(gcf->org, ngx_http_geoip_addr(r, gcf));
+#endif
 
     if (val == NULL) {
         goto not_found;
@@ -500,7 +597,15 @@ ngx_http_geoip_get_city_record(ngx_http_request_t *r)
     gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
 
     if (gcf->city) {
+#if (NGX_HAVE_GEOIP_V6)
+        return gcf->city_v6
+                   ? GeoIP_record_by_ipnum_v6(gcf->city,
+                                              ngx_http_geoip_addr_v6(r, gcf))
+                   : GeoIP_record_by_ipnum(gcf->city,
+                                           ngx_http_geoip_addr(r, gcf));
+#else
         return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r, gcf));
+#endif
     }
 
     return NULL;
@@ -598,11 +703,16 @@ ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     switch (gcf->country->databaseType) {
 
     case GEOIP_COUNTRY_EDITION:
-    case GEOIP_PROXY_EDITION:
-    case GEOIP_NETSPEED_EDITION:
 
         return NGX_CONF_OK;
 
+#if (NGX_HAVE_GEOIP_V6)
+    case GEOIP_COUNTRY_EDITION_V6:
+
+        gcf->country_v6 = 1;
+        return NGX_CONF_OK;
+#endif
+
     default:
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                            "invalid GeoIP database \"%V\" type:%d",
@@ -654,6 +764,16 @@ ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
         return NGX_CONF_OK;
 
+#if (NGX_HAVE_GEOIP_V6)
+    case GEOIP_ISP_EDITION_V6:
+    case GEOIP_ORG_EDITION_V6:
+    case GEOIP_DOMAIN_EDITION_V6:
+    case GEOIP_ASNUM_EDITION_V6:
+
+        gcf->org_v6 = 1;
+        return NGX_CONF_OK;
+#endif
+
     default:
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                            "invalid GeoIP database \"%V\" type:%d",
@@ -703,6 +823,14 @@ ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
         return NGX_CONF_OK;
 
+#if (NGX_HAVE_GEOIP_V6)
+    case GEOIP_CITY_EDITION_REV0_V6:
+    case GEOIP_CITY_EDITION_REV1_V6:
+
+        gcf->city_v6 = 1;
+        return NGX_CONF_OK;
+#endif
+
     default:
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                            "invalid GeoIP City database \"%V\" type:%d",

  Added: vendor/nginx-1.4.2/src/http/modules/ngx_http_gunzip_filter_module.c (+677 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_gunzip_filter_module.c    2013-07-22 13:32:39 +0900 (d4e41e4)
@@ -0,0 +1,677 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Maxim Dounin
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+#include <zlib.h>
+
+
+typedef struct {
+    ngx_flag_t           enable;
+    ngx_bufs_t           bufs;
+} ngx_http_gunzip_conf_t;
+
+
+typedef struct {
+    ngx_chain_t         *in;
+    ngx_chain_t         *free;
+    ngx_chain_t         *busy;
+    ngx_chain_t         *out;
+    ngx_chain_t        **last_out;
+
+    ngx_buf_t           *in_buf;
+    ngx_buf_t           *out_buf;
+    ngx_int_t            bufs;
+
+    unsigned             started:1;
+    unsigned             flush:4;
+    unsigned             redo:1;
+    unsigned             done:1;
+    unsigned             nomem:1;
+
+    z_stream             zstream;
+    ngx_http_request_t  *request;
+} ngx_http_gunzip_ctx_t;
+
+
+static ngx_int_t ngx_http_gunzip_filter_inflate_start(ngx_http_request_t *r,
+    ngx_http_gunzip_ctx_t *ctx);
+static ngx_int_t ngx_http_gunzip_filter_add_data(ngx_http_request_t *r,
+    ngx_http_gunzip_ctx_t *ctx);
+static ngx_int_t ngx_http_gunzip_filter_get_buf(ngx_http_request_t *r,
+    ngx_http_gunzip_ctx_t *ctx);
+static ngx_int_t ngx_http_gunzip_filter_inflate(ngx_http_request_t *r,
+    ngx_http_gunzip_ctx_t *ctx);
+static ngx_int_t ngx_http_gunzip_filter_inflate_end(ngx_http_request_t *r,
+    ngx_http_gunzip_ctx_t *ctx);
+
+static void *ngx_http_gunzip_filter_alloc(void *opaque, u_int items,
+    u_int size);
+static void ngx_http_gunzip_filter_free(void *opaque, void *address);
+
+static ngx_int_t ngx_http_gunzip_filter_init(ngx_conf_t *cf);
+static void *ngx_http_gunzip_create_conf(ngx_conf_t *cf);
+static char *ngx_http_gunzip_merge_conf(ngx_conf_t *cf,
+    void *parent, void *child);
+
+
+static ngx_command_t  ngx_http_gunzip_filter_commands[] = {
+
+    { ngx_string("gunzip"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_gunzip_conf_t, enable),
+      NULL },
+
+    { ngx_string("gunzip_buffers"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
+      ngx_conf_set_bufs_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_gunzip_conf_t, bufs),
+      NULL },
+
+      ngx_null_command
+};
+
+
+static ngx_http_module_t  ngx_http_gunzip_filter_module_ctx = {
+    NULL,                                  /* preconfiguration */
+    ngx_http_gunzip_filter_init,           /* postconfiguration */
+
+    NULL,                                  /* create main configuration */
+    NULL,                                  /* init main configuration */
+
+    NULL,                                  /* create server configuration */
+    NULL,                                  /* merge server configuration */
+
+    ngx_http_gunzip_create_conf,           /* create location configuration */
+    ngx_http_gunzip_merge_conf             /* merge location configuration */
+};
+
+
+ngx_module_t  ngx_http_gunzip_filter_module = {
+    NGX_MODULE_V1,
+    &ngx_http_gunzip_filter_module_ctx,    /* module context */
+    ngx_http_gunzip_filter_commands,       /* module directives */
+    NGX_HTTP_MODULE,                       /* module type */
+    NULL,                                  /* init master */
+    NULL,                                  /* init module */
+    NULL,                                  /* init process */
+    NULL,                                  /* init thread */
+    NULL,                                  /* exit thread */
+    NULL,                                  /* exit process */
+    NULL,                                  /* exit master */
+    NGX_MODULE_V1_PADDING
+};
+
+
+static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;
+static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;
+
+
+static ngx_int_t
+ngx_http_gunzip_header_filter(ngx_http_request_t *r)
+{
+    ngx_http_gunzip_ctx_t   *ctx;
+    ngx_http_gunzip_conf_t  *conf;
+
+    conf = ngx_http_get_module_loc_conf(r, ngx_http_gunzip_filter_module);
+
+    /* TODO support multiple content-codings */
+    /* TODO always gunzip - due to configuration or module request */
+    /* TODO ignore content encoding? */
+
+    if (!conf->enable
+        || r->headers_out.content_encoding == NULL
+        || r->headers_out.content_encoding->value.len != 4
+        || ngx_strncasecmp(r->headers_out.content_encoding->value.data,
+                           (u_char *) "gzip", 4) != 0)
+    {
+        return ngx_http_next_header_filter(r);
+    }
+
+    r->gzip_vary = 1;
+
+    if (!r->gzip_tested) {
+        if (ngx_http_gzip_ok(r) == NGX_OK) {
+            return ngx_http_next_header_filter(r);
+        }
+
+    } else if (r->gzip_ok) {
+        return ngx_http_next_header_filter(r);
+    }
+
+    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gunzip_ctx_t));
+    if (ctx == NULL) {
+        return NGX_ERROR;
+    }
+
+    ngx_http_set_ctx(r, ctx, ngx_http_gunzip_filter_module);
+
+    ctx->request = r;
+
+    r->filter_need_in_memory = 1;
+
+    r->headers_out.content_encoding->hash = 0;
+    r->headers_out.content_encoding = NULL;
+
+    ngx_http_clear_content_length(r);
+    ngx_http_clear_accept_ranges(r);
+    ngx_http_clear_etag(r);
+
+    return ngx_http_next_header_filter(r);
+}
+
+
+static ngx_int_t
+ngx_http_gunzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
+{
+    int                     rc;
+    ngx_chain_t            *cl;
+    ngx_http_gunzip_ctx_t  *ctx;
+
+    ctx = ngx_http_get_module_ctx(r, ngx_http_gunzip_filter_module);
+
+    if (ctx == NULL || ctx->done) {
+        return ngx_http_next_body_filter(r, in);
+    }
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http gunzip filter");
+
+    if (!ctx->started) {
+        if (ngx_http_gunzip_filter_inflate_start(r, ctx) != NGX_OK) {
+            goto failed;
+        }
+    }
+
+    if (in) {
+        if (ngx_chain_add_copy(r->pool, &ctx->in, in) != NGX_OK) {
+            goto failed;
+        }
+    }
+
+    if (ctx->nomem) {
+
+        /* flush busy buffers */
+
+        if (ngx_http_next_body_filter(r, NULL) == NGX_ERROR) {
+            goto failed;
+        }
+
+        cl = NULL;
+
+        ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &cl,
+                                (ngx_buf_tag_t) &ngx_http_gunzip_filter_module);
+        ctx->nomem = 0;
+    }
+
+    for ( ;; ) {
+
+        /* cycle while we can write to a client */
+
+        for ( ;; ) {
+
+            /* cycle while there is data to feed zlib and ... */
+
+            rc = ngx_http_gunzip_filter_add_data(r, ctx);
+
+            if (rc == NGX_DECLINED) {
+                break;
+            }
+
+            if (rc == NGX_AGAIN) {
+                continue;
+            }
+
+
+            /* ... there are buffers to write zlib output */
+
+            rc = ngx_http_gunzip_filter_get_buf(r, ctx);
+
+            if (rc == NGX_DECLINED) {
+                break;
+            }
+
+            if (rc == NGX_ERROR) {
+                goto failed;
+            }
+
+            rc = ngx_http_gunzip_filter_inflate(r, ctx);
+
+            if (rc == NGX_OK) {
+                break;
+            }
+
+            if (rc == NGX_ERROR) {
+                goto failed;
+            }
+
+            /* rc == NGX_AGAIN */
+        }
+
+        if (ctx->out == NULL) {
+            return ctx->busy ? NGX_AGAIN : NGX_OK;
+        }
+
+        rc = ngx_http_next_body_filter(r, ctx->out);
+
+        if (rc == NGX_ERROR) {
+            goto failed;
+        }
+
+        ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &ctx->out,
+                                (ngx_buf_tag_t) &ngx_http_gunzip_filter_module);
+        ctx->last_out = &ctx->out;
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "gunzip out: %p", ctx->out);
+
+        ctx->nomem = 0;
+
+        if (ctx->done) {
+            return rc;
+        }
+    }
+
+    /* unreachable */
+
+failed:
+
+    ctx->done = 1;
+
+    return NGX_ERROR;
+}
+
+
+static ngx_int_t
+ngx_http_gunzip_filter_inflate_start(ngx_http_request_t *r,
+    ngx_http_gunzip_ctx_t *ctx)
+{
+    int  rc;
+
+    ctx->zstream.next_in = Z_NULL;
+    ctx->zstream.avail_in = 0;
+
+    ctx->zstream.zalloc = ngx_http_gunzip_filter_alloc;
+    ctx->zstream.zfree = ngx_http_gunzip_filter_free;
+    ctx->zstream.opaque = ctx;
+
+    /* windowBits +16 to decode gzip, zlib 1.2.0.4+ */
+    rc = inflateInit2(&ctx->zstream, MAX_WBITS + 16);
+
+    if (rc != Z_OK) {
+        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                      "inflateInit2() failed: %d", rc);
+        return NGX_ERROR;
+    }
+
+    ctx->started = 1;
+
+    ctx->last_out = &ctx->out;
+    ctx->flush = Z_NO_FLUSH;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_gunzip_filter_add_data(ngx_http_request_t *r,
+    ngx_http_gunzip_ctx_t *ctx)
+{
+    if (ctx->zstream.avail_in || ctx->flush != Z_NO_FLUSH || ctx->redo) {
+        return NGX_OK;
+    }
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "gunzip in: %p", ctx->in);
+
+    if (ctx->in == NULL) {
+        return NGX_DECLINED;
+    }
+
+    ctx->in_buf = ctx->in->buf;
+    ctx->in = ctx->in->next;
+
+    ctx->zstream.next_in = ctx->in_buf->pos;
+    ctx->zstream.avail_in = ctx->in_buf->last - ctx->in_buf->pos;
+
+    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "gunzip in_buf:%p ni:%p ai:%ud",
+                   ctx->in_buf,
+                   ctx->zstream.next_in, ctx->zstream.avail_in);
+
+    if (ctx->in_buf->last_buf || ctx->in_buf->last_in_chain) {
+        ctx->flush = Z_FINISH;
+
+    } else if (ctx->in_buf->flush) {
+        ctx->flush = Z_SYNC_FLUSH;
+
+    } else if (ctx->zstream.avail_in == 0) {
+        /* ctx->flush == Z_NO_FLUSH */
+        return NGX_AGAIN;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_gunzip_filter_get_buf(ngx_http_request_t *r,
+    ngx_http_gunzip_ctx_t *ctx)
+{
+    ngx_http_gunzip_conf_t  *conf;
+
+    if (ctx->zstream.avail_out) {
+        return NGX_OK;
+    }
+
+    conf = ngx_http_get_module_loc_conf(r, ngx_http_gunzip_filter_module);
+
+    if (ctx->free) {
+        ctx->out_buf = ctx->free->buf;
+        ctx->free = ctx->free->next;
+
+        ctx->out_buf->flush = 0;
+
+    } else if (ctx->bufs < conf->bufs.num) {
+
+        ctx->out_buf = ngx_create_temp_buf(r->pool, conf->bufs.size);
+        if (ctx->out_buf == NULL) {
+            return NGX_ERROR;
+        }
+
+        ctx->out_buf->tag = (ngx_buf_tag_t) &ngx_http_gunzip_filter_module;
+        ctx->out_buf->recycled = 1;
+        ctx->bufs++;
+
+    } else {
+        ctx->nomem = 1;
+        return NGX_DECLINED;
+    }
+
+    ctx->zstream.next_out = ctx->out_buf->pos;
+    ctx->zstream.avail_out = conf->bufs.size;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_gunzip_filter_inflate(ngx_http_request_t *r,
+    ngx_http_gunzip_ctx_t *ctx)
+{
+    int           rc;
+    ngx_buf_t    *b;
+    ngx_chain_t  *cl;
+
+    ngx_log_debug6(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "inflate in: ni:%p no:%p ai:%ud ao:%ud fl:%d redo:%d",
+                   ctx->zstream.next_in, ctx->zstream.next_out,
+                   ctx->zstream.avail_in, ctx->zstream.avail_out,
+                   ctx->flush, ctx->redo);
+
+    rc = inflate(&ctx->zstream, ctx->flush);
+
+    if (rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR) {
+        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                      "inflate() failed: %d, %d", ctx->flush, rc);
+        return NGX_ERROR;
+    }
+
+    ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "inflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
+                   ctx->zstream.next_in, ctx->zstream.next_out,
+                   ctx->zstream.avail_in, ctx->zstream.avail_out,
+                   rc);
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "gunzip in_buf:%p pos:%p",
+                   ctx->in_buf, ctx->in_buf->pos);
+
+    if (ctx->zstream.next_in) {
+        ctx->in_buf->pos = ctx->zstream.next_in;
+
+        if (ctx->zstream.avail_in == 0) {
+            ctx->zstream.next_in = NULL;
+        }
+    }
+
+    ctx->out_buf->last = ctx->zstream.next_out;
+
+    if (ctx->zstream.avail_out == 0) {
+
+        /* zlib wants to output some more data */
+
+        cl = ngx_alloc_chain_link(r->pool);
+        if (cl == NULL) {
+            return NGX_ERROR;
+        }
+
+        cl->buf = ctx->out_buf;
+        cl->next = NULL;
+        *ctx->last_out = cl;
+        ctx->last_out = &cl->next;
+
+        ctx->redo = 1;
+
+        return NGX_AGAIN;
+    }
+
+    ctx->redo = 0;
+
+    if (ctx->flush == Z_SYNC_FLUSH) {
+
+        ctx->flush = Z_NO_FLUSH;
+
+        cl = ngx_alloc_chain_link(r->pool);
+        if (cl == NULL) {
+            return NGX_ERROR;
+        }
+
+        b = ctx->out_buf;
+
+        if (ngx_buf_size(b) == 0) {
+
+            b = ngx_calloc_buf(ctx->request->pool);
+            if (b == NULL) {
+                return NGX_ERROR;
+            }
+
+        } else {
+            ctx->zstream.avail_out = 0;
+        }
+
+        b->flush = 1;
+
+        cl->buf = b;
+        cl->next = NULL;
+        *ctx->last_out = cl;
+        ctx->last_out = &cl->next;
+
+        return NGX_OK;
+    }
+
+    if (rc == Z_STREAM_END && ctx->flush == Z_FINISH
+        && ctx->zstream.avail_in == 0)
+    {
+
+        if (ngx_http_gunzip_filter_inflate_end(r, ctx) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
+        return NGX_OK;
+    }
+
+    if (rc == Z_STREAM_END && ctx->zstream.avail_in > 0) {
+
+        rc = inflateReset(&ctx->zstream);
+
+        if (rc != Z_OK) {
+            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                          "inflateReset() failed: %d", rc);
+            return NGX_ERROR;
+        }
+
+        ctx->redo = 1;
+
+        return NGX_AGAIN;
+    }
+
+    if (ctx->in == NULL) {
+
+        b = ctx->out_buf;
+
+        if (ngx_buf_size(b) == 0) {
+            return NGX_OK;
+        }
+
+        cl = ngx_alloc_chain_link(r->pool);
+        if (cl == NULL) {
+            return NGX_ERROR;
+        }
+
+        ctx->zstream.avail_out = 0;
+
+        cl->buf = b;
+        cl->next = NULL;
+        *ctx->last_out = cl;
+        ctx->last_out = &cl->next;
+
+        return NGX_OK;
+    }
+
+    return NGX_AGAIN;
+}
+
+
+static ngx_int_t
+ngx_http_gunzip_filter_inflate_end(ngx_http_request_t *r,
+    ngx_http_gunzip_ctx_t *ctx)
+{
+    int           rc;
+    ngx_buf_t    *b;
+    ngx_chain_t  *cl;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "gunzip inflate end");
+
+    rc = inflateEnd(&ctx->zstream);
+
+    if (rc != Z_OK) {
+        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                      "inflateEnd() failed: %d", rc);
+        return NGX_ERROR;
+    }
+
+    b = ctx->out_buf;
+
+    if (ngx_buf_size(b) == 0) {
+
+        b = ngx_calloc_buf(ctx->request->pool);
+        if (b == NULL) {
+            return NGX_ERROR;
+        }
+    }
+
+    cl = ngx_alloc_chain_link(r->pool);
+    if (cl == NULL) {
+        return NGX_ERROR;
+    }
+
+    cl->buf = b;
+    cl->next = NULL;
+    *ctx->last_out = cl;
+    ctx->last_out = &cl->next;
+
+    b->last_buf = (r == r->main) ? 1 : 0;
+    b->last_in_chain = 1;
+    b->sync = 1;
+
+    ctx->done = 1;
+
+    return NGX_OK;
+}
+
+
+static void *
+ngx_http_gunzip_filter_alloc(void *opaque, u_int items, u_int size)
+{
+    ngx_http_gunzip_ctx_t *ctx = opaque;
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0,
+                   "gunzip alloc: n:%ud s:%ud",
+                   items, size);
+
+    return ngx_palloc(ctx->request->pool, items * size);
+}
+
+
+static void
+ngx_http_gunzip_filter_free(void *opaque, void *address)
+{
+#if 0
+    ngx_http_gunzip_ctx_t *ctx = opaque;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0,
+                   "gunzip free: %p", address);
+#endif
+}
+
+
+static void *
+ngx_http_gunzip_create_conf(ngx_conf_t *cf)
+{
+    ngx_http_gunzip_conf_t  *conf;
+
+    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_gunzip_conf_t));
+    if (conf == NULL) {
+        return NULL;
+    }
+
+    /*
+     * set by ngx_pcalloc():
+     *
+     *     conf->bufs.num = 0;
+     */
+
+    conf->enable = NGX_CONF_UNSET;
+
+    return conf;
+}
+
+
+static char *
+ngx_http_gunzip_merge_conf(ngx_conf_t *cf, void *parent, void *child)
+{
+    ngx_http_gunzip_conf_t *prev = parent;
+    ngx_http_gunzip_conf_t *conf = child;
+
+    ngx_conf_merge_value(conf->enable, prev->enable, 0);
+
+    ngx_conf_merge_bufs_value(conf->bufs, prev->bufs,
+                              (128 * 1024) / ngx_pagesize, ngx_pagesize);
+
+    return NGX_CONF_OK;
+}
+
+
+static ngx_int_t
+ngx_http_gunzip_filter_init(ngx_conf_t *cf)
+{
+    ngx_http_next_header_filter = ngx_http_top_header_filter;
+    ngx_http_top_header_filter = ngx_http_gunzip_header_filter;
+
+    ngx_http_next_body_filter = ngx_http_top_body_filter;
+    ngx_http_top_body_filter = ngx_http_gunzip_body_filter;
+
+    return NGX_OK;
+}

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_gzip_filter_module.c (+8 -1) 99%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_gzip_filter_module.c    2013-07-22 11:05:55 +0900 (128d3d9)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_gzip_filter_module.c    2013-07-22 13:32:39 +0900 (35dd07e)
@@ -306,6 +306,7 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
 
     ngx_http_clear_content_length(r);
     ngx_http_clear_accept_ranges(r);
+    ngx_http_clear_etag(r);
 
     return ngx_http_next_header_filter(r);
 }
@@ -320,7 +321,7 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
 
     ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module);
 
-    if (ctx == NULL || ctx->done) {
+    if (ctx == NULL || ctx->done || r->header_only) {
         return ngx_http_next_body_filter(r, in);
     }
 
@@ -497,6 +498,10 @@ ngx_http_gzip_filter_memory(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
             wbits--;
             memlevel--;
         }
+
+        if (memlevel < 1) {
+            memlevel = 1;
+        }
     }
 
     ctx->wbits = wbits;
@@ -615,6 +620,8 @@ 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;

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_gzip_static_module.c (+36 -10) 87%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_gzip_static_module.c    2013-07-22 11:05:55 +0900 (b0183e0)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_gzip_static_module.c    2013-07-22 13:32:39 +0900 (6e77761)
@@ -10,8 +10,13 @@
 #include <ngx_http.h>
 
 
+#define NGX_HTTP_GZIP_STATIC_OFF     0
+#define NGX_HTTP_GZIP_STATIC_ON      1
+#define NGX_HTTP_GZIP_STATIC_ALWAYS  2
+
+
 typedef struct {
-    ngx_flag_t  enable;
+    ngx_uint_t  enable;
 } ngx_http_gzip_static_conf_t;
 
 
@@ -22,14 +27,22 @@ static char *ngx_http_gzip_static_merge_conf(ngx_conf_t *cf, void *parent,
 static ngx_int_t ngx_http_gzip_static_init(ngx_conf_t *cf);
 
 
+static ngx_conf_enum_t  ngx_http_gzip_static[] = {
+    { ngx_string("off"), NGX_HTTP_GZIP_STATIC_OFF },
+    { ngx_string("on"), NGX_HTTP_GZIP_STATIC_ON },
+    { ngx_string("always"), NGX_HTTP_GZIP_STATIC_ALWAYS },
+    { ngx_null_string, 0 }
+};
+
+
 static ngx_command_t  ngx_http_gzip_static_commands[] = {
 
     { ngx_string("gzip_static"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
-      ngx_conf_set_flag_slot,
+      ngx_conf_set_enum_slot,
       NGX_HTTP_LOC_CONF_OFFSET,
       offsetof(ngx_http_gzip_static_conf_t, enable),
-      NULL },
+      &ngx_http_gzip_static },
 
       ngx_null_command
 };
@@ -92,11 +105,17 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
 
     gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module);
 
-    if (!gzcf->enable) {
+    if (gzcf->enable == NGX_HTTP_GZIP_STATIC_OFF) {
         return NGX_DECLINED;
     }
 
-    rc = ngx_http_gzip_ok(r);
+    if (gzcf->enable == NGX_HTTP_GZIP_STATIC_ON) {
+        rc = ngx_http_gzip_ok(r);
+
+    } else {
+        /* always */
+        rc = NGX_OK;
+    }
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
@@ -169,10 +188,12 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
         return NGX_DECLINED;
     }
 
-    r->gzip_vary = 1;
+    if (gzcf->enable == NGX_HTTP_GZIP_STATIC_ON) {
+        r->gzip_vary = 1;
 
-    if (rc != NGX_OK) {
-        return NGX_DECLINED;
+        if (rc != NGX_OK) {
+            return NGX_DECLINED;
+        }
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", of.fd);
@@ -207,6 +228,10 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
     r->headers_out.content_length_n = of.size;
     r->headers_out.last_modified_time = of.mtime;
 
+    if (ngx_http_set_etag(r) != NGX_OK) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
     if (ngx_http_set_content_type(r) != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -270,7 +295,7 @@ ngx_http_gzip_static_create_conf(ngx_conf_t *cf)
         return NULL;
     }
 
-    conf->enable = NGX_CONF_UNSET;
+    conf->enable = NGX_CONF_UNSET_UINT;
 
     return conf;
 }
@@ -282,7 +307,8 @@ ngx_http_gzip_static_merge_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_http_gzip_static_conf_t *prev = parent;
     ngx_http_gzip_static_conf_t *conf = child;
 
-    ngx_conf_merge_value(conf->enable, prev->enable, 0);
+    ngx_conf_merge_uint_value(conf->enable, prev->enable,
+                              NGX_HTTP_GZIP_STATIC_OFF);
 
     return NGX_CONF_OK;
 }

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_headers_filter_module.c (+32 -13) 94%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_headers_filter_module.c    2013-07-22 11:05:55 +0900 (9389934)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_headers_filter_module.c    2013-07-22 13:32:39 +0900 (0dfe810)
@@ -57,6 +57,8 @@ static ngx_int_t ngx_http_add_header(ngx_http_request_t *r,
     ngx_http_header_val_t *hv, ngx_str_t *value);
 static ngx_int_t ngx_http_set_last_modified(ngx_http_request_t *r,
     ngx_http_header_val_t *hv, ngx_str_t *value);
+static ngx_int_t ngx_http_set_response_header(ngx_http_request_t *r,
+    ngx_http_header_val_t *hv, ngx_str_t *value);
 
 static void *ngx_http_headers_create_conf(ngx_conf_t *cf);
 static char *ngx_http_headers_merge_conf(ngx_conf_t *cf,
@@ -76,6 +78,10 @@ static ngx_http_set_header_t  ngx_http_set_headers[] = {
                  offsetof(ngx_http_headers_out_t, last_modified),
                  ngx_http_set_last_modified },
 
+    { ngx_string("ETag"),
+                 offsetof(ngx_http_headers_out_t, etag),
+                 ngx_http_set_response_header },
+
     { ngx_null_string, 0, NULL }
 };
 
@@ -149,6 +155,7 @@ ngx_http_headers_filter(ngx_http_request_t *r)
     if ((conf->expires == NGX_HTTP_EXPIRES_OFF && conf->headers == NULL)
         || r != r->main
         || (r->headers_out.status != NGX_HTTP_OK
+            && r->headers_out.status != NGX_HTTP_CREATED
             && r->headers_out.status != NGX_HTTP_NO_CONTENT
             && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT
             && r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY
@@ -368,32 +375,44 @@ static ngx_int_t
 ngx_http_set_last_modified(ngx_http_request_t *r, ngx_http_header_val_t *hv,
     ngx_str_t *value)
 {
+    if (ngx_http_set_response_header(r, hv, value) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    r->headers_out.last_modified_time =
+        (value->len) ? ngx_http_parse_time(value->data, value->len) : -1;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_set_response_header(ngx_http_request_t *r, ngx_http_header_val_t *hv,
+    ngx_str_t *value)
+{
     ngx_table_elt_t  *h, **old;
 
     old = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset);
 
-    r->headers_out.last_modified_time = -1;
+    if (value->len == 0) {
+        if (*old) {
+            (*old)->hash = 0;
+            *old = NULL;
+        }
 
-    if (*old == NULL) {
+        return NGX_OK;
+    }
 
-        if (value->len == 0) {
-            return NGX_OK;
-        }
+    if (*old) {
+        h = *old;
 
+    } else {
         h = ngx_list_push(&r->headers_out.headers);
         if (h == NULL) {
             return NGX_ERROR;
         }
 
         *old = h;
-
-    } else {
-        h = *old;
-
-        if (value->len == 0) {
-            h->hash = 0;
-            return NGX_OK;
-        }
     }
 
     h->hash = 1;

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_image_filter_module.c (+40 -13) 96%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_image_filter_module.c    2013-07-22 11:05:55 +0900 (c853c33)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_image_filter_module.c    2013-07-22 13:32:39 +0900 (c6c3b74)
@@ -45,6 +45,7 @@ typedef struct {
     ngx_uint_t                   sharpen;
 
     ngx_flag_t                   transparency;
+    ngx_flag_t                   interlace;
 
     ngx_http_complex_value_t    *wcv;
     ngx_http_complex_value_t    *hcv;
@@ -143,6 +144,13 @@ static ngx_command_t  ngx_http_image_filter_commands[] = {
       offsetof(ngx_http_image_filter_conf_t, transparency),
       NULL },
 
+   { ngx_string("image_filter_interlace"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_image_filter_conf_t, interlace),
+      NULL },
+
     { ngx_string("image_filter_buffer"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_size_slot,
@@ -963,6 +971,8 @@ transparent:
         gdImageSharpen(dst, sharpen);
     }
 
+    gdImageInterlace(dst, (int) conf->interlace);
+
     out = ngx_http_image_out(r, ctx->type, dst, &size);
 
     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -1169,11 +1179,24 @@ ngx_http_image_filter_create_conf(ngx_conf_t *cf)
         return NULL;
     }
 
+    /*
+     * set by ngx_pcalloc():
+     *
+     *     conf->width = 0;
+     *     conf->height = 0;
+     *     conf->angle = 0;
+     *     conf->wcv = NULL;
+     *     conf->hcv = NULL;
+     *     conf->acv = NULL;
+     *     conf->jqcv = NULL;
+     *     conf->shcv = NULL;
+     */
+
     conf->filter = NGX_CONF_UNSET_UINT;
     conf->jpeg_quality = NGX_CONF_UNSET_UINT;
     conf->sharpen = NGX_CONF_UNSET_UINT;
-    conf->angle = NGX_CONF_UNSET_UINT;
     conf->transparency = NGX_CONF_UNSET;
+    conf->interlace = NGX_CONF_UNSET;
     conf->buffer_size = NGX_CONF_UNSET_SIZE;
 
     return conf;
@@ -1195,31 +1218,35 @@ ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
             conf->filter = prev->filter;
             conf->width = prev->width;
             conf->height = prev->height;
+            conf->angle = prev->angle;
             conf->wcv = prev->wcv;
             conf->hcv = prev->hcv;
+            conf->acv = prev->acv;
         }
     }
 
-    /* 75 is libjpeg default quality */
-    ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75);
+    if (conf->jpeg_quality == NGX_CONF_UNSET_UINT) {
 
-    if (conf->jqcv == NULL) {
-        conf->jqcv = prev->jqcv;
-    }
-
-    ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0);
+        /* 75 is libjpeg default quality */
+        ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75);
 
-    if (conf->shcv == NULL) {
-        conf->shcv = prev->shcv;
+        if (conf->jqcv == NULL) {
+            conf->jqcv = prev->jqcv;
+        }
     }
 
-    ngx_conf_merge_uint_value(conf->angle, prev->angle, 0);
-    if (conf->acv == NULL) {
-        conf->acv = prev->acv;
+    if (conf->sharpen == NGX_CONF_UNSET_UINT) {
+        ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0);
+
+        if (conf->shcv == NULL) {
+            conf->shcv = prev->shcv;
+        }
     }
 
     ngx_conf_merge_value(conf->transparency, prev->transparency, 1);
 
+    ngx_conf_merge_value(conf->interlace, prev->interlace, 0);
+
     ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
                               1 * 1024 * 1024);
 

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_index_module.c (+5 -5) 97%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_index_module.c    2013-07-22 11:05:55 +0900 (cfe4ba6)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_index_module.c    2013-07-22 13:32:39 +0900 (d3544db)
@@ -85,12 +85,12 @@ ngx_module_t  ngx_http_index_module = {
 
 /*
  * Try to open/test the first index file before the test of directory
- * existence because valid requests should be much more than invalid ones.
- * If the file open()/stat() would fail, then the directory stat() should
- * be more quickly because some data is already cached in the kernel.
+ * existence because valid requests should prevail over invalid ones.
+ * If open()/stat() of a file will fail then stat() of a directory
+ * should be faster because kernel may have already cached some data.
  * Besides, Win32 may return ERROR_PATH_NOT_FOUND (NGX_ENOTDIR) at once.
- * Unix has ENOTDIR error, however, it's less helpful than Win32's one:
- * it only indicates that path contains an usual file in place of directory.
+ * Unix has ENOTDIR error; however, it's less helpful than Win32's one:
+ * it only indicates that path points to a regular file, not a directory.
  */
 
 static ngx_int_t

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_limit_conn_module.c (+18 -2) 96%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_limit_conn_module.c    2013-07-22 11:05:55 +0900 (e82ca49)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_limit_conn_module.c    2013-07-22 13:32:39 +0900 (7f0eea7)
@@ -40,6 +40,7 @@ typedef struct {
 typedef struct {
     ngx_array_t         limits;
     ngx_uint_t          log_level;
+    ngx_uint_t          status_code;
 } ngx_http_limit_conn_conf_t;
 
 
@@ -74,6 +75,11 @@ static ngx_conf_enum_t  ngx_http_limit_conn_log_levels[] = {
 };
 
 
+static ngx_conf_num_bounds_t  ngx_http_limit_conn_status_bounds = {
+    ngx_conf_check_num_bounds, 400, 599
+};
+
+
 static ngx_command_t  ngx_http_limit_conn_commands[] = {
 
     { ngx_string("limit_conn_zone"),
@@ -104,6 +110,13 @@ static ngx_command_t  ngx_http_limit_conn_commands[] = {
       offsetof(ngx_http_limit_conn_conf_t, log_level),
       &ngx_http_limit_conn_log_levels },
 
+    { ngx_string("limit_conn_status"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_num_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_limit_conn_conf_t, status_code),
+      &ngx_http_limit_conn_status_bounds },
+
       ngx_null_command
 };
 
@@ -206,7 +219,7 @@ ngx_http_limit_conn_handler(ngx_http_request_t *r)
             if (node == NULL) {
                 ngx_shmtx_unlock(&shpool->mutex);
                 ngx_http_limit_conn_cleanup_all(r->pool);
-                return NGX_HTTP_SERVICE_UNAVAILABLE;
+                return lccf->status_code;
             }
 
             lc = (ngx_http_limit_conn_node_t *) &node->color;
@@ -231,7 +244,7 @@ ngx_http_limit_conn_handler(ngx_http_request_t *r)
                               &limits[i].shm_zone->shm.name);
 
                 ngx_http_limit_conn_cleanup_all(r->pool);
-                return NGX_HTTP_SERVICE_UNAVAILABLE;
+                return lccf->status_code;
             }
 
             lc->conn++;
@@ -467,6 +480,7 @@ ngx_http_limit_conn_create_conf(ngx_conf_t *cf)
      */
 
     conf->log_level = NGX_CONF_UNSET_UINT;
+    conf->status_code = NGX_CONF_UNSET_UINT;
 
     return conf;
 }
@@ -483,6 +497,8 @@ ngx_http_limit_conn_merge_conf(ngx_conf_t *cf, void *parent, void *child)
     }
 
     ngx_conf_merge_uint_value(conf->log_level, prev->log_level, NGX_LOG_ERR);
+    ngx_conf_merge_uint_value(conf->status_code, prev->status_code,
+                              NGX_HTTP_SERVICE_UNAVAILABLE);
 
     return NGX_CONF_OK;
 }

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_limit_req_module.c (+19 -2) 97%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_limit_req_module.c    2013-07-22 11:05:55 +0900 (31a8b98)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_limit_req_module.c    2013-07-22 13:32:39 +0900 (90434c9)
@@ -53,6 +53,7 @@ typedef struct {
     ngx_array_t                  limits;
     ngx_uint_t                   limit_log_level;
     ngx_uint_t                   delay_log_level;
+    ngx_uint_t                   status_code;
 } ngx_http_limit_req_conf_t;
 
 
@@ -84,6 +85,11 @@ static ngx_conf_enum_t  ngx_http_limit_req_log_levels[] = {
 };
 
 
+static ngx_conf_num_bounds_t  ngx_http_limit_req_status_bounds = {
+    ngx_conf_check_num_bounds, 400, 599
+};
+
+
 static ngx_command_t  ngx_http_limit_req_commands[] = {
 
     { ngx_string("limit_req_zone"),
@@ -107,6 +113,13 @@ static ngx_command_t  ngx_http_limit_req_commands[] = {
       offsetof(ngx_http_limit_req_conf_t, limit_log_level),
       &ngx_http_limit_req_log_levels },
 
+    { ngx_string("limit_req_status"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_num_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_limit_req_conf_t, status_code),
+      &ngx_http_limit_req_status_bounds },
+
       ngx_null_command
 };
 
@@ -245,7 +258,7 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
             ctx->node = NULL;
         }
 
-        return NGX_HTTP_SERVICE_UNAVAILABLE;
+        return lrcf->status_code;
     }
 
     /* rc == NGX_AGAIN || rc == NGX_OK */
@@ -682,6 +695,7 @@ ngx_http_limit_req_create_conf(ngx_conf_t *cf)
      */
 
     conf->limit_log_level = NGX_CONF_UNSET_UINT;
+    conf->status_code = NGX_CONF_UNSET_UINT;
 
     return conf;
 }
@@ -703,6 +717,9 @@ ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent, void *child)
     conf->delay_log_level = (conf->limit_log_level == NGX_LOG_INFO) ?
                                 NGX_LOG_INFO : conf->limit_log_level + 1;
 
+    ngx_conf_merge_uint_value(conf->status_code, prev->status_code,
+                              NGX_HTTP_SERVICE_UNAVAILABLE);
+
     return NGX_CONF_OK;
 }
 
@@ -778,7 +795,7 @@ ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
             }
 
             rate = ngx_atoi(value[i].data + 5, len - 5);
-            if (rate <= NGX_ERROR) {
+            if (rate <= 0) {
                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                    "invalid rate \"%V\"", &value[i]);
                 return NGX_CONF_ERROR;

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_log_module.c (+378 -40) 76%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_log_module.c    2013-07-22 11:05:55 +0900 (0962c84)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_log_module.c    2013-07-22 13:32:39 +0900 (aa6a3fc)
@@ -9,6 +9,10 @@
 #include <ngx_core.h>
 #include <ngx_http.h>
 
+#if (NGX_ZLIB)
+#include <zlib.h>
+#endif
+
 
 typedef struct ngx_http_log_op_s  ngx_http_log_op_t;
 
@@ -41,6 +45,17 @@ typedef struct {
 
 
 typedef struct {
+    u_char                     *start;
+    u_char                     *pos;
+    u_char                     *last;
+
+    ngx_event_t                *event;
+    ngx_msec_t                  flush;
+    ngx_int_t                   gzip;
+} ngx_http_log_buf_t;
+
+
+typedef struct {
     ngx_array_t                *lengths;
     ngx_array_t                *values;
 } ngx_http_log_script_t;
@@ -78,6 +93,17 @@ static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log,
 static ssize_t ngx_http_log_script_write(ngx_http_request_t *r,
     ngx_http_log_script_t *script, u_char **name, u_char *buf, size_t len);
 
+#if (NGX_ZLIB)
+static ssize_t ngx_http_log_gzip(ngx_fd_t fd, u_char *buf, size_t len,
+    ngx_int_t level, ngx_log_t *log);
+
+static void *ngx_http_log_gzip_alloc(void *opaque, u_int items, u_int size);
+static void ngx_http_log_gzip_free(void *opaque, void *address);
+#endif
+
+static void ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log);
+static void ngx_http_log_flush_handler(ngx_event_t *ev);
+
 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf,
     ngx_http_log_op_t *op);
 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf,
@@ -132,7 +158,7 @@ static ngx_command_t  ngx_http_log_commands[] = {
 
     { ngx_string("access_log"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-                        |NGX_HTTP_LMT_CONF|NGX_CONF_TAKE123,
+                        |NGX_HTTP_LMT_CONF|NGX_CONF_1MORE,
       ngx_http_log_set_log,
       NGX_HTTP_LOC_CONF_OFFSET,
       0,
@@ -216,8 +242,8 @@ ngx_http_log_handler(ngx_http_request_t *r)
     size_t                    len;
     ngx_uint_t                i, l;
     ngx_http_log_t           *log;
-    ngx_open_file_t          *file;
     ngx_http_log_op_t        *op;
+    ngx_http_log_buf_t       *buffer;
     ngx_http_log_loc_conf_t  *lcf;
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -258,21 +284,25 @@ ngx_http_log_handler(ngx_http_request_t *r)
 
         len += NGX_LINEFEED_SIZE;
 
-        file = log[l].file;
+        buffer = log[l].file ? log[l].file->data : NULL;
 
-        if (file && file->buffer) {
+        if (buffer) {
 
-            if (len > (size_t) (file->last - file->pos)) {
+            if (len > (size_t) (buffer->last - buffer->pos)) {
 
-                ngx_http_log_write(r, &log[l], file->buffer,
-                                   file->pos - file->buffer);
+                ngx_http_log_write(r, &log[l], buffer->start,
+                                   buffer->pos - buffer->start);
 
-                file->pos = file->buffer;
+                buffer->pos = buffer->start;
             }
 
-            if (len <= (size_t) (file->last - file->pos)) {
+            if (len <= (size_t) (buffer->last - buffer->pos)) {
 
-                p = file->pos;
+                p = buffer->pos;
+
+                if (buffer->event && p == buffer->start) {
+                    ngx_add_timer(buffer->event, buffer->flush);
+                }
 
                 for (i = 0; i < log[l].format->ops->nelts; i++) {
                     p = op[i].run(r, p, &op[i]);
@@ -280,10 +310,14 @@ ngx_http_log_handler(ngx_http_request_t *r)
 
                 ngx_linefeed(p);
 
-                file->pos = p;
+                buffer->pos = p;
 
                 continue;
             }
+
+            if (buffer->event && buffer->event->timer_set) {
+                ngx_del_timer(buffer->event);
+            }
         }
 
         line = ngx_pnalloc(r->pool, len);
@@ -310,14 +344,29 @@ static void
 ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf,
     size_t len)
 {
-    u_char     *name;
-    time_t      now;
-    ssize_t     n;
-    ngx_err_t   err;
+    u_char              *name;
+    time_t               now;
+    ssize_t              n;
+    ngx_err_t            err;
+#if (NGX_ZLIB)
+    ngx_http_log_buf_t  *buffer;
+#endif
 
     if (log->script == NULL) {
         name = log->file->name.data;
+
+#if (NGX_ZLIB)
+        buffer = log->file->data;
+
+        if (buffer && buffer->gzip) {
+            n = ngx_http_log_gzip(log->file->fd, buf, len, buffer->gzip,
+                                  r->connection->log);
+        } else {
+            n = ngx_write_fd(log->file->fd, buf, len);
+        }
+#else
         n = ngx_write_fd(log->file->fd, buf, len);
+#endif
 
     } else {
         name = NULL;
@@ -465,6 +514,194 @@ ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script,
 }
 
 
+#if (NGX_ZLIB)
+
+static ssize_t
+ngx_http_log_gzip(ngx_fd_t fd, u_char *buf, size_t len, ngx_int_t level,
+    ngx_log_t *log)
+{
+    int          rc, wbits, memlevel;
+    u_char      *out;
+    size_t       size;
+    ssize_t      n;
+    z_stream     zstream;
+    ngx_err_t    err;
+    ngx_pool_t  *pool;
+
+    wbits = MAX_WBITS;
+    memlevel = MAX_MEM_LEVEL - 1;
+
+    while ((ssize_t) len < ((1 << (wbits - 1)) - 262)) {
+        wbits--;
+        memlevel--;
+    }
+
+    /*
+     * This is a formula from deflateBound() for conservative upper bound of
+     * compressed data plus 18 bytes of gzip wrapper.
+     */
+
+    size = len + ((len + 7) >> 3) + ((len + 63) >> 6) + 5 + 18;
+
+    ngx_memzero(&zstream, sizeof(z_stream));
+
+    pool = ngx_create_pool(256, log);
+    if (pool == NULL) {
+        /* simulate successful logging */
+        return len;
+    }
+
+    pool->log = log;
+
+    zstream.zalloc = ngx_http_log_gzip_alloc;
+    zstream.zfree = ngx_http_log_gzip_free;
+    zstream.opaque = pool;
+
+    out = ngx_pnalloc(pool, size);
+    if (out == NULL) {
+        goto done;
+    }
+
+    zstream.next_in = buf;
+    zstream.avail_in = len;
+    zstream.next_out = out;
+    zstream.avail_out = size;
+
+    rc = deflateInit2(&zstream, (int) level, Z_DEFLATED, wbits + 16, memlevel,
+                      Z_DEFAULT_STRATEGY);
+
+    if (rc != Z_OK) {
+        ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateInit2() failed: %d", rc);
+        goto done;
+    }
+
+    ngx_log_debug4(NGX_LOG_DEBUG_HTTP, log, 0,
+                   "deflate in: ni:%p no:%p ai:%ud ao:%ud",
+                   zstream.next_in, zstream.next_out,
+                   zstream.avail_in, zstream.avail_out);
+
+    rc = deflate(&zstream, Z_FINISH);
+
+    if (rc != Z_STREAM_END) {
+        ngx_log_error(NGX_LOG_ALERT, log, 0,
+                      "deflate(Z_FINISH) failed: %d", rc);
+        goto done;
+    }
+
+    ngx_log_debug5(NGX_LOG_DEBUG_HTTP, log, 0,
+                   "deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
+                   zstream.next_in, zstream.next_out,
+                   zstream.avail_in, zstream.avail_out,
+                   rc);
+
+    size -= zstream.avail_out;
+
+    rc = deflateEnd(&zstream);
+
+    if (rc != Z_OK) {
+        ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateEnd() failed: %d", rc);
+        goto done;
+    }
+
+    n = ngx_write_fd(fd, out, size);
+
+    if (n != (ssize_t) size) {
+        err = (n == -1) ? ngx_errno : 0;
+
+        ngx_destroy_pool(pool);
+
+        ngx_set_errno(err);
+        return -1;
+    }
+
+done:
+
+    ngx_destroy_pool(pool);
+
+    /* simulate successful logging */
+    return len;
+}
+
+
+static void *
+ngx_http_log_gzip_alloc(void *opaque, u_int items, u_int size)
+{
+    ngx_pool_t *pool = opaque;
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pool->log, 0,
+                   "gzip alloc: n:%ud s:%ud", items, size);
+
+    return ngx_palloc(pool, items * size);
+}
+
+
+static void
+ngx_http_log_gzip_free(void *opaque, void *address)
+{
+#if 0
+    ngx_pool_t *pool = opaque;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pool->log, 0, "gzip free: %p", address);
+#endif
+}
+
+#endif
+
+
+static void
+ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log)
+{
+    size_t               len;
+    ssize_t              n;
+    ngx_http_log_buf_t  *buffer;
+
+    buffer = file->data;
+
+    len = buffer->pos - buffer->start;
+
+    if (len == 0) {
+        return;
+    }
+
+#if (NGX_ZLIB)
+    if (buffer->gzip) {
+        n = ngx_http_log_gzip(file->fd, buffer->start, len, buffer->gzip, log);
+    } else {
+        n = ngx_write_fd(file->fd, buffer->start, len);
+    }
+#else
+    n = ngx_write_fd(file->fd, buffer->start, len);
+#endif
+
+    if (n == -1) {
+        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+                      ngx_write_fd_n " to \"%s\" failed",
+                      file->name.data);
+
+    } else if ((size_t) n != len) {
+        ngx_log_error(NGX_LOG_ALERT, log, 0,
+                      ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
+                      file->name.data, n, len);
+    }
+
+    buffer->pos = buffer->start;
+
+    if (buffer->event && buffer->event->timer_set) {
+        ngx_del_timer(buffer->event);
+    }
+}
+
+
+static void
+ngx_http_log_flush_handler(ngx_event_t *ev)
+{
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0,
+                   "http log buffer flush handler");
+
+    ngx_http_log_flush(ev->data, ev->log);
+}
+
+
 static u_char *
 ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf,
     ngx_http_log_op_t *op)
@@ -848,10 +1085,13 @@ 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                     buf;
+    ssize_t                     size;
+    ngx_int_t                   gzip;
     ngx_uint_t                  i, n;
-    ngx_str_t                  *value, name;
+    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;
@@ -936,54 +1176,152 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
             && ngx_strcasecmp(fmt[i].name.data, name.data) == 0)
         {
             log->format = &fmt[i];
-            goto buffer;
+            break;
         }
     }
 
-    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                       "unknown log format \"%V\"", &name);
-    return NGX_CONF_ERROR;
+    if (log->format == NULL) {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "unknown log format \"%V\"", &name);
+        return NGX_CONF_ERROR;
+    }
+
+    size = 0;
+    flush = 0;
+    gzip = 0;
+
+    for (i = 3; i < cf->args->nelts; i++) {
+
+        if (ngx_strncmp(value[i].data, "buffer=", 7) == 0) {
+            s.len = value[i].len - 7;
+            s.data = value[i].data + 7;
+
+            size = ngx_parse_size(&s);
+
+            if (size == NGX_ERROR || size == 0) {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                   "invalid buffer size \"%V\"", &s);
+                return NGX_CONF_ERROR;
+            }
 
-buffer:
+            continue;
+        }
+
+        if (ngx_strncmp(value[i].data, "flush=", 6) == 0) {
+            s.len = value[i].len - 6;
+            s.data = value[i].data + 6;
+
+            flush = ngx_parse_time(&s, 0);
+
+            if (flush == (ngx_msec_t) NGX_ERROR || flush == 0) {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                   "invalid flush time \"%V\"", &s);
+                return NGX_CONF_ERROR;
+            }
 
-    if (cf->args->nelts == 4) {
-        if (ngx_strncmp(value[3].data, "buffer=", 7) != 0) {
+            continue;
+        }
+
+        if (ngx_strncmp(value[i].data, "gzip", 4) == 0
+            && (value[i].len == 4 || value[i].data[4] == '='))
+        {
+#if (NGX_ZLIB)
+            if (size == 0) {
+                size = 64 * 1024;
+            }
+
+            if (value[i].len == 4) {
+                gzip = Z_BEST_SPEED;
+                continue;
+            }
+
+            s.len = value[i].len - 5;
+            s.data = value[i].data + 5;
+
+            gzip = ngx_atoi(s.data, s.len);
+
+            if (gzip < 1 || gzip > 9) {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                   "invalid compression level \"%V\"", &s);
+                return NGX_CONF_ERROR;
+            }
+
+            continue;
+
+#else
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "invalid parameter \"%V\"", &value[3]);
+                               "nginx was built without zlib support");
             return NGX_CONF_ERROR;
+#endif
         }
 
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "invalid parameter \"%V\"", &value[i]);
+        return NGX_CONF_ERROR;
+    }
+
+    if (flush && size == 0) {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "no buffer is defined for access_log \"%V\"",
+                           &value[1]);
+        return NGX_CONF_ERROR;
+    }
+
+    if (size) {
+
         if (log->script) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                "buffered logs cannot have variables in name");
             return NGX_CONF_ERROR;
         }
 
-        name.len = value[3].len - 7;
-        name.data = value[3].data + 7;
+        if (log->file->data) {
+            buffer = log->file->data;
+
+            if (buffer->last - buffer->start != size
+                || buffer->flush != flush
+                || buffer->gzip != gzip)
+            {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                   "access_log \"%V\" already defined "
+                                   "with conflicting parameters",
+                                   &value[1]);
+                return NGX_CONF_ERROR;
+            }
 
-        buf = ngx_parse_size(&name);
+            return NGX_CONF_OK;
+        }
 
-        if (buf == NGX_ERROR) {
-            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "invalid buffer value \"%V\"", &name);
+        buffer = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_buf_t));
+        if (buffer == NULL) {
             return NGX_CONF_ERROR;
         }
 
-        if (log->file->buffer && log->file->last - log->file->pos != buf) {
-            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "access_log \"%V\" already defined "
-                               "with different buffer size", &value[1]);
+        buffer->start = ngx_pnalloc(cf->pool, size);
+        if (buffer->start == NULL) {
             return NGX_CONF_ERROR;
         }
 
-        log->file->buffer = ngx_palloc(cf->pool, buf);
-        if (log->file->buffer == NULL) {
-            return NGX_CONF_ERROR;
+        buffer->pos = buffer->start;
+        buffer->last = buffer->start + size;
+
+        if (flush) {
+            buffer->event = ngx_pcalloc(cf->pool, sizeof(ngx_event_t));
+            if (buffer->event == NULL) {
+                return NGX_CONF_ERROR;
+            }
+
+            buffer->event->data = log->file;
+            buffer->event->handler = ngx_http_log_flush_handler;
+            buffer->event->log = &cf->cycle->new_log;
+
+            buffer->flush = flush;
         }
 
-        log->file->pos = log->file->buffer;
-        log->file->last = log->file->buffer + buf;
+        buffer->gzip = gzip;
+
+        log->file->flush = ngx_http_log_flush;
+        log->file->data = buffer;
     }
 
     return NGX_CONF_OK;

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_map_module.c (+8 -1) 98%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_map_module.c    2013-07-22 11:05:55 +0900 (371737b)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_map_module.c    2013-07-22 13:32:39 +0900 (13c8b97)
@@ -209,6 +209,13 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     }
 
     name = value[2];
+
+    if (name.data[0] != '$') {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "invalid variable name \"%V\"", &name);
+        return NGX_CONF_ERROR;
+    }
+
     name.len--;
     name.data++;
 
@@ -220,7 +227,7 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     var->get_handler = ngx_http_map_variable;
     var->data = (uintptr_t) map;
 
-    pool = ngx_create_pool(16384, cf->log);
+    pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
     if (pool == NULL) {
         return NGX_CONF_ERROR;
     }

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_memcached_module.c (+60 -8) 89%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_memcached_module.c    2013-07-22 11:05:55 +0900 (5077ded)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_memcached_module.c    2013-07-22 13:32:39 +0900 (278b1ed)
@@ -13,6 +13,7 @@
 typedef struct {
     ngx_http_upstream_conf_t   upstream;
     ngx_int_t                  index;
+    ngx_uint_t                 gzip_flag;
 } ngx_http_memcached_loc_conf_t;
 
 
@@ -101,6 +102,13 @@ static ngx_command_t  ngx_http_memcached_commands[] = {
       offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream),
       &ngx_http_memcached_next_upstream_masks },
 
+    { ngx_string("memcached_gzip_flag"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_num_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_memcached_loc_conf_t, gzip_flag),
+      NULL },
+
       ngx_null_command
 };
 
@@ -281,10 +289,13 @@ ngx_http_memcached_reinit_request(ngx_http_request_t *r)
 static ngx_int_t
 ngx_http_memcached_process_header(ngx_http_request_t *r)
 {
-    u_char                    *p, *len;
-    ngx_str_t                  line;
-    ngx_http_upstream_t       *u;
-    ngx_http_memcached_ctx_t  *ctx;
+    u_char                         *p, *start;
+    ngx_str_t                       line;
+    ngx_uint_t                      flags;
+    ngx_table_elt_t                *h;
+    ngx_http_upstream_t            *u;
+    ngx_http_memcached_ctx_t       *ctx;
+    ngx_http_memcached_loc_conf_t  *mlcf;
 
     u = r->upstream;
 
@@ -309,6 +320,7 @@ found:
     p = u->buffer.pos;
 
     ctx = ngx_http_get_module_ctx(r, ngx_http_memcached_module);
+    mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
 
     if (ngx_strncmp(p, "VALUE ", sizeof("VALUE ") - 1) == 0) {
 
@@ -329,23 +341,56 @@ found:
             goto no_valid;
         }
 
-        /* skip flags */
+        /* flags */
+
+        start = p;
 
         while (*p) {
             if (*p++ == ' ') {
-                goto length;
+                if (mlcf->gzip_flag) {
+                    goto flags;
+                } else {
+                    goto length;
+                }
             }
         }
 
         goto no_valid;
 
+    flags:
+
+        flags = ngx_atoi(start, p - start - 1);
+
+        if (flags == (ngx_uint_t) NGX_ERROR) {
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                          "memcached sent invalid flags in response \"%V\" "
+                          "for key \"%V\"",
+                          &line, &ctx->key);
+            return NGX_HTTP_UPSTREAM_INVALID_HEADER;
+        }
+
+        if (flags & mlcf->gzip_flag) {
+            h = ngx_list_push(&r->headers_out.headers);
+            if (h == NULL) {
+                return NGX_ERROR;
+            }
+
+            h->hash = 1;
+            h->key.len = sizeof("Content-Encoding") - 1;
+            h->key.data = (u_char *) "Content-Encoding";
+            h->value.len = sizeof("gzip") - 1;
+            h->value.data = (u_char *) "gzip";
+
+            r->headers_out.content_encoding = h;
+        }
+
     length:
 
-        len = p;
+        start = p;
 
         while (*p && *p++ != CR) { /* void */ }
 
-        u->headers_in.content_length_n = ngx_atoof(len, p - len - 1);
+        u->headers_in.content_length_n = ngx_atoof(start, p - start - 1);
         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\" "
@@ -529,6 +574,7 @@ ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
      *     conf->upstream.location = NULL;
      */
 
+    conf->upstream.local = NGX_CONF_UNSET_PTR;
     conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
@@ -550,6 +596,7 @@ ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
     conf->upstream.pass_request_body = 0;
 
     conf->index = NGX_CONF_UNSET;
+    conf->gzip_flag = NGX_CONF_UNSET_UINT;
 
     return conf;
 }
@@ -561,6 +608,9 @@ ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_http_memcached_loc_conf_t *prev = parent;
     ngx_http_memcached_loc_conf_t *conf = child;
 
+    ngx_conf_merge_ptr_value(conf->upstream.local,
+                              prev->upstream.local, NULL);
+
     ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
                               prev->upstream.connect_timeout, 60000);
 
@@ -593,6 +643,8 @@ ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
         conf->index = prev->index;
     }
 
+    ngx_conf_merge_uint_value(conf->gzip_flag, prev->gzip_flag, 0);
+
     return NGX_CONF_OK;
 }
 

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_mp4_module.c (+11 -8) 99%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_mp4_module.c    2013-07-22 11:05:55 +0900 (d3be234)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_mp4_module.c    2013-07-22 13:32:39 +0900 (20ef51a)
@@ -586,6 +586,10 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
     r->headers_out.status = NGX_HTTP_OK;
     r->headers_out.last_modified_time = of.mtime;
 
+    if (ngx_http_set_etag(r) != NGX_OK) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
     if (ngx_http_set_content_type(r) != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -750,6 +754,13 @@ ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
 
     *prev = &mp4->mdat_atom;
 
+    if (start_offset > mp4->mdat_data.buf->file_last) {
+        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
+                      "start time is out mp4 mdat atom in \"%s\"",
+                      mp4->file.name.data);
+        return NGX_ERROR;
+    }
+
     adjustment = mp4->ftyp_size + mp4->moov_size
                  + ngx_http_mp4_update_mdat_atom(mp4, start_offset)
                  - start_offset;
@@ -1838,14 +1849,6 @@ ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
                    ngx_mp4_get_32value(stsd_atom->entries),
                    4, stsd_atom->media_name);
 
-    /* supported media format: "avc1" (H.264) and "mp4a" (MPEG-4/AAC) */
-
-    if (ngx_strncmp(stsd_atom->media_name, "avc1", 4) != 0
-        && ngx_strncmp(stsd_atom->media_name, "mp4a", 4) != 0)
-    {
-        return NGX_DECLINED;
-    }
-
     trak = ngx_mp4_last_trak(mp4);
 
     atom = &trak->stsd_atom_buf;

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_not_modified_filter_module.c (+126 -29) 50%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_not_modified_filter_module.c    2013-07-22 11:05:55 +0900 (488c36b)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_not_modified_filter_module.c    2013-07-22 13:32:39 +0900 (7f1ab62)
@@ -10,8 +10,10 @@
 #include <ngx_http.h>
 
 
-static ngx_int_t ngx_http_test_precondition(ngx_http_request_t *r);
-static ngx_int_t ngx_http_test_not_modified(ngx_http_request_t *r);
+static ngx_uint_t ngx_http_test_if_unmodified(ngx_http_request_t *r);
+static ngx_uint_t ngx_http_test_if_modified(ngx_http_request_t *r);
+static ngx_uint_t ngx_http_test_if_match(ngx_http_request_t *r,
+    ngx_table_elt_t *header);
 static ngx_int_t ngx_http_not_modified_filter_init(ngx_conf_t *cf);
 
 
@@ -59,20 +61,56 @@ ngx_http_not_modified_header_filter(ngx_http_request_t *r)
         return ngx_http_next_header_filter(r);
     }
 
-    if (r->headers_in.if_unmodified_since) {
-        return ngx_http_test_precondition(r);
+    if (r->headers_in.if_unmodified_since
+        && !ngx_http_test_if_unmodified(r))
+    {
+        return ngx_http_filter_finalize_request(r, NULL,
+                                                NGX_HTTP_PRECONDITION_FAILED);
     }
 
-    if (r->headers_in.if_modified_since) {
-        return ngx_http_test_not_modified(r);
+    if (r->headers_in.if_match
+        && !ngx_http_test_if_match(r, r->headers_in.if_match))
+    {
+        return ngx_http_filter_finalize_request(r, NULL,
+                                                NGX_HTTP_PRECONDITION_FAILED);
+    }
+
+    if (r->headers_in.if_modified_since || r->headers_in.if_none_match) {
+
+        if (r->headers_in.if_modified_since
+            && ngx_http_test_if_modified(r))
+        {
+            return ngx_http_next_header_filter(r);
+        }
+
+        if (r->headers_in.if_none_match
+            && !ngx_http_test_if_match(r, r->headers_in.if_none_match))
+        {
+            return ngx_http_next_header_filter(r);
+        }
+
+        /* not modified */
+
+        r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
+        r->headers_out.status_line.len = 0;
+        r->headers_out.content_type.len = 0;
+        ngx_http_clear_content_length(r);
+        ngx_http_clear_accept_ranges(r);
+
+        if (r->headers_out.content_encoding) {
+            r->headers_out.content_encoding->hash = 0;
+            r->headers_out.content_encoding = NULL;
+        }
+
+        return ngx_http_next_header_filter(r);
     }
 
     return ngx_http_next_header_filter(r);
 }
 
 
-static ngx_int_t
-ngx_http_test_precondition(ngx_http_request_t *r)
+static ngx_uint_t
+ngx_http_test_if_unmodified(ngx_http_request_t *r)
 {
     time_t  iums;
 
@@ -83,16 +121,15 @@ ngx_http_test_precondition(ngx_http_request_t *r)
                  "http iums:%d lm:%d", iums, r->headers_out.last_modified_time);
 
     if (iums >= r->headers_out.last_modified_time) {
-        return ngx_http_next_header_filter(r);
+        return 1;
     }
 
-    return ngx_http_filter_finalize_request(r, NULL,
-                                            NGX_HTTP_PRECONDITION_FAILED);
+    return 0;
 }
 
 
-static ngx_int_t
-ngx_http_test_not_modified(ngx_http_request_t *r)
+static ngx_uint_t
+ngx_http_test_if_modified(ngx_http_request_t *r)
 {
     time_t                     ims;
     ngx_http_core_loc_conf_t  *clcf;
@@ -100,7 +137,7 @@ ngx_http_test_not_modified(ngx_http_request_t *r)
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
     if (clcf->if_modified_since == NGX_HTTP_IMS_OFF) {
-        return ngx_http_next_header_filter(r);
+        return 1;
     }
 
     ims = ngx_http_parse_time(r->headers_in.if_modified_since->value.data,
@@ -109,27 +146,87 @@ ngx_http_test_not_modified(ngx_http_request_t *r)
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http ims:%d lm:%d", ims, r->headers_out.last_modified_time);
 
-    if (ims != r->headers_out.last_modified_time) {
+    if (ims == r->headers_out.last_modified_time) {
+        return 0;
+    }
 
-        if (clcf->if_modified_since == NGX_HTTP_IMS_EXACT
-            || ims < r->headers_out.last_modified_time)
-        {
-            return ngx_http_next_header_filter(r);
-        }
+    if (clcf->if_modified_since == NGX_HTTP_IMS_EXACT
+        || ims < r->headers_out.last_modified_time)
+    {
+        return 1;
     }
 
-    r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
-    r->headers_out.status_line.len = 0;
-    r->headers_out.content_type.len = 0;
-    ngx_http_clear_content_length(r);
-    ngx_http_clear_accept_ranges(r);
+    return 0;
+}
+
 
-    if (r->headers_out.content_encoding) {
-        r->headers_out.content_encoding->hash = 0;
-        r->headers_out.content_encoding = NULL;
+static ngx_uint_t
+ngx_http_test_if_match(ngx_http_request_t *r, ngx_table_elt_t *header)
+{
+    u_char     *start, *end, ch;
+    ngx_str_t  *etag, *list;
+
+    list = &header->value;
+
+    if (list->len == 1 && list->data[0] == '*') {
+        return 1;
     }
 
-    return ngx_http_next_header_filter(r);
+    if (r->headers_out.etag == NULL) {
+        return 0;
+    }
+
+    etag = &r->headers_out.etag->value;
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http im:\"%V\" etag:%V", list, etag);
+
+    start = list->data;
+    end = list->data + list->len;
+
+    while (start < end) {
+
+        if (etag->len > (size_t) (end - start)) {
+            return 0;
+        }
+
+        if (ngx_strncmp(start, etag->data, etag->len) != 0) {
+            goto skip;
+        }
+
+        start += etag->len;
+
+        while (start < end) {
+            ch = *start;
+
+            if (ch == ' ' || ch == '\t') {
+                start++;
+                continue;
+            }
+
+            break;
+        }
+
+        if (start == end || *start == ',') {
+            return 1;
+        }
+
+    skip:
+
+        while (start < end && *start != ',') { start++; }
+        while (start < end) {
+            ch = *start;
+
+            if (ch == ' ' || ch == '\t' || ch == ',') {
+                start++;
+                continue;
+            }
+
+            break;
+        }
+    }
+
+    return 0;
 }
 
 

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_proxy_module.c (+70 -309) 92%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_proxy_module.c    2013-07-22 11:05:55 +0900 (387f77f)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_proxy_module.c    2013-07-22 13:32:39 +0900 (5e62caa)
@@ -81,12 +81,9 @@ typedef struct {
 
 typedef struct {
     ngx_http_status_t              status;
+    ngx_http_chunked_t             chunked;
     ngx_http_proxy_vars_t          vars;
-    size_t                         internal_body_length;
-
-    ngx_uint_t                     state;
-    off_t                          size;
-    off_t                          length;
+    off_t                          internal_body_length;
 
     ngx_uint_t                     head;  /* unsigned  head:1 */
 } ngx_http_proxy_ctx_t;
@@ -558,6 +555,8 @@ static char  ngx_http_proxy_version_11[] = " HTTP/1.1" CRLF;
 static ngx_keyval_t  ngx_http_proxy_headers[] = {
     { ngx_string("Host"), ngx_string("$proxy_host") },
     { ngx_string("Connection"), ngx_string("close") },
+    { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") },
+    { ngx_string("Transfer-Encoding"), ngx_string("") },
     { ngx_string("Keep-Alive"), ngx_string("") },
     { ngx_string("Expect"), ngx_string("") },
     { ngx_string("Upgrade"), ngx_string("") },
@@ -583,6 +582,8 @@ static ngx_str_t  ngx_http_proxy_hide_headers[] = {
 static ngx_keyval_t  ngx_http_proxy_cache_headers[] = {
     { ngx_string("Host"), ngx_string("$proxy_host") },
     { ngx_string("Connection"), ngx_string("close") },
+    { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") },
+    { ngx_string("Transfer-Encoding"), ngx_string("") },
     { ngx_string("Keep-Alive"), ngx_string("") },
     { ngx_string("Expect"), ngx_string("") },
     { ngx_string("Upgrade"), ngx_string("") },
@@ -614,7 +615,8 @@ static ngx_http_variable_t  ngx_http_proxy_vars[] = {
 #endif
 
     { ngx_string("proxy_internal_body_length"), NULL,
-      ngx_http_proxy_internal_body_length_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
+      ngx_http_proxy_internal_body_length_variable, 0,
+      NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
 
     { ngx_null_string, NULL, NULL, 0, 0, 0 }
 };
@@ -836,7 +838,7 @@ ngx_http_proxy_create_key(ngx_http_request_t *r)
         return NGX_ERROR;
     }
 
-    if (plcf->cache_key.value.len) {
+    if (plcf->cache_key.value.data) {
 
         if (ngx_http_complex_value(r, &plcf->cache_key, key) != NGX_OK) {
             return NGX_ERROR;
@@ -1006,6 +1008,9 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
 
         ctx->internal_body_length = body_len;
         len += body_len;
+
+    } else {
+        ctx->internal_body_length = r->headers_in.content_length_n;
     }
 
     le.ip = plcf->headers_set_len->elts;
@@ -1252,7 +1257,7 @@ ngx_http_proxy_reinit_request(ngx_http_request_t *r)
     ctx->status.count = 0;
     ctx->status.start = NULL;
     ctx->status.end = NULL;
-    ctx->state = 0;
+    ctx->chunked.state = 0;
 
     r->upstream->process_header = ngx_http_proxy_process_status_line;
     r->upstream->pipe->input_filter = ngx_http_proxy_copy_filter;
@@ -1470,6 +1475,14 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
                 u->keepalive = !u->headers_in.connection_close;
             }
 
+            if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS) {
+                u->keepalive = 0;
+
+                if (r->headers_in.upgrade) {
+                    u->upgrade = 1;
+                }
+            }
+
             return NGX_OK;
         }
 
@@ -1610,272 +1623,14 @@ ngx_http_proxy_copy_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
         p->upstream_done = 1;
 
         ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
-                      "upstream sent too much data");
+                      "upstream sent more data than specified in "
+                      "\"Content-Length\" header");
     }
 
     return NGX_OK;
 }
 
 
-static ngx_inline ngx_int_t
-ngx_http_proxy_parse_chunked(ngx_http_request_t *r, ngx_buf_t *buf)
-{
-    u_char                *pos, ch, c;
-    ngx_int_t              rc;
-    ngx_http_proxy_ctx_t  *ctx;
-    enum {
-        sw_chunk_start = 0,
-        sw_chunk_size,
-        sw_chunk_extension,
-        sw_chunk_extension_almost_done,
-        sw_chunk_data,
-        sw_after_data,
-        sw_after_data_almost_done,
-        sw_last_chunk_extension,
-        sw_last_chunk_extension_almost_done,
-        sw_trailer,
-        sw_trailer_almost_done,
-        sw_trailer_header,
-        sw_trailer_header_almost_done
-    } state;
-
-    ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
-    if (ctx == NULL) {
-        return NGX_ERROR;
-    }
-
-    state = ctx->state;
-
-    if (state == sw_chunk_data && ctx->size == 0) {
-        state = sw_after_data;
-    }
-
-    rc = NGX_AGAIN;
-
-    for (pos = buf->pos; pos < buf->last; pos++) {
-
-        ch = *pos;
-
-        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "http proxy chunked byte: %02Xd s:%d", ch, state);
-
-        switch (state) {
-
-        case sw_chunk_start:
-            if (ch >= '0' && ch <= '9') {
-                state = sw_chunk_size;
-                ctx->size = ch - '0';
-                break;
-            }
-
-            c = (u_char) (ch | 0x20);
-
-            if (c >= 'a' && c <= 'f') {
-                state = sw_chunk_size;
-                ctx->size = c - 'a' + 10;
-                break;
-            }
-
-            goto invalid;
-
-        case sw_chunk_size:
-            if (ch >= '0' && ch <= '9') {
-                ctx->size = ctx->size * 16 + (ch - '0');
-                break;
-            }
-
-            c = (u_char) (ch | 0x20);
-
-            if (c >= 'a' && c <= 'f') {
-                ctx->size = ctx->size * 16 + (c - 'a' + 10);
-                break;
-            }
-
-            if (ctx->size == 0) {
-
-                switch (ch) {
-                case CR:
-                    state = sw_last_chunk_extension_almost_done;
-                    break;
-                case LF:
-                    state = sw_trailer;
-                    break;
-                case ';':
-                case ' ':
-                case '\t':
-                    state = sw_last_chunk_extension;
-                    break;
-                default:
-                    goto invalid;
-                }
-
-                break;
-            }
-
-            switch (ch) {
-            case CR:
-                state = sw_chunk_extension_almost_done;
-                break;
-            case LF:
-                state = sw_chunk_data;
-                break;
-            case ';':
-            case ' ':
-            case '\t':
-                state = sw_chunk_extension;
-                break;
-            default:
-                goto invalid;
-            }
-
-            break;
-
-        case sw_chunk_extension:
-            switch (ch) {
-            case CR:
-                state = sw_chunk_extension_almost_done;
-                break;
-            case LF:
-                state = sw_chunk_data;
-            }
-            break;
-
-        case sw_chunk_extension_almost_done:
-            if (ch == LF) {
-                state = sw_chunk_data;
-                break;
-            }
-            goto invalid;
-
-        case sw_chunk_data:
-            rc = NGX_OK;
-            goto data;
-
-        case sw_after_data:
-            switch (ch) {
-            case CR:
-                state = sw_after_data_almost_done;
-                break;
-            case LF:
-                state = sw_chunk_start;
-            }
-            break;
-
-        case sw_after_data_almost_done:
-            if (ch == LF) {
-                state = sw_chunk_start;
-                break;
-            }
-            goto invalid;
-
-        case sw_last_chunk_extension:
-            switch (ch) {
-            case CR:
-                state = sw_last_chunk_extension_almost_done;
-                break;
-            case LF:
-                state = sw_trailer;
-            }
-            break;
-
-        case sw_last_chunk_extension_almost_done:
-            if (ch == LF) {
-                state = sw_trailer;
-                break;
-            }
-            goto invalid;
-
-        case sw_trailer:
-            switch (ch) {
-            case CR:
-                state = sw_trailer_almost_done;
-                break;
-            case LF:
-                goto done;
-            default:
-                state = sw_trailer_header;
-            }
-            break;
-
-        case sw_trailer_almost_done:
-            if (ch == LF) {
-                goto done;
-            }
-            goto invalid;
-
-        case sw_trailer_header:
-            switch (ch) {
-            case CR:
-                state = sw_trailer_header_almost_done;
-                break;
-            case LF:
-                state = sw_trailer;
-            }
-            break;
-
-        case sw_trailer_header_almost_done:
-            if (ch == LF) {
-                state = sw_trailer;
-                break;
-            }
-            goto invalid;
-
-        }
-    }
-
-data:
-
-    ctx->state = state;
-    buf->pos = pos;
-
-    switch (state) {
-
-    case sw_chunk_start:
-        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);
-        break;
-    case sw_chunk_extension:
-    case sw_chunk_extension_almost_done:
-        ctx->length = 1 /* LF */ + ctx->size + 4 /* LF "0" LF LF */;
-        break;
-    case sw_chunk_data:
-        ctx->length = ctx->size + 4 /* LF "0" LF LF */;
-        break;
-    case sw_after_data:
-    case sw_after_data_almost_done:
-        ctx->length = 4 /* LF "0" LF LF */;
-        break;
-    case sw_last_chunk_extension:
-    case sw_last_chunk_extension_almost_done:
-        ctx->length = 2 /* LF LF */;
-        break;
-    case sw_trailer:
-    case sw_trailer_almost_done:
-        ctx->length = 1 /* LF */;
-        break;
-    case sw_trailer_header:
-    case sw_trailer_header_almost_done:
-        ctx->length = 2 /* LF LF */;
-        break;
-
-    }
-
-    return rc;
-
-done:
-
-    return NGX_DONE;
-
-invalid:
-
-    return NGX_ERROR;
-}
-
-
 static ngx_int_t
 ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
 {
@@ -1901,7 +1656,7 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
 
     for ( ;; ) {
 
-        rc = ngx_http_proxy_parse_chunked(r, buf);
+        rc = ngx_http_parse_chunked(r, buf, &ctx->chunked);
 
         if (rc == NGX_OK) {
 
@@ -1952,16 +1707,16 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
             ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
                            "input buf #%d %p", b->num, b->pos);
 
-            if (buf->last - buf->pos >= ctx->size) {
+            if (buf->last - buf->pos >= ctx->chunked.size) {
 
-                buf->pos += ctx->size;
+                buf->pos += ctx->chunked.size;
                 b->last = buf->pos;
-                ctx->size = 0;
+                ctx->chunked.size = 0;
 
                 continue;
             }
 
-            ctx->size -= buf->last - buf->pos;
+            ctx->chunked.size -= buf->last - buf->pos;
             buf->pos = buf->last;
             b->last = buf->last;
 
@@ -1982,7 +1737,7 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
 
             /* set p->length, minimal amount of data we want to see */
 
-            p->length = ctx->length;
+            p->length = ctx->chunked.length;
 
             break;
         }
@@ -1997,7 +1752,7 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http proxy chunked state %d, length %d",
-                   ctx->state, p->length);
+                   ctx->chunked.state, p->length);
 
     if (b) {
         b->shadow = buf;
@@ -2094,7 +1849,7 @@ ngx_http_proxy_non_buffered_chunked_filter(void *data, ssize_t bytes)
 
     for ( ;; ) {
 
-        rc = ngx_http_proxy_parse_chunked(r, buf);
+        rc = ngx_http_parse_chunked(r, buf, &ctx->chunked);
 
         if (rc == NGX_OK) {
 
@@ -2116,13 +1871,13 @@ ngx_http_proxy_non_buffered_chunked_filter(void *data, ssize_t bytes)
             b->pos = buf->pos;
             b->tag = u->output.tag;
 
-            if (buf->last - buf->pos >= ctx->size) {
-                buf->pos += ctx->size;
+            if (buf->last - buf->pos >= ctx->chunked.size) {
+                buf->pos += ctx->chunked.size;
                 b->last = buf->pos;
-                ctx->size = 0;
+                ctx->chunked.size = 0;
 
             } else {
-                ctx->size -= buf->last - buf->pos;
+                ctx->chunked.size -= buf->last - buf->pos;
                 buf->pos = buf->last;
                 b->last = buf->last;
             }
@@ -2260,32 +2015,44 @@ static ngx_int_t
 ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
 {
-    u_char  *p;
+    size_t             len;
+    u_char            *p;
+    ngx_uint_t         i, n;
+    ngx_table_elt_t  **h;
 
     v->valid = 1;
     v->no_cacheable = 0;
     v->not_found = 0;
 
-    if (r->headers_in.x_forwarded_for == NULL) {
+    n = r->headers_in.x_forwarded_for.nelts;
+    h = r->headers_in.x_forwarded_for.elts;
+
+    len = 0;
+
+    for (i = 0; i < n; i++) {
+        len += h[i]->value.len + sizeof(", ") - 1;
+    }
+
+    if (len == 0) {
         v->len = r->connection->addr_text.len;
         v->data = r->connection->addr_text.data;
         return NGX_OK;
     }
 
-    v->len = r->headers_in.x_forwarded_for->value.len
-             + sizeof(", ") - 1 + r->connection->addr_text.len;
+    len += r->connection->addr_text.len;
 
-    p = ngx_pnalloc(r->pool, v->len);
+    p = ngx_pnalloc(r->pool, len);
     if (p == NULL) {
         return NGX_ERROR;
     }
 
+    v->len = len;
     v->data = p;
 
-    p = ngx_copy(p, r->headers_in.x_forwarded_for->value.data,
-                 r->headers_in.x_forwarded_for->value.len);
-
-    *p++ = ','; *p++ = ' ';
+    for (i = 0; i < n; i++) {
+        p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
+        *p++ = ','; *p++ = ' ';
+    }
 
     ngx_memcpy(p, r->connection->addr_text.data, r->connection->addr_text.len);
 
@@ -2301,7 +2068,7 @@ ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,
 
     ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
 
-    if (ctx == NULL) {
+    if (ctx == NULL || ctx->internal_body_length < 0) {
         v->not_found = 1;
         return NGX_OK;
     }
@@ -2310,13 +2077,13 @@ 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_SIZE_T_LEN);
+    v->data = ngx_pnalloc(r->connection->pool, NGX_OFF_T_LEN);
 
     if (v->data == NULL) {
         return NGX_ERROR;
     }
 
-    v->len = ngx_sprintf(v->data, "%uz", ctx->internal_body_length) - v->data;
+    v->len = ngx_sprintf(v->data, "%O", ctx->internal_body_length) - v->data;
 
     return NGX_OK;
 }
@@ -2607,7 +2374,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
      *     conf->upstream.store_lengths = NULL;
      *     conf->upstream.store_values = NULL;
      *
-     *     conf->method = NULL;
+     *     conf->method = { 0, NULL };
      *     conf->headers_source = NULL;
      *     conf->headers_set_len = NULL;
      *     conf->headers_set = NULL;
@@ -2623,6 +2390,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
     conf->upstream.buffering = NGX_CONF_UNSET;
     conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
 
+    conf->upstream.local = NGX_CONF_UNSET_PTR;
+
     conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
@@ -2707,6 +2476,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_value(conf->upstream.ignore_client_abort,
                               prev->upstream.ignore_client_abort, 0);
 
+    ngx_conf_merge_ptr_value(conf->upstream.local,
+                              prev->upstream.local, NULL);
+
     ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
                               prev->upstream.connect_timeout, 60000);
 
@@ -2906,10 +2678,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
 
 #endif
 
-    if (conf->method.len == 0) {
-        conf->method = prev->method;
+    ngx_conf_merge_str_value(conf->method, prev->method, "");
 
-    } else {
+    if (conf->method.len
+        && conf->method.data[conf->method.len - 1] != ' ')
+    {
         conf->method.data[conf->method.len] = ' ';
         conf->method.len++;
     }
@@ -3084,8 +2857,6 @@ ngx_http_proxy_merge_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
     }
 
     if (conf->headers_set_hash.buckets
-        && ((conf->body_source.data == NULL)
-            == (prev->body_source.data == NULL))
 #if (NGX_HTTP_CACHE)
         && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL))
 #endif
@@ -3168,16 +2939,6 @@ ngx_http_proxy_merge_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
         h++;
     }
 
-    if (conf->body_source.data) {
-        s = ngx_array_push(&headers_merged);
-        if (s == NULL) {
-            return NGX_ERROR;
-        }
-
-        ngx_str_set(&s->key, "Content-Length");
-        ngx_str_set(&s->value, "$proxy_internal_body_length");
-    }
-
 
     src = headers_merged.elts;
     for (i = 0; i < headers_merged.nelts; i++) {
@@ -3918,7 +3679,7 @@ ngx_http_proxy_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     value = cf->args->elts;
 
-    if (plcf->cache_key.value.len) {
+    if (plcf->cache_key.value.data) {
         return "is duplicate";
     }
 

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

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_range_filter_module.c (+34 -6) 95%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_range_filter_module.c    2013-07-22 11:05:55 +0900 (0eaeff9)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_range_filter_module.c    2013-07-22 13:32:39 +0900 (82c202d)
@@ -146,7 +146,8 @@ static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;
 static ngx_int_t
 ngx_http_range_header_filter(ngx_http_request_t *r)
 {
-    time_t                        if_range;
+    time_t                        if_range_time;
+    ngx_str_t                    *if_range, *etag;
     ngx_http_core_loc_conf_t     *clcf;
     ngx_http_range_filter_ctx_t  *ctx;
 
@@ -174,20 +175,47 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
         goto next_filter;
     }
 
-    if (r->headers_in.if_range && r->headers_out.last_modified_time != -1) {
+    if (r->headers_in.if_range) {
 
-        if_range = ngx_http_parse_time(r->headers_in.if_range->value.data,
-                                       r->headers_in.if_range->value.len);
+        if_range = &r->headers_in.if_range->value;
+
+        if (if_range->len >= 2 && if_range->data[if_range->len - 1] == '"') {
+
+            if (r->headers_out.etag == NULL) {
+                goto next_filter;
+            }
+
+            etag = &r->headers_out.etag->value;
+
+            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                           "http ir:%V etag:%V", if_range, etag);
+
+            if (if_range->len != etag->len
+                || ngx_strncmp(if_range->data, etag->data, etag->len) != 0)
+            {
+                goto next_filter;
+            }
+
+            goto parse;
+        }
+
+        if (r->headers_out.last_modified_time == (time_t) -1) {
+            goto next_filter;
+        }
+
+        if_range_time = ngx_http_parse_time(if_range->data, if_range->len);
 
         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "http ir:%d lm:%d",
-                       if_range, r->headers_out.last_modified_time);
+                       if_range_time, r->headers_out.last_modified_time);
 
-        if (if_range != r->headers_out.last_modified_time) {
+        if (if_range_time != r->headers_out.last_modified_time) {
             goto next_filter;
         }
     }
 
+parse:
+
     ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_range_filter_ctx_t));
     if (ctx == NULL) {
         return NGX_ERROR;

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_realip_module.c (+13 -12) 94%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_realip_module.c    2013-07-22 11:05:55 +0900 (4531ea5)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_realip_module.c    2013-07-22 13:32:39 +0900 (ed9c5f9)
@@ -107,10 +107,12 @@ ngx_module_t  ngx_http_realip_module = {
 static ngx_int_t
 ngx_http_realip_handler(ngx_http_request_t *r)
 {
-    u_char                      *ip, *p;
+    u_char                      *p;
     size_t                       len;
+    ngx_str_t                   *value;
     ngx_uint_t                   i, hash;
     ngx_addr_t                   addr;
+    ngx_array_t                 *xfwd;
     ngx_list_part_t             *part;
     ngx_table_elt_t             *header;
     ngx_connection_t            *c;
@@ -137,19 +139,20 @@ ngx_http_realip_handler(ngx_http_request_t *r)
             return NGX_DECLINED;
         }
 
-        len = r->headers_in.x_real_ip->value.len;
-        ip = r->headers_in.x_real_ip->value.data;
+        value = &r->headers_in.x_real_ip->value;
+        xfwd = NULL;
 
         break;
 
     case NGX_HTTP_REALIP_XFWD:
 
-        if (r->headers_in.x_forwarded_for == NULL) {
+        xfwd = &r->headers_in.x_forwarded_for;
+
+        if (xfwd->elts == NULL) {
             return NGX_DECLINED;
         }
 
-        len = r->headers_in.x_forwarded_for->value.len;
-        ip = r->headers_in.x_forwarded_for->value.data;
+        value = NULL;
 
         break;
 
@@ -178,8 +181,8 @@ ngx_http_realip_handler(ngx_http_request_t *r)
                 && len == header[i].key.len
                 && ngx_strncmp(p, header[i].lowcase_key, len) == 0)
             {
-                len = header[i].value.len;
-                ip = header[i].value.data;
+                value = &header[i].value;
+                xfwd = NULL;
 
                 goto found;
             }
@@ -192,15 +195,13 @@ found:
 
     c = r->connection;
 
-    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip);
-
     addr.sockaddr = c->sockaddr;
     addr.socklen = c->socklen;
     /* addr.name = c->addr_text; */
 
-    if (ngx_http_get_forwarded_addr(r, &addr, ip, len, rlcf->from,
+    if (ngx_http_get_forwarded_addr(r, &addr, xfwd, value, rlcf->from,
                                     rlcf->recursive)
-        == NGX_OK)
+        != NGX_DECLINED)
     {
         return ngx_http_realip_set_addr(r, &addr);
     }

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

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

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_scgi_module.c (+31 -12) 98%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_scgi_module.c    2013-07-22 11:05:55 +0900 (bf0cb8a)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_scgi_module.c    2013-07-22 13:32:39 +0900 (49cc96d)
@@ -533,10 +533,11 @@ ngx_http_scgi_create_key(ngx_http_request_t *r)
 static ngx_int_t
 ngx_http_scgi_create_request(ngx_http_request_t *r)
 {
+    off_t                         content_length_n;
     u_char                        ch, *key, *val, *lowcase_key;
     size_t                        len, key_len, val_len, allocated;
     ngx_buf_t                    *b;
-    ngx_str_t                    *content_length;
+    ngx_str_t                     content_length;
     ngx_uint_t                    i, n, hash, skip_empty, header_params;
     ngx_chain_t                  *cl, *body;
     ngx_list_part_t              *part;
@@ -545,12 +546,20 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
     ngx_http_script_engine_t      e, le;
     ngx_http_scgi_loc_conf_t     *scf;
     ngx_http_script_len_code_pt   lcode;
-    static ngx_str_t              zero = ngx_string("0");
+    u_char                        buffer[NGX_OFF_T_LEN];
 
-    content_length = r->headers_in.content_length ?
-                         &r->headers_in.content_length->value : &zero;
+    content_length_n = 0;
+    body = r->upstream->request_bufs;
 
-    len = sizeof("CONTENT_LENGTH") + content_length->len + 1;
+    while (body) {
+        content_length_n += ngx_buf_size(body->buf);
+        body = body->next;
+    }
+
+    content_length.data = buffer;
+    content_length.len = ngx_sprintf(buffer, "%O", content_length_n) - buffer;
+
+    len = sizeof("CONTENT_LENGTH") + content_length.len + 1;
 
     header_params = 0;
     ignored = NULL;
@@ -672,11 +681,8 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
 
     cl->buf = b;
 
-    b->last = ngx_snprintf(b->last,
-                           NGX_SIZE_T_LEN + 1 + sizeof("CONTENT_LENGTH")
-                           + NGX_OFF_T_LEN + 1,
-                           "%ui:CONTENT_LENGTH%Z%V%Z",
-                           len, content_length);
+    b->last = ngx_sprintf(b->last, "%ui:CONTENT_LENGTH%Z%V%Z",
+                          len, &content_length);
 
     if (scf->params_len) {
         ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
@@ -978,7 +984,7 @@ ngx_http_scgi_process_header(ngx_http_request_t *r)
             u = r->upstream;
 
             if (u->headers_in.status_n) {
-                return NGX_OK;
+                goto done;
             }
 
             if (u->headers_in.status) {
@@ -1009,6 +1015,14 @@ ngx_http_scgi_process_header(ngx_http_request_t *r)
                 u->state->status = u->headers_in.status_n;
             }
 
+        done:
+
+            if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS
+                && r->headers_in.upgrade)
+            {
+                u->upgrade = 1;
+            }
+
             return NGX_OK;
         }
 
@@ -1061,6 +1075,8 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t *cf)
     conf->upstream.buffering = NGX_CONF_UNSET;
     conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
 
+    conf->upstream.local = NGX_CONF_UNSET_PTR;
+
     conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
@@ -1129,6 +1145,9 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_value(conf->upstream.ignore_client_abort,
                               prev->upstream.ignore_client_abort, 0);
 
+    ngx_conf_merge_ptr_value(conf->upstream.local,
+                              prev->upstream.local, NULL);
+
     ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
                               prev->upstream.connect_timeout, 60000);
 
@@ -1765,7 +1784,7 @@ ngx_http_scgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     value = cf->args->elts;
 
-    if (scf->cache_key.value.len) {
+    if (scf->cache_key.value.data) {
         return "is duplicate";
     }
 

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_secure_link_module.c (+15 -2) 94%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_secure_link_module.c    2013-07-22 11:05:55 +0900 (b69b552)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_secure_link_module.c    2013-07-22 13:32:39 +0900 (907ba6e)
@@ -111,7 +111,7 @@ ngx_http_secure_link_variable(ngx_http_request_t *r,
 
     conf = ngx_http_get_module_loc_conf(r, ngx_http_secure_link_module);
 
-    if (conf->secret.len) {
+    if (conf->secret.data) {
         return ngx_http_secure_link_old_variable(r, conf, v, data);
     }
 
@@ -318,7 +318,16 @@ ngx_http_secure_link_merge_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_http_secure_link_conf_t *prev = parent;
     ngx_http_secure_link_conf_t *conf = child;
 
-    ngx_conf_merge_str_value(conf->secret, prev->secret, "");
+    if (conf->secret.data) {
+        if (conf->variable || conf->md5) {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "\"secure_link_secret\" cannot be mixed with "
+                               "\"secure_link\" and \"secure_link_md5\"");
+            return NGX_CONF_ERROR;
+        }
+
+        return NGX_CONF_OK;
+    }
 
     if (conf->variable == NULL) {
         conf->variable = prev->variable;
@@ -328,6 +337,10 @@ ngx_http_secure_link_merge_conf(ngx_conf_t *cf, void *parent, void *child)
         conf->md5 = prev->md5;
     }
 
+    if (conf->variable == NULL && conf->md5 == NULL) {
+        conf->secret = prev->secret;
+    }
+
     return NGX_CONF_OK;
 }
 

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_split_clients_module.c (+2 -2) 98%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_split_clients_module.c    2013-07-22 11:05:55 +0900 (33a2fe7)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_split_clients_module.c    2013-07-22 13:32:39 +0900 (2f92c9e)
@@ -139,7 +139,7 @@ ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     name = value[2];
 
-    if (name.len < 2 || name.data[0] != '$') {
+    if (name.data[0] != '$') {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                            "invalid variable name \"%V\"", &name);
         return NGX_CONF_ERROR;
@@ -218,7 +218,7 @@ ngx_http_split_clients(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
         part->percent = 0;
 
     } else {
-        if (value[0].data[value[0].len - 1] != '%') {
+        if (value[0].len == 0 || value[0].data[value[0].len - 1] != '%') {
             goto invalid;
         }
 

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_ssi_filter_module.c (+1 -0) 99%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_ssi_filter_module.c    2013-07-22 11:05:55 +0900 (6c2d0a9)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_ssi_filter_module.c    2013-07-22 13:32:39 +0900 (eb286cc)
@@ -361,6 +361,7 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
         ngx_http_clear_content_length(r);
         ngx_http_clear_last_modified(r);
         ngx_http_clear_accept_ranges(r);
+        ngx_http_clear_etag(r);
     }
 
     return ngx_http_next_header_filter(r);

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

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_ssl_module.c (+155 -5) 80%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_ssl_module.c    2013-07-22 11:05:55 +0900 (ea8a0da)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_ssl_module.c    2013-07-22 13:32:39 +0900 (a6c803d)
@@ -18,6 +18,11 @@ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
 #define NGX_DEFAULT_ECDH_CURVE  "prime256v1"
 
 
+#ifdef TLSEXT_TYPE_next_proto_neg
+static int ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
+    const unsigned char **out, unsigned int *outlen, void *arg);
+#endif
+
 static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r,
@@ -33,6 +38,8 @@ static char *ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
 static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
 
+static ngx_int_t ngx_http_ssl_init(ngx_conf_t *cf);
+
 
 static ngx_conf_bitmask_t  ngx_http_ssl_protocols[] = {
     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
@@ -125,6 +132,13 @@ static ngx_command_t  ngx_http_ssl_commands[] = {
       offsetof(ngx_http_ssl_srv_conf_t, client_certificate),
       NULL },
 
+    { ngx_string("ssl_trusted_certificate"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_str_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_ssl_srv_conf_t, trusted_certificate),
+      NULL },
+
     { ngx_string("ssl_prefer_server_ciphers"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
       ngx_conf_set_flag_slot,
@@ -153,13 +167,41 @@ static ngx_command_t  ngx_http_ssl_commands[] = {
       offsetof(ngx_http_ssl_srv_conf_t, crl),
       NULL },
 
+    { ngx_string("ssl_stapling"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_ssl_srv_conf_t, stapling),
+      NULL },
+
+    { ngx_string("ssl_stapling_file"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_str_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_ssl_srv_conf_t, stapling_file),
+      NULL },
+
+    { ngx_string("ssl_stapling_responder"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_str_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_ssl_srv_conf_t, stapling_responder),
+      NULL },
+
+    { ngx_string("ssl_stapling_verify"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_ssl_srv_conf_t, stapling_verify),
+      NULL },
+
       ngx_null_command
 };
 
 
 static ngx_http_module_t  ngx_http_ssl_module_ctx = {
     ngx_http_ssl_add_variables,            /* preconfiguration */
-    NULL,                                  /* postconfiguration */
+    ngx_http_ssl_init,                     /* postconfiguration */
 
     NULL,                                  /* create main configuration */
     NULL,                                  /* init main configuration */
@@ -225,6 +267,45 @@ 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
+
+#define NGX_HTTP_NPN_ADVERTISE  "\x08http/1.1"
+
+static int
+ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
+    const unsigned char **out, unsigned int *outlen, void *arg)
+{
+#if (NGX_HTTP_SPDY || NGX_DEBUG)
+    ngx_connection_t  *c;
+
+    c = ngx_ssl_get_connection(ssl_conn);
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL NPN advertised");
+#endif
+
+#if (NGX_HTTP_SPDY)
+    {
+    ngx_http_connection_t  *hc;
+
+    hc = c->data;
+
+    if (hc->addr_conf->spdy) {
+        *out = (unsigned char *) NGX_SPDY_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE;
+        *outlen = sizeof(NGX_SPDY_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1;
+
+        return SSL_TLSEXT_ERR_OK;
+    }
+    }
+#endif
+
+    *out = (unsigned char *) NGX_HTTP_NPN_ADVERTISE;
+    *outlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1;
+
+    return SSL_TLSEXT_ERR_OK;
+}
+
+#endif
+
+
 static ngx_int_t
 ngx_http_ssl_static_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
@@ -326,9 +407,12 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
      *     sscf->dhparam = { 0, NULL };
      *     sscf->ecdh_curve = { 0, NULL };
      *     sscf->client_certificate = { 0, NULL };
+     *     sscf->trusted_certificate = { 0, NULL };
      *     sscf->crl = { 0, NULL };
      *     sscf->ciphers = { 0, NULL };
      *     sscf->shm_zone = NULL;
+     *     sscf->stapling_file = { 0, NULL };
+     *     sscf->stapling_responder = { 0, NULL };
      */
 
     sscf->enable = NGX_CONF_UNSET;
@@ -337,6 +421,8 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
     sscf->verify_depth = NGX_CONF_UNSET_UINT;
     sscf->builtin_session_cache = NGX_CONF_UNSET;
     sscf->session_timeout = NGX_CONF_UNSET;
+    sscf->stapling = NGX_CONF_UNSET;
+    sscf->stapling_verify = NGX_CONF_UNSET;
 
     return sscf;
 }
@@ -381,6 +467,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
 
     ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
                          "");
+    ngx_conf_merge_str_value(conf->trusted_certificate,
+                         prev->trusted_certificate, "");
     ngx_conf_merge_str_value(conf->crl, prev->crl, "");
 
     ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
@@ -388,6 +476,11 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
 
     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
 
+    ngx_conf_merge_value(conf->stapling, prev->stapling, 0);
+    ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0);
+    ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, "");
+    ngx_conf_merge_str_value(conf->stapling_responder,
+                         prev->stapling_responder, "");
 
     conf->ssl.log = cf->log;
 
@@ -441,6 +534,11 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
 
 #endif
 
+#ifdef TLSEXT_TYPE_next_proto_neg
+    SSL_CTX_set_next_protos_advertised_cb(conf->ssl.ctx,
+                                          ngx_http_ssl_npn_advertised, NULL);
+#endif
+
     cln = ngx_pool_cleanup_add(cf->pool, 0);
     if (cln == NULL) {
         return NGX_CONF_ERROR;
@@ -480,10 +578,18 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
         {
             return NGX_CONF_ERROR;
         }
+    }
 
-        if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
-            return NGX_CONF_ERROR;
-        }
+    if (ngx_ssl_trusted_certificate(cf, &conf->ssl,
+                                    &conf->trusted_certificate,
+                                    conf->verify_depth)
+        != NGX_OK)
+    {
+        return NGX_CONF_ERROR;
+    }
+
+    if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
+        return NGX_CONF_ERROR;
     }
 
     if (conf->prefer_server_ciphers) {
@@ -516,6 +622,17 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
         return NGX_CONF_ERROR;
     }
 
+    if (conf->stapling) {
+
+        if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
+                             &conf->stapling_responder, conf->stapling_verify)
+            != NGX_OK)
+        {
+            return NGX_CONF_ERROR;
+        }
+
+    }
+
     return NGX_CONF_OK;
 }
 
@@ -593,7 +710,6 @@ ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
             for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
                 if (value[i].data[j] == ':') {
-                    value[i].data[j] = '\0';
                     break;
                 }
 
@@ -651,3 +767,37 @@ invalid:
 
     return NGX_CONF_ERROR;
 }
+
+
+static ngx_int_t
+ngx_http_ssl_init(ngx_conf_t *cf)
+{
+    ngx_uint_t                   s;
+    ngx_http_ssl_srv_conf_t     *sscf;
+    ngx_http_core_loc_conf_t    *clcf;
+    ngx_http_core_srv_conf_t   **cscfp;
+    ngx_http_core_main_conf_t   *cmcf;
+
+    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
+    cscfp = cmcf->servers.elts;
+
+    for (s = 0; s < cmcf->servers.nelts; s++) {
+
+        sscf = cscfp[s]->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
+
+        if (sscf->ssl.ctx == NULL || !sscf->stapling) {
+            continue;
+        }
+
+        clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
+
+        if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, clcf->resolver,
+                                      clcf->resolver_timeout)
+            != NGX_OK)
+        {
+            return NGX_ERROR;
+        }
+    }
+
+    return NGX_OK;
+}

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_ssl_module.h (+6 -0) 82%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_ssl_module.h    2013-07-22 11:05:55 +0900 (58659ab)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_ssl_module.h    2013-07-22 13:32:39 +0900 (c4c576e)
@@ -35,12 +35,18 @@ typedef struct {
     ngx_str_t                       dhparam;
     ngx_str_t                       ecdh_curve;
     ngx_str_t                       client_certificate;
+    ngx_str_t                       trusted_certificate;
     ngx_str_t                       crl;
 
     ngx_str_t                       ciphers;
 
     ngx_shm_zone_t                 *shm_zone;
 
+    ngx_flag_t                      stapling;
+    ngx_flag_t                      stapling_verify;
+    ngx_str_t                       stapling_file;
+    ngx_str_t                       stapling_responder;
+
     u_char                         *file;
     ngx_uint_t                      line;
 } ngx_http_ssl_srv_conf_t;

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_static_module.c (+4 -0) 98%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_static_module.c    2013-07-22 11:05:55 +0900 (9d77e43)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_static_module.c    2013-07-22 13:32:39 +0900 (631eb17)
@@ -220,6 +220,10 @@ ngx_http_static_handler(ngx_http_request_t *r)
     r->headers_out.content_length_n = of.size;
     r->headers_out.last_modified_time = of.mtime;
 
+    if (ngx_http_set_etag(r) != NGX_OK) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
     if (ngx_http_set_content_type(r) != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_stub_status_module.c (+90 -3) 65%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_stub_status_module.c    2013-07-22 11:05:55 +0900 (96abe92)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_stub_status_module.c    2013-07-22 13:32:39 +0900 (83a35cd)
@@ -10,6 +10,10 @@
 #include <ngx_http.h>
 
 
+static ngx_int_t ngx_http_stub_status_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_stub_status_add_variables(ngx_conf_t *cf);
+
 static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd,
                                  void *conf);
 
@@ -28,7 +32,7 @@ static ngx_command_t  ngx_http_status_commands[] = {
 
 
 static ngx_http_module_t  ngx_http_stub_status_module_ctx = {
-    NULL,                                  /* preconfiguration */
+    ngx_http_stub_status_add_variables,    /* preconfiguration */
     NULL,                                  /* postconfiguration */
 
     NULL,                                  /* create main configuration */
@@ -58,13 +62,31 @@ ngx_module_t  ngx_http_stub_status_module = {
 };
 
 
+static ngx_http_variable_t  ngx_http_stub_status_vars[] = {
+
+    { ngx_string("connections_active"), NULL, ngx_http_stub_status_variable,
+      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
+    { ngx_string("connections_reading"), NULL, ngx_http_stub_status_variable,
+      1, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
+    { ngx_string("connections_writing"), NULL, ngx_http_stub_status_variable,
+      2, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
+    { ngx_string("connections_waiting"), NULL, ngx_http_stub_status_variable,
+      3, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
+    { ngx_null_string, NULL, NULL, 0, 0, 0 }
+};
+
+
 static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
 {
     size_t             size;
     ngx_int_t          rc;
     ngx_buf_t         *b;
     ngx_chain_t        out;
-    ngx_atomic_int_t   ap, hn, ac, rq, rd, wr;
+    ngx_atomic_int_t   ap, hn, ac, rq, rd, wr, wa;
 
     if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
         return NGX_HTTP_NOT_ALLOWED;
@@ -107,6 +129,7 @@ static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
     rq = *ngx_stat_requests;
     rd = *ngx_stat_reading;
     wr = *ngx_stat_writing;
+    wa = *ngx_stat_waiting;
 
     b->last = ngx_sprintf(b->last, "Active connections: %uA \n", ac);
 
@@ -116,7 +139,7 @@ static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
     b->last = ngx_sprintf(b->last, " %uA %uA %uA \n", ap, hn, rq);
 
     b->last = ngx_sprintf(b->last, "Reading: %uA Writing: %uA Waiting: %uA \n",
-                          rd, wr, ac - (rd + wr));
+                          rd, wr, wa);
 
     r->headers_out.status = NGX_HTTP_OK;
     r->headers_out.content_length_n = b->last - b->pos;
@@ -133,6 +156,70 @@ static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
 }
 
 
+static ngx_int_t
+ngx_http_stub_status_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    u_char            *p;
+    ngx_atomic_int_t   value;
+
+    p = ngx_pnalloc(r->pool, NGX_ATOMIC_T_LEN);
+    if (p == NULL) {
+        return NGX_ERROR;
+    }
+
+    switch (data) {
+    case 0:
+        value = *ngx_stat_active;
+        break;
+
+    case 1:
+        value = *ngx_stat_reading;
+        break;
+
+    case 2:
+        value = *ngx_stat_writing;
+        break;
+
+    case 3:
+        value = *ngx_stat_waiting;
+        break;
+
+    /* suppress warning */
+    default:
+        value = 0;
+        break;
+    }
+
+    v->len = ngx_sprintf(p, "%uA", value) - p;
+    v->valid = 1;
+    v->no_cacheable = 0;
+    v->not_found = 0;
+    v->data = p;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_stub_status_add_variables(ngx_conf_t *cf)
+{
+    ngx_http_variable_t  *var, *v;
+
+    for (v = ngx_http_stub_status_vars; v->name.len; v++) {
+        var = ngx_http_add_variable(cf, &v->name, v->flags);
+        if (var == NULL) {
+            return NGX_ERROR;
+        }
+
+        var->get_handler = v->get_handler;
+        var->data = v->data;
+    }
+
+    return NGX_OK;
+}
+
+
 static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
     ngx_http_core_loc_conf_t  *clcf;

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_sub_filter_module.c (+3 -2) 99%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_sub_filter_module.c    2013-07-22 11:05:55 +0900 (be5e90c)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_sub_filter_module.c    2013-07-22 13:32:39 +0900 (6ba57df)
@@ -168,6 +168,7 @@ 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);
     }
 
     return ngx_http_next_header_filter(r);
@@ -627,7 +628,7 @@ ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     ngx_str_t                         *value;
     ngx_http_compile_complex_value_t   ccv;
 
-    if (slcf->match.len) {
+    if (slcf->match.data) {
         return "is duplicate";
     }
 
@@ -687,7 +688,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, "");
 
-    if (conf->value.value.len == 0) {
+    if (conf->value.value.data == NULL) {
         conf->value = prev->value;
     }
 

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_upstream_ip_hash_module.c (+5 -0) 97%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_upstream_ip_hash_module.c    2013-07-22 11:05:55 +0900 (89ccc2b)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_upstream_ip_hash_module.c    2013-07-22 13:32:39 +0900 (29c74fd)
@@ -252,6 +252,11 @@ ngx_http_upstream_ip_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
 
+    if (uscf->peer.init_upstream) {
+        ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+                           "load balancing method redefined");
+    }
+
     uscf->peer.init_upstream = ngx_http_upstream_init_ip_hash;
 
     uscf->flags = NGX_HTTP_UPSTREAM_CREATE

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_upstream_keepalive_module.c (+5 -11) 98%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_upstream_keepalive_module.c    2013-07-22 11:05:55 +0900 (d10e3d0)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_upstream_keepalive_module.c    2013-07-22 13:32:39 +0900 (eed1174)
@@ -37,8 +37,6 @@ typedef struct {
     ngx_event_save_peer_session_pt     original_save_session;
 #endif
 
-    ngx_uint_t                         failed;       /* unsigned:1 */
-
 } ngx_http_upstream_keepalive_peer_data_t;
 
 
@@ -220,8 +218,6 @@ ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, void *data)
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    "get keepalive peer");
 
-    kp->failed = 0;
-
     /* ask balancer */
 
     rc = kp->original_get_peer(pc, kp->data);
@@ -282,18 +278,12 @@ ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc, void *data,
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    "free keepalive peer");
 
-    /* remember failed state - peer.free() may be called more than once */
-
-    if (state & NGX_PEER_FAILED) {
-        kp->failed = 1;
-    }
-
     /* cache valid connections */
 
     u = kp->upstream;
     c = pc->connection;
 
-    if (kp->failed
+    if (state & NGX_PEER_FAILED
         || c == NULL
         || c->read->eof
         || c->read->error
@@ -502,6 +492,10 @@ ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     kcf = ngx_http_conf_upstream_srv_conf(uscf,
                                           ngx_http_upstream_keepalive_module);
 
+    if (kcf->original_init_upstream) {
+        return "is duplicate";
+    }
+
     kcf->original_init_upstream = uscf->peer.init_upstream
                                   ? uscf->peer.init_upstream
                                   : ngx_http_upstream_init_round_robin;

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_upstream_least_conn_module.c (+12 -6) 96%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_upstream_least_conn_module.c    2013-07-22 11:05:55 +0900 (21156ae)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_upstream_least_conn_module.c    2013-07-22 13:32:39 +0900 (dbef95d)
@@ -282,7 +282,10 @@ ngx_http_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data)
     }
 
     best->current_weight -= total;
-    best->checked = now;
+
+    if (now - best->checked > best->fail_timeout) {
+        best->checked = now;
+    }
 
     pc->sockaddr = best->sockaddr;
     pc->socklen = best->socklen;
@@ -313,7 +316,9 @@ failed:
         lcp->rrp.peers = peers->next;
         pc->tries = lcp->rrp.peers->number;
 
-        n = lcp->rrp.peers->number / (8 * sizeof(uintptr_t)) + 1;
+        n = (lcp->rrp.peers->number + (8 * sizeof(uintptr_t) - 1))
+                / (8 * sizeof(uintptr_t));
+
         for (i = 0; i < n; i++) {
              lcp->rrp.tried[i] = 0;
         }
@@ -351,10 +356,6 @@ ngx_http_upstream_free_least_conn_peer(ngx_peer_connection_t *pc,
         return;
     }
 
-    if (state == 0 && pc->tries == 0) {
-        return;
-    }
-
     lcp->conns[lcp->rrp.current]--;
 
     lcp->free_rr_peer(pc, &lcp->rrp, state);
@@ -389,6 +390,11 @@ ngx_http_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
 
+    if (uscf->peer.init_upstream) {
+        ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+                           "load balancing method redefined");
+    }
+
     uscf->peer.init_upstream = ngx_http_upstream_init_least_conn;
 
     uscf->flags = NGX_HTTP_UPSTREAM_CREATE

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

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_uwsgi_module.c (+15 -2) 99%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_uwsgi_module.c    2013-07-22 11:05:55 +0900 (ef8994c)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_uwsgi_module.c    2013-07-22 13:32:39 +0900 (623ee49)
@@ -1018,7 +1018,7 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
             u = r->upstream;
 
             if (u->headers_in.status_n) {
-                return NGX_OK;
+                goto done;
             }
 
             if (u->headers_in.status) {
@@ -1049,6 +1049,14 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
                 u->state->status = u->headers_in.status_n;
             }
 
+        done:
+
+            if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS
+                && r->headers_in.upgrade)
+            {
+                u->upgrade = 1;
+            }
+
             return NGX_OK;
         }
 
@@ -1104,6 +1112,8 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
     conf->upstream.buffering = NGX_CONF_UNSET;
     conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
 
+    conf->upstream.local = NGX_CONF_UNSET_PTR;
+
     conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
@@ -1172,6 +1182,9 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_value(conf->upstream.ignore_client_abort,
                               prev->upstream.ignore_client_abort, 0);
 
+    ngx_conf_merge_ptr_value(conf->upstream.local,
+                              prev->upstream.local, NULL);
+
     ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
                               prev->upstream.connect_timeout, 60000);
 
@@ -1807,7 +1820,7 @@ ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     value = cf->args->elts;
 
-    if (uwcf->cache_key.value.len) {
+    if (uwcf->cache_key.value.data) {
         return "is duplicate";
     }
 

  Renamed: vendor/nginx-1.4.2/src/http/modules/ngx_http_xslt_filter_module.c (+3 -2) 99%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/ngx_http_xslt_filter_module.c    2013-07-22 11:05:55 +0900 (9b0354b)
+++ vendor/nginx-1.4.2/src/http/modules/ngx_http_xslt_filter_module.c    2013-07-22 13:32:39 +0900 (a6ae1ce)
@@ -307,7 +307,7 @@ ngx_http_xslt_send(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
     ctx->done = 1;
 
     if (b == NULL) {
-        return ngx_http_filter_finalize_request(r, NULL,
+        return ngx_http_filter_finalize_request(r, &ngx_http_xslt_filter_module,
                                                NGX_HTTP_INTERNAL_SERVER_ERROR);
     }
 
@@ -315,7 +315,7 @@ ngx_http_xslt_send(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
 
     if (cln == NULL) {
         ngx_free(b->pos);
-        return ngx_http_filter_finalize_request(r, NULL,
+        return ngx_http_filter_finalize_request(r, &ngx_http_xslt_filter_module,
                                                NGX_HTTP_INTERNAL_SERVER_ERROR);
     }
 
@@ -328,6 +328,7 @@ ngx_http_xslt_send(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
         }
 
         ngx_http_clear_last_modified(r);
+        ngx_http_clear_etag(r);
     }
 
     rc = ngx_http_next_header_filter(r);

  Added: vendor/nginx-1.4.2/src/http/modules/perl/Makefile.PL (+33 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.4.2/src/http/modules/perl/Makefile.PL    2013-07-22 13:32:39 +0900 (03348b5)
@@ -0,0 +1,33 @@
+
+# Copyright (C) Igor Sysoev
+# Copyright (C) Nginx, Inc.
+
+use 5.006001;
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+    NAME              => 'nginx',
+    VERSION_FROM      => 'nginx.pm',     # finds $VERSION
+    PREREQ_PM         => {},             # e.g., Module::Name => 1.1
+
+    ABSTRACT_FROM     => 'nginx.pm',     # retrieve abstract from module
+    AUTHOR            => 'Igor Sysoev',
+
+    CCFLAGS           => "$ENV{NGX_PM_CFLAGS}",
+    OPTIMIZE          => '-O',
+
+    INC               => join(" ", map {
+                             m#^/# ? "-I $_" : "-I ../../../../../$_"
+                         } (split /\s+/, $ENV{NGX_INCS})),
+
+    depend => {
+        'nginx.c'     => join(" ", map {
+                             m#^/# ? $_ : "../../../../../$_"
+                         } (split(/\s+/, $ENV{NGX_DEPS}),
+                            "src/http/modules/perl/ngx_http_perl_module.h"))
+    },
+
+    PM => {
+        'nginx.pm'    => '$(INST_LIBDIR)/nginx.pm'
+    }
+);

  Renamed: vendor/nginx-1.4.2/src/http/modules/perl/nginx.pm (+2 -2) 97%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/perl/nginx.pm    2013-07-22 11:05:55 +0900 (0f720d8)
+++ vendor/nginx-1.4.2/src/http/modules/perl/nginx.pm    2013-07-22 13:32:39 +0900 (e3f7361)
@@ -50,7 +50,7 @@ our @EXPORT = qw(
     HTTP_INSUFFICIENT_STORAGE
 );
 
-our $VERSION = '1.2.6';
+our $VERSION = '%%VERSION%%';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
@@ -123,7 +123,7 @@ This module provides a Perl interface to the nginx HTTP server API.
 
 =head1 SEE ALSO
 
-http://sysoev.ru/nginx/docs/http/ngx_http_perl_module.html
+http://nginx.org/en/docs/http/ngx_http_perl_module.html
 
 =head1 AUTHOR
 

  Renamed: vendor/nginx-1.4.2/src/http/modules/perl/nginx.xs (+63 -12) 92%
===================================================================
--- vendor/nginx-1.2.6/src/http/modules/perl/nginx.xs    2013-07-22 11:05:55 +0900 (ed97439)
+++ vendor/nginx-1.4.2/src/http/modules/perl/nginx.xs    2013-07-22 13:32:39 +0900 (77fb653)
@@ -222,10 +222,11 @@ header_in(r, key)
     dXSTARG;
     ngx_http_request_t         *r;
     SV                         *key;
-    u_char                     *p, *lowcase_key, *cookie;
+    u_char                     *p, *lowcase_key, *value, sep;
     STRLEN                      len;
     ssize_t                     size;
     ngx_uint_t                  i, n, hash;
+    ngx_array_t                *a;
     ngx_list_part_t            *part;
     ngx_table_elt_t            *h, **ph;
     ngx_http_header_t          *hh;
@@ -255,6 +256,19 @@ header_in(r, key)
     hh = ngx_hash_find(&cmcf->headers_in_hash, hash, lowcase_key, len);
 
     if (hh) {
+
+        if (hh->offset == offsetof(ngx_http_headers_in_t, cookies)) {
+            sep = ';';
+            goto multi;
+        }
+
+    #if (NGX_HTTP_X_FORWARDED_FOR)
+        if (hh->offset == offsetof(ngx_http_headers_in_t, x_forwarded_for)) {
+            sep = ',';
+            goto multi;
+        }
+    #endif
+
         if (hh->offset) {
 
             ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset);
@@ -268,15 +282,19 @@ header_in(r, key)
             XSRETURN_UNDEF;
         }
 
-        /* Cookie */
+    multi:
 
-        n = r->headers_in.cookies.nelts;
+        /* Cookie, X-Forwarded-For */
+
+        a = (ngx_array_t *) ((char *) &r->headers_in + hh->offset);
+
+        n = a->nelts;
 
         if (n == 0) {
             XSRETURN_UNDEF;
         }
 
-        ph = r->headers_in.cookies.elts;
+        ph = a->elts;
 
         if (n == 1) {
             ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len);
@@ -290,12 +308,12 @@ header_in(r, key)
             size += ph[i]->value.len + sizeof("; ") - 1;
         }
 
-        cookie = ngx_pnalloc(r->pool, size);
-        if (cookie == NULL) {
+        value = ngx_pnalloc(r->pool, size);
+        if (value == NULL) {
             XSRETURN_UNDEF;
         }
 
-        p = cookie;
+        p = value;
 
         for (i = 0; /* void */ ; i++) {
             p = ngx_copy(p, ph[i]->value.data, ph[i]->value.len);
@@ -304,10 +322,10 @@ header_in(r, key)
                 break;
             }
 
-            *p++ = ';'; *p++ = ' ';
+            *p++ = sep; *p++ = ' ';
         }
 
-        ngx_http_perl_set_targ(cookie, size);
+        ngx_http_perl_set_targ(value, size);
 
         goto done;
     }
@@ -357,7 +375,7 @@ has_request_body(r, next)
 
     ngx_http_perl_set_request(r);
 
-    if (r->headers_in.content_length_n <= 0) {
+    if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) {
         XSRETURN_UNDEF;
     }
 
@@ -386,7 +404,10 @@ request_body(r)
 
     dXSTARG;
     ngx_http_request_t  *r;
+    u_char              *p, *data;
     size_t               len;
+    ngx_buf_t           *buf;
+    ngx_chain_t         *cl;
 
     ngx_http_perl_set_request(r);
 
@@ -397,13 +418,43 @@ request_body(r)
         XSRETURN_UNDEF;
     }
 
-    len = r->request_body->bufs->buf->last - r->request_body->bufs->buf->pos;
+    cl = r->request_body->bufs;
+    buf = cl->buf;
+
+    if (cl->next == NULL) {
+        len = buf->last - buf->pos;
+        data = buf->pos;
+        goto done;
+    }
+
+    len = buf->last - buf->pos;
+    cl = cl->next;
+
+    for ( /* void */ ; cl; cl = cl->next) {
+        buf = cl->buf;
+        len += buf->last - buf->pos;
+    }
+
+    p = ngx_pnalloc(r->pool, len);
+    if (p == NULL) {
+        XSRETURN_UNDEF;
+    }
+
+    data = p;
+    cl = r->request_body->bufs;
+
+    for ( /* void */ ; cl; cl = cl->next) {
+        buf = cl->buf;
+        p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
+    }
+
+    done:
 
     if (len == 0) {
         XSRETURN_UNDEF;
     }
 
-    ngx_http_perl_set_targ(r->request_body->bufs->buf->pos, len);
+    ngx_http_perl_set_targ(data, len);
 
     ST(0) = TARG;
 

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

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

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

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http.c (+24 -1) 98%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http.c    2013-07-22 11:05:55 +0900 (f1f8a48)
+++ vendor/nginx-1.4.2/src/http/ngx_http.c    2013-07-22 13:32:39 +0900 (987ae54)
@@ -1225,6 +1225,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
 #if (NGX_HTTP_SSL)
     ngx_uint_t             ssl;
 #endif
+#if (NGX_HTTP_SPDY)
+    ngx_uint_t             spdy;
+#endif
 
     /*
      * we cannot compare whole sockaddr struct's as kernel
@@ -1277,6 +1280,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
 #if (NGX_HTTP_SSL)
         ssl = lsopt->ssl || addr[i].opt.ssl;
 #endif
+#if (NGX_HTTP_SPDY)
+        spdy = lsopt->spdy || addr[i].opt.spdy;
+#endif
 
         if (lsopt->set) {
 
@@ -1307,6 +1313,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
 #if (NGX_HTTP_SSL)
         addr[i].opt.ssl = ssl;
 #endif
+#if (NGX_HTTP_SPDY)
+        addr[i].opt.spdy = spdy;
+#endif
 
         return NGX_OK;
     }
@@ -1337,6 +1346,14 @@ 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 (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);
+    }
+#endif
+
     addr = ngx_array_push(&port->addrs);
     if (addr == NULL) {
         return NGX_ERROR;
@@ -1462,7 +1479,7 @@ ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
 
     ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t));
 
-    ha.temp_pool = ngx_create_pool(16384, cf->log);
+    ha.temp_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
     if (ha.temp_pool == NULL) {
         return NGX_ERROR;
     }
@@ -1820,6 +1837,9 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
 #if (NGX_HTTP_SSL)
         addrs[i].conf.ssl = addr[i].opt.ssl;
 #endif
+#if (NGX_HTTP_SPDY)
+        addrs[i].conf.spdy = addr[i].opt.spdy;
+#endif
 
         if (addr[i].hash.buckets == NULL
             && (addr[i].wc_head == NULL
@@ -1881,6 +1901,9 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
 #if (NGX_HTTP_SSL)
         addrs6[i].conf.ssl = addr[i].opt.ssl;
 #endif
+#if (NGX_HTTP_SPDY)
+        addrs6[i].conf.spdy = addr[i].opt.spdy;
+#endif
 
         if (addr[i].hash.buckets == NULL
             && (addr[i].wc_head == NULL

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http.h (+27 -4) 84%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http.h    2013-07-22 11:05:55 +0900 (f152006)
+++ vendor/nginx-1.4.2/src/http/ngx_http.h    2013-07-22 13:32:39 +0900 (d4dc1bd)
@@ -18,6 +18,11 @@ typedef struct ngx_http_upstream_s    ngx_http_upstream_t;
 typedef struct ngx_http_cache_s       ngx_http_cache_t;
 typedef struct ngx_http_file_cache_s  ngx_http_file_cache_t;
 typedef struct ngx_http_log_ctx_s     ngx_http_log_ctx_t;
+typedef struct ngx_http_chunked_s     ngx_http_chunked_t;
+
+#if (NGX_HTTP_SPDY)
+typedef struct ngx_http_spdy_stream_s  ngx_http_spdy_stream_t;
+#endif
 
 typedef ngx_int_t (*ngx_http_header_handler_pt)(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
@@ -26,14 +31,17 @@ typedef u_char *(*ngx_http_log_handler_pt)(ngx_http_request_t *r,
 
 
 #include <ngx_http_variables.h>
+#include <ngx_http_config.h>
 #include <ngx_http_request.h>
+#include <ngx_http_script.h>
 #include <ngx_http_upstream.h>
 #include <ngx_http_upstream_round_robin.h>
-#include <ngx_http_config.h>
 #include <ngx_http_busy_lock.h>
-#include <ngx_http_script.h>
 #include <ngx_http_core_module.h>
 
+#if (NGX_HTTP_SPDY)
+#include <ngx_http_spdy.h>
+#endif
 #if (NGX_HTTP_CACHE)
 #include <ngx_http_cache.h>
 #endif
@@ -52,6 +60,13 @@ struct ngx_http_log_ctx_s {
 };
 
 
+struct ngx_http_chunked_s {
+    ngx_uint_t           state;
+    off_t                size;
+    off_t                length;
+};
+
+
 typedef struct {
     ngx_uint_t           http_version;
     ngx_uint_t           code;
@@ -72,12 +87,14 @@ ngx_int_t ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
 
 
 void ngx_http_init_connection(ngx_connection_t *c);
+void ngx_http_close_connection(ngx_connection_t *c);
 
-#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
 int ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg);
 #endif
 
 ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b);
+ngx_int_t ngx_http_parse_uri(ngx_http_request_t *r);
 ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r,
     ngx_uint_t merge_slashes);
 ngx_int_t ngx_http_parse_status_line(ngx_http_request_t *r, ngx_buf_t *b,
@@ -92,15 +109,21 @@ ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len,
     ngx_str_t *value);
 void ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri,
     ngx_str_t *args);
+ngx_int_t ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
+    ngx_http_chunked_t *ctx);
 
 
-ngx_int_t ngx_http_find_server_conf(ngx_http_request_t *r);
+ngx_http_request_t *ngx_http_create_request(ngx_connection_t *c);
+ngx_int_t ngx_http_process_request_uri(ngx_http_request_t *r);
+ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
+void ngx_http_process_request(ngx_http_request_t *r);
 void ngx_http_update_location_config(ngx_http_request_t *r);
 void ngx_http_handler(ngx_http_request_t *r);
 void ngx_http_run_posted_requests(ngx_connection_t *c);
 ngx_int_t ngx_http_post_request(ngx_http_request_t *r,
     ngx_http_posted_request_t *pr);
 void ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
+void ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc);
 
 void ngx_http_empty_handler(ngx_event_t *wev);
 void ngx_http_request_empty_handler(ngx_http_request_t *r);

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

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

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

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

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

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_core_module.c (+138 -11) 97%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_core_module.c    2013-07-22 11:05:55 +0900 (e02a251)
+++ vendor/nginx-1.4.2/src/http/ngx_http_core_module.c    2013-07-22 13:32:39 +0900 (25d3dc9)
@@ -76,6 +76,9 @@ static ngx_uint_t ngx_http_gzip_quantity(u_char *p, u_char *last);
 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
 #endif
+static ngx_int_t ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r,
+    ngx_addr_t *addr, u_char *xff, size_t xfflen, ngx_array_t *proxies,
+    int recursive);
 #if (NGX_HAVE_OPENAT)
 static char *ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
@@ -650,6 +653,13 @@ static ngx_command_t  ngx_http_core_commands[] = {
       offsetof(ngx_http_core_loc_conf_t, chunked_transfer_encoding),
       NULL },
 
+    { ngx_string("etag"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_core_loc_conf_t, etag),
+      NULL },
+
     { ngx_string("error_page"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
                         |NGX_CONF_2MORE,
@@ -841,7 +851,8 @@ ngx_http_handler(ngx_http_request_t *r)
             break;
         }
 
-        r->lingering_close = (r->headers_in.content_length_n > 0);
+        r->lingering_close = (r->headers_in.content_length_n > 0
+                              || r->headers_in.chunked);
         r->phase_handler = 0;
 
     } else {
@@ -993,6 +1004,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
                       "client intended to send too large body: %O bytes",
                       r->headers_in.content_length_n);
 
+        r->expect_tested = 1;
         (void) ngx_http_discard_request_body(r);
         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
         return NGX_OK;
@@ -1449,11 +1461,7 @@ ngx_http_update_location_config(ngx_http_request_t *r)
     }
 
     if (r == r->main) {
-        r->connection->log->file = clcf->error_log->file;
-
-        if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
-            r->connection->log->log_level = clcf->error_log->log_level;
-        }
+        ngx_http_set_connection_log(r->connection, clcf->error_log);
     }
 
     if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) {
@@ -1809,6 +1817,42 @@ ngx_http_set_exten(ngx_http_request_t *r)
 
 
 ngx_int_t
+ngx_http_set_etag(ngx_http_request_t *r)
+{
+    ngx_table_elt_t           *etag;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    if (!clcf->etag) {
+        return NGX_OK;
+    }
+
+    etag = ngx_list_push(&r->headers_out.headers);
+    if (etag == NULL) {
+        return NGX_ERROR;
+    }
+
+    etag->hash = 1;
+    ngx_str_set(&etag->key, "ETag");
+
+    etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3);
+    if (etag->value.data == NULL) {
+        return NGX_ERROR;
+    }
+
+    etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"",
+                                  r->headers_out.last_modified_time,
+                                  r->headers_out.content_length_n)
+                      - etag->value.data;
+
+    r->headers_out.etag = etag;
+
+    return NGX_OK;
+}
+
+
+ngx_int_t
 ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
     ngx_str_t *ct, ngx_http_complex_value_t *cv)
 {
@@ -2086,6 +2130,13 @@ ngx_http_gzip_ok(ngx_http_request_t *r)
         return NGX_DECLINED;
     }
 
+#if (NGX_HTTP_SPDY)
+    if (r->spdy_stream) {
+        r->gzip_ok = 1;
+        return NGX_OK;
+    }
+#endif
+
     ae = r->headers_in.accept_encoding;
     if (ae == NULL) {
         return NGX_DECLINED;
@@ -2420,6 +2471,10 @@ ngx_http_subrequest(ngx_http_request_t *r,
 
     sr->request_body = r->request_body;
 
+#if (NGX_HTTP_SPDY)
+    sr->spdy_stream = r->spdy_stream;
+#endif
+
     sr->method = NGX_HTTP_GET;
     sr->http_version = r->http_version;
 
@@ -2702,10 +2757,58 @@ ngx_http_set_disable_symlinks(ngx_http_request_t *r,
 
 ngx_int_t
 ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
+    ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies,
+    int recursive)
+{
+    ngx_int_t          rc;
+    ngx_uint_t         i, found;
+    ngx_table_elt_t  **h;
+
+    if (headers == NULL) {
+        return ngx_http_get_forwarded_addr_internal(r, addr, value->data,
+                                                    value->len, proxies,
+                                                    recursive);
+    }
+
+    i = headers->nelts;
+    h = headers->elts;
+
+    rc = NGX_DECLINED;
+
+    found = 0;
+
+    while (i-- > 0) {
+        rc = ngx_http_get_forwarded_addr_internal(r, addr, h[i]->value.data,
+                                                  h[i]->value.len, proxies,
+                                                  recursive);
+
+        if (!recursive) {
+            break;
+        }
+
+        if (rc == NGX_DECLINED && found) {
+            rc = NGX_DONE;
+            break;
+        }
+
+        if (rc != NGX_OK) {
+            break;
+        }
+
+        found = 1;
+    }
+
+    return rc;
+}
+
+
+static ngx_int_t
+ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
     u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive)
 {
     u_char           *p;
     in_addr_t         inaddr;
+    ngx_int_t         rc;
     ngx_addr_t        paddr;
     ngx_cidr_t       *cidr;
     ngx_uint_t        family, i;
@@ -2797,8 +2900,15 @@ ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
         *addr = paddr;
 
         if (recursive && p > xff) {
-            (void) ngx_http_get_forwarded_addr(r, addr, xff, p - 1 - xff,
-                                               proxies, 1);
+            rc = ngx_http_get_forwarded_addr_internal(r, addr, xff, p - 1 - xff,
+                                                      proxies, 1);
+
+            if (rc == NGX_DECLINED) {
+                return NGX_DONE;
+            }
+
+            /* rc == NGX_OK || rc == NGX_DONE  */
+            return rc;
         }
 
         return NGX_OK;
@@ -3146,7 +3256,7 @@ ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
 #if (NGX_HAVE_CASELESS_FILESYSTEM)
     rc.options = NGX_REGEX_CASELESS;
 #else
-    rc.options = caseless;
+    rc.options = caseless ? NGX_REGEX_CASELESS : 0;
 #endif
 
     clcf->regex = ngx_http_regex_compile(cf, &rc);
@@ -3511,6 +3621,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
     clcf->recursive_error_pages = NGX_CONF_UNSET;
     clcf->server_tokens = NGX_CONF_UNSET;
     clcf->chunked_transfer_encoding = NGX_CONF_UNSET;
+    clcf->etag = NGX_CONF_UNSET;
     clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
     clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
 
@@ -3772,6 +3883,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
     ngx_conf_merge_value(conf->chunked_transfer_encoding,
                               prev->chunked_transfer_encoding, 1);
+    ngx_conf_merge_value(conf->etag, prev->etag, 1);
 
     ngx_conf_merge_ptr_value(conf->open_file_cache,
                               prev->open_file_cache, NULL);
@@ -3868,6 +3980,9 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     lsopt.setfib = -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,
                          NGX_SOCKADDR_STRLEN, 1);
@@ -3987,7 +4102,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                     lsopt.ipv6only = 1;
 
                 } else if (ngx_strcmp(&value[n].data[10], "ff") == 0) {
-                    lsopt.ipv6only = 2;
+                    lsopt.ipv6only = 0;
 
                 } else {
                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -4026,6 +4141,18 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 #endif
         }
 
+        if (ngx_strcmp(value[n].data, "spdy") == 0) {
+#if (NGX_HTTP_SPDY)
+            lsopt.spdy = 1;
+            continue;
+#else
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "the \"spdy\" parameter requires "
+                               "ngx_http_spdy_module");
+            return NGX_CONF_ERROR;
+#endif
+        }
+
         if (ngx_strncmp(value[n].data, "so_keepalive=", 13) == 0) {
 
             if (ngx_strcmp(&value[n].data[13], "on") == 0) {
@@ -4544,7 +4671,7 @@ ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     ngx_str_null(&args);
 
-    if (cv.lengths == NULL && uri.data[0] == '/') {
+    if (cv.lengths == NULL && uri.len && uri.data[0] == '/') {
         p = (u_char *) ngx_strchr(uri.data, '?');
 
         if (p) {

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_core_module.h (+37 -13) 94%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_core_module.h    2013-07-22 11:05:55 +0900 (e95d1e0)
+++ vendor/nginx-1.4.2/src/http/ngx_http_core_module.h    2013-07-22 13:32:39 +0900 (5b38000)
@@ -75,8 +75,11 @@ typedef struct {
 #if (NGX_HTTP_SSL)
     unsigned                   ssl:1;
 #endif
+#if (NGX_HTTP_SPDY)
+    unsigned                   spdy:1;
+#endif
 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
-    unsigned                   ipv6only:2;
+    unsigned                   ipv6only:1;
 #endif
     unsigned                   so_keepalive:2;
 
@@ -209,15 +212,35 @@ typedef struct {
 
 
 typedef struct {
+#if (NGX_PCRE)
+    ngx_http_regex_t          *regex;
+#endif
+    ngx_http_core_srv_conf_t  *server;   /* virtual name server conf */
+    ngx_str_t                  name;
+} ngx_http_server_name_t;
+
+
+typedef struct {
+     ngx_hash_combined_t       names;
+
+     ngx_uint_t                nregex;
+     ngx_http_server_name_t   *regex;
+} ngx_http_virtual_names_t;
+
+
+struct ngx_http_addr_conf_s {
     /* the default server configuration for this address:port */
     ngx_http_core_srv_conf_t  *default_server;
 
     ngx_http_virtual_names_t  *virtual_names;
 
 #if (NGX_HTTP_SSL)
-    ngx_uint_t                 ssl;   /* unsigned  ssl:1; */
+    unsigned                   ssl:1;
 #endif
-} ngx_http_addr_conf_t;
+#if (NGX_HTTP_SPDY)
+    unsigned                   spdy:1;
+#endif
+};
 
 
 typedef struct {
@@ -268,15 +291,6 @@ typedef struct {
 } ngx_http_conf_addr_t;
 
 
-struct ngx_http_server_name_s {
-#if (NGX_PCRE)
-    ngx_http_regex_t          *regex;
-#endif
-    ngx_http_core_srv_conf_t  *server;   /* virtual name server conf */
-    ngx_str_t                  name;
-};
-
-
 typedef struct {
     ngx_int_t                  status;
     ngx_int_t                  overwrite;
@@ -392,6 +406,7 @@ struct ngx_http_core_loc_conf_s {
     ngx_flag_t    recursive_error_pages;   /* recursive_error_pages */
     ngx_flag_t    server_tokens;           /* server_tokens */
     ngx_flag_t    chunked_transfer_encoding; /* chunked_transfer_encoding */
+    ngx_flag_t    etag;                    /* etag */
 
 #if (NGX_HTTP_GZIP)
     ngx_flag_t    gzip_vary;               /* gzip_vary */
@@ -480,6 +495,7 @@ ngx_int_t ngx_http_core_content_phase(ngx_http_request_t *r,
 void *ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash);
 ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r);
 void ngx_http_set_exten(ngx_http_request_t *r);
+ngx_int_t ngx_http_set_etag(ngx_http_request_t *r);
 ngx_int_t ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
     ngx_str_t *ct, ngx_http_complex_value_t *cv);
 u_char *ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *name,
@@ -514,7 +530,8 @@ ngx_int_t ngx_http_set_disable_symlinks(ngx_http_request_t *r,
     ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of);
 
 ngx_int_t ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
-    u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive);
+    ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies,
+    int recursive);
 
 
 extern ngx_module_t  ngx_http_core_module;
@@ -555,5 +572,12 @@ extern ngx_str_t  ngx_http_core_get_method;
         r->headers_out.location = NULL;                                       \
     }
 
+#define ngx_http_clear_etag(r)                                                \
+                                                                              \
+    if (r->headers_out.etag) {                                                \
+        r->headers_out.etag->hash = 0;                                        \
+        r->headers_out.etag = NULL;                                           \
+    }
+
 
 #endif /* _NGX_HTTP_CORE_H_INCLUDED_ */

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_file_cache.c (+0 -2) 99%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_file_cache.c    2013-07-22 11:05:55 +0900 (bd6ceba)
+++ vendor/nginx-1.4.2/src/http/ngx_http_file_cache.c    2013-07-22 13:32:39 +0900 (6d94c50)
@@ -1674,8 +1674,6 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
             p = (u_char *) ngx_strchr(name.data, ':');
 
             if (p) {
-                *p = '\0';
-
                 name.len = p - name.data;
 
                 p++;

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_header_filter_module.c (+9 -2) 98%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_header_filter_module.c    2013-07-22 11:05:55 +0900 (e3efbba)
+++ vendor/nginx-1.4.2/src/http/ngx_http_header_filter_module.c    2013-07-22 13:32:39 +0900 (707a813)
@@ -379,7 +379,10 @@ ngx_http_header_filter(ngx_http_request_t *r)
         len += sizeof("Transfer-Encoding: chunked" CRLF) - 1;
     }
 
-    if (r->keepalive) {
+    if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {
+        len += sizeof("Connection: upgrade" CRLF) - 1;
+
+    } else if (r->keepalive) {
         len += sizeof("Connection: keep-alive" CRLF) - 1;
 
         /*
@@ -548,7 +551,11 @@ ngx_http_header_filter(ngx_http_request_t *r)
                              sizeof("Transfer-Encoding: chunked" CRLF) - 1);
     }
 
-    if (r->keepalive) {
+    if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {
+        b->last = ngx_cpymem(b->last, "Connection: upgrade" CRLF,
+                             sizeof("Connection: upgrade" CRLF) - 1);
+
+    } else if (r->keepalive) {
         b->last = ngx_cpymem(b->last, "Connection: keep-alive" CRLF,
                              sizeof("Connection: keep-alive" CRLF) - 1);
 

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_parse.c (+408 -0) 82%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_parse.c    2013-07-22 11:05:55 +0900 (be750ed)
+++ vendor/nginx-1.4.2/src/http/ngx_http_parse.c    2013-07-22 13:32:39 +0900 (3c168aa)
@@ -1075,6 +1075,154 @@ header_done:
 
 
 ngx_int_t
+ngx_http_parse_uri(ngx_http_request_t *r)
+{
+    u_char  *p, ch;
+    enum {
+        sw_start = 0,
+        sw_after_slash_in_uri,
+        sw_check_uri,
+        sw_uri
+    } state;
+
+    state = sw_start;
+
+    for (p = r->uri_start; p != r->uri_end; p++) {
+
+        ch = *p;
+
+        switch (state) {
+
+        case sw_start:
+
+            if (ch != '/') {
+                return NGX_ERROR;
+            }
+
+            state = sw_after_slash_in_uri;
+            break;
+
+        /* check "/.", "//", "%", and "\" (Win32) in URI */
+        case sw_after_slash_in_uri:
+
+            if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+                state = sw_check_uri;
+                break;
+            }
+
+            switch (ch) {
+            case ' ':
+                r->space_in_uri = 1;
+                state = sw_check_uri;
+                break;
+            case '.':
+                r->complex_uri = 1;
+                state = sw_uri;
+                break;
+            case '%':
+                r->quoted_uri = 1;
+                state = sw_uri;
+                break;
+            case '/':
+                r->complex_uri = 1;
+                state = sw_uri;
+                break;
+#if (NGX_WIN32)
+            case '\\':
+                r->complex_uri = 1;
+                state = sw_uri;
+                break;
+#endif
+            case '?':
+                r->args_start = p + 1;
+                state = sw_uri;
+                break;
+            case '#':
+                r->complex_uri = 1;
+                state = sw_uri;
+                break;
+            case '+':
+                r->plus_in_uri = 1;
+                break;
+            default:
+                state = sw_check_uri;
+                break;
+            }
+            break;
+
+        /* check "/", "%" and "\" (Win32) in URI */
+        case sw_check_uri:
+
+            if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+                break;
+            }
+
+            switch (ch) {
+            case '/':
+#if (NGX_WIN32)
+                if (r->uri_ext == p) {
+                    r->complex_uri = 1;
+                    state = sw_uri;
+                    break;
+                }
+#endif
+                r->uri_ext = NULL;
+                state = sw_after_slash_in_uri;
+                break;
+            case '.':
+                r->uri_ext = p + 1;
+                break;
+            case ' ':
+                r->space_in_uri = 1;
+                break;
+#if (NGX_WIN32)
+            case '\\':
+                r->complex_uri = 1;
+                state = sw_after_slash_in_uri;
+                break;
+#endif
+            case '%':
+                r->quoted_uri = 1;
+                state = sw_uri;
+                break;
+            case '?':
+                r->args_start = p + 1;
+                state = sw_uri;
+                break;
+            case '#':
+                r->complex_uri = 1;
+                state = sw_uri;
+                break;
+            case '+':
+                r->plus_in_uri = 1;
+                break;
+            }
+            break;
+
+        /* URI */
+        case sw_uri:
+
+            if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+                break;
+            }
+
+            switch (ch) {
+            case ' ':
+                r->space_in_uri = 1;
+                break;
+            case '#':
+                r->complex_uri = 1;
+                break;
+            }
+            break;
+        }
+    }
+
+    return NGX_OK;
+}
+
+
+ngx_int_t
 ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
 {
     u_char  c, ch, decoded, *p, *u;
@@ -1818,3 +1966,263 @@ ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args)
         args->len = 0;
     }
 }
+
+
+ngx_int_t
+ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
+    ngx_http_chunked_t *ctx)
+{
+    u_char     *pos, ch, c;
+    ngx_int_t   rc;
+    enum {
+        sw_chunk_start = 0,
+        sw_chunk_size,
+        sw_chunk_extension,
+        sw_chunk_extension_almost_done,
+        sw_chunk_data,
+        sw_after_data,
+        sw_after_data_almost_done,
+        sw_last_chunk_extension,
+        sw_last_chunk_extension_almost_done,
+        sw_trailer,
+        sw_trailer_almost_done,
+        sw_trailer_header,
+        sw_trailer_header_almost_done
+    } state;
+
+    state = ctx->state;
+
+    if (state == sw_chunk_data && ctx->size == 0) {
+        state = sw_after_data;
+    }
+
+    rc = NGX_AGAIN;
+
+    for (pos = b->pos; pos < b->last; pos++) {
+
+        ch = *pos;
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "http chunked byte: %02Xd s:%d", ch, state);
+
+        switch (state) {
+
+        case sw_chunk_start:
+            if (ch >= '0' && ch <= '9') {
+                state = sw_chunk_size;
+                ctx->size = ch - '0';
+                break;
+            }
+
+            c = (u_char) (ch | 0x20);
+
+            if (c >= 'a' && c <= 'f') {
+                state = sw_chunk_size;
+                ctx->size = c - 'a' + 10;
+                break;
+            }
+
+            goto invalid;
+
+        case sw_chunk_size:
+            if (ch >= '0' && ch <= '9') {
+                ctx->size = ctx->size * 16 + (ch - '0');
+                break;
+            }
+
+            c = (u_char) (ch | 0x20);
+
+            if (c >= 'a' && c <= 'f') {
+                ctx->size = ctx->size * 16 + (c - 'a' + 10);
+                break;
+            }
+
+            if (ctx->size == 0) {
+
+                switch (ch) {
+                case CR:
+                    state = sw_last_chunk_extension_almost_done;
+                    break;
+                case LF:
+                    state = sw_trailer;
+                    break;
+                case ';':
+                case ' ':
+                case '\t':
+                    state = sw_last_chunk_extension;
+                    break;
+                default:
+                    goto invalid;
+                }
+
+                break;
+            }
+
+            switch (ch) {
+            case CR:
+                state = sw_chunk_extension_almost_done;
+                break;
+            case LF:
+                state = sw_chunk_data;
+                break;
+            case ';':
+            case ' ':
+            case '\t':
+                state = sw_chunk_extension;
+                break;
+            default:
+                goto invalid;
+            }
+
+            break;
+
+        case sw_chunk_extension:
+            switch (ch) {
+            case CR:
+                state = sw_chunk_extension_almost_done;
+                break;
+            case LF:
+                state = sw_chunk_data;
+            }
+            break;
+
+        case sw_chunk_extension_almost_done:
+            if (ch == LF) {
+                state = sw_chunk_data;
+                break;
+            }
+            goto invalid;
+
+        case sw_chunk_data:
+            rc = NGX_OK;
+            goto data;
+
+        case sw_after_data:
+            switch (ch) {
+            case CR:
+                state = sw_after_data_almost_done;
+                break;
+            case LF:
+                state = sw_chunk_start;
+            }
+            break;
+
+        case sw_after_data_almost_done:
+            if (ch == LF) {
+                state = sw_chunk_start;
+                break;
+            }
+            goto invalid;
+
+        case sw_last_chunk_extension:
+            switch (ch) {
+            case CR:
+                state = sw_last_chunk_extension_almost_done;
+                break;
+            case LF:
+                state = sw_trailer;
+            }
+            break;
+
+        case sw_last_chunk_extension_almost_done:
+            if (ch == LF) {
+                state = sw_trailer;
+                break;
+            }
+            goto invalid;
+
+        case sw_trailer:
+            switch (ch) {
+            case CR:
+                state = sw_trailer_almost_done;
+                break;
+            case LF:
+                goto done;
+            default:
+                state = sw_trailer_header;
+            }
+            break;
+
+        case sw_trailer_almost_done:
+            if (ch == LF) {
+                goto done;
+            }
+            goto invalid;
+
+        case sw_trailer_header:
+            switch (ch) {
+            case CR:
+                state = sw_trailer_header_almost_done;
+                break;
+            case LF:
+                state = sw_trailer;
+            }
+            break;
+
+        case sw_trailer_header_almost_done:
+            if (ch == LF) {
+                state = sw_trailer;
+                break;
+            }
+            goto invalid;
+
+        }
+    }
+
+data:
+
+    ctx->state = state;
+    b->pos = pos;
+
+    switch (state) {
+
+    case sw_chunk_start:
+        ctx->length = 3 /* "0" LF LF */;
+        break;
+    case sw_chunk_size:
+        ctx->length = 2 /* LF LF */
+                      + (ctx->size ? ctx->size + 4 /* LF "0" LF LF */ : 0);
+        break;
+    case sw_chunk_extension:
+    case sw_chunk_extension_almost_done:
+        ctx->length = 1 /* LF */ + ctx->size + 4 /* LF "0" LF LF */;
+        break;
+    case sw_chunk_data:
+        ctx->length = ctx->size + 4 /* LF "0" LF LF */;
+        break;
+    case sw_after_data:
+    case sw_after_data_almost_done:
+        ctx->length = 4 /* LF "0" LF LF */;
+        break;
+    case sw_last_chunk_extension:
+    case sw_last_chunk_extension_almost_done:
+        ctx->length = 2 /* LF LF */;
+        break;
+    case sw_trailer:
+    case sw_trailer_almost_done:
+        ctx->length = 1 /* LF */;
+        break;
+    case sw_trailer_header:
+    case sw_trailer_header_almost_done:
+        ctx->length = 2 /* LF LF */;
+        break;
+
+    }
+
+    if (ctx->size < 0 || ctx->length < 0) {
+        goto invalid;
+    }
+
+    return rc;
+
+done:
+
+    ctx->state = 0;
+    b->pos = pos + 1;
+
+    return NGX_DONE;
+
+invalid:
+
+    return NGX_ERROR;
+}

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

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

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_request.c (+840 -516) 78%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_request.c    2013-07-22 11:05:55 +0900 (ee00fd3)
+++ vendor/nginx-1.4.2/src/http/ngx_http_request.c    2013-07-22 13:32:39 +0900 (c8c5d15)
@@ -10,7 +10,7 @@
 #include <ngx_http.h>
 
 
-static void ngx_http_init_request(ngx_event_t *ev);
+static void ngx_http_wait_request_handler(ngx_event_t *ev);
 static void ngx_http_process_request_line(ngx_event_t *rev);
 static void ngx_http_process_request_headers(ngx_event_t *rev);
 static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
@@ -21,21 +21,22 @@ static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
+static ngx_int_t ngx_http_process_multi_header_lines(ngx_http_request_t *r,
+    ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_process_host(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r,
-    ngx_table_elt_t *h, ngx_uint_t offset);
 
-static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
-static void ngx_http_process_request(ngx_http_request_t *r);
-static ssize_t ngx_http_validate_host(ngx_http_request_t *r, u_char **host,
-    size_t len, ngx_uint_t alloc);
-static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r,
-    u_char *host, size_t len);
+static ngx_int_t ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool,
+    ngx_uint_t alloc);
+static ngx_int_t ngx_http_set_virtual_server(ngx_http_request_t *r,
+    ngx_str_t *host);
+static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c,
+    ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
+    ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp);
 
 static void ngx_http_request_handler(ngx_event_t *ev);
 static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc);
@@ -51,9 +52,7 @@ static void ngx_http_set_lingering_close(ngx_http_request_t *r);
 static void ngx_http_lingering_close_handler(ngx_event_t *ev);
 static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
 static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);
-static void ngx_http_free_request(ngx_http_request_t *r, ngx_int_t error);
 static void ngx_http_log_request(ngx_http_request_t *r);
-static void ngx_http_close_connection(ngx_connection_t *c);
 
 static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len);
 static u_char *ngx_http_log_error_handler(ngx_http_request_t *r,
@@ -93,6 +92,14 @@ ngx_http_header_t  ngx_http_headers_in[] = {
                  offsetof(ngx_http_headers_in_t, if_unmodified_since),
                  ngx_http_process_unique_header_line },
 
+    { ngx_string("If-Match"),
+                 offsetof(ngx_http_headers_in_t, if_match),
+                 ngx_http_process_unique_header_line },
+
+    { ngx_string("If-None-Match"),
+                 offsetof(ngx_http_headers_in_t, if_none_match),
+                 ngx_http_process_unique_header_line },
+
     { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
                  ngx_http_process_user_agent },
 
@@ -122,6 +129,10 @@ ngx_http_header_t  ngx_http_headers_in[] = {
                  offsetof(ngx_http_headers_in_t, expect),
                  ngx_http_process_unique_header_line },
 
+    { ngx_string("Upgrade"),
+                 offsetof(ngx_http_headers_in_t, upgrade),
+                 ngx_http_process_header_line },
+
 #if (NGX_HTTP_GZIP)
     { ngx_string("Accept-Encoding"),
                  offsetof(ngx_http_headers_in_t, accept_encoding),
@@ -141,7 +152,7 @@ ngx_http_header_t  ngx_http_headers_in[] = {
 #if (NGX_HTTP_X_FORWARDED_FOR)
     { ngx_string("X-Forwarded-For"),
                  offsetof(ngx_http_headers_in_t, x_forwarded_for),
-                 ngx_http_process_header_line },
+                 ngx_http_process_multi_header_lines },
 #endif
 
 #if (NGX_HTTP_REALIP)
@@ -173,7 +184,8 @@ ngx_http_header_t  ngx_http_headers_in[] = {
                  ngx_http_process_header_line },
 #endif
 
-    { ngx_string("Cookie"), 0, ngx_http_process_cookie },
+    { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookies),
+                 ngx_http_process_multi_header_lines },
 
     { ngx_null_string, 0, NULL }
 };
@@ -182,137 +194,30 @@ ngx_http_header_t  ngx_http_headers_in[] = {
 void
 ngx_http_init_connection(ngx_connection_t *c)
 {
-    ngx_event_t         *rev;
-    ngx_http_log_ctx_t  *ctx;
-
-    ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
-    if (ctx == NULL) {
-        ngx_http_close_connection(c);
-        return;
-    }
-
-    ctx->connection = c;
-    ctx->request = NULL;
-    ctx->current_request = NULL;
-
-    c->log->connection = c->number;
-    c->log->handler = ngx_http_log_error;
-    c->log->data = ctx;
-    c->log->action = "reading client request line";
-
-    c->log_error = NGX_ERROR_INFO;
-
-    rev = c->read;
-    rev->handler = ngx_http_init_request;
-    c->write->handler = ngx_http_empty_handler;
-
-#if (NGX_STAT_STUB)
-    (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
-#endif
-
-    if (rev->ready) {
-        /* the deferred accept(), rtsig, aio, iocp */
-
-        if (ngx_use_accept_mutex) {
-            ngx_post_event(rev, &ngx_posted_events);
-            return;
-        }
-
-        ngx_http_init_request(rev);
-        return;
-    }
-
-    ngx_add_timer(rev, c->listening->post_accept_timeout);
-
-    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
-#if (NGX_STAT_STUB)
-        (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
-#endif
-        ngx_http_close_connection(c);
-        return;
-    }
-}
-
-
-static void
-ngx_http_init_request(ngx_event_t *rev)
-{
-    ngx_time_t                 *tp;
-    ngx_uint_t                  i;
-    ngx_connection_t           *c;
-    ngx_http_request_t         *r;
-    struct sockaddr_in         *sin;
-    ngx_http_port_t            *port;
-    ngx_http_in_addr_t         *addr;
-    ngx_http_log_ctx_t         *ctx;
-    ngx_http_addr_conf_t       *addr_conf;
-    ngx_http_connection_t      *hc;
-    ngx_http_core_srv_conf_t   *cscf;
-    ngx_http_core_loc_conf_t   *clcf;
-    ngx_http_core_main_conf_t  *cmcf;
+    ngx_uint_t              i;
+    ngx_event_t            *rev;
+    struct sockaddr_in     *sin;
+    ngx_http_port_t        *port;
+    ngx_http_in_addr_t     *addr;
+    ngx_http_log_ctx_t     *ctx;
+    ngx_http_connection_t  *hc;
 #if (NGX_HAVE_INET6)
-    struct sockaddr_in6        *sin6;
-    ngx_http_in6_addr_t        *addr6;
-#endif
-
-#if (NGX_STAT_STUB)
-    (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
+    struct sockaddr_in6    *sin6;
+    ngx_http_in6_addr_t    *addr6;
 #endif
 
-    c = rev->data;
-
-    if (rev->timedout) {
-        ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
-
+    hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
+    if (hc == NULL) {
         ngx_http_close_connection(c);
         return;
     }
 
-    c->requests++;
-
-    hc = c->data;
-
-    if (hc == NULL) {
-        hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
-        if (hc == NULL) {
-            ngx_http_close_connection(c);
-            return;
-        }
-    }
-
-    r = hc->request;
-
-    if (r) {
-        ngx_memzero(r, sizeof(ngx_http_request_t));
-
-        r->pipeline = hc->pipeline;
-
-        if (hc->nbusy) {
-            r->header_in = hc->busy[0];
-        }
-
-    } else {
-        r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t));
-        if (r == NULL) {
-            ngx_http_close_connection(c);
-            return;
-        }
-
-        hc->request = r;
-    }
-
-    c->data = r;
-    r->http_connection = hc;
-
-    c->sent = 0;
-    r->signature = NGX_HTTP_MODULE;
+    c->data = hc;
 
     /* find the server configuration for the address:port */
 
     port = c->listening->servers;
 
-    r->connection = c;
-
     if (port->naddrs > 1) {
 
         /*
@@ -342,7 +247,7 @@ ngx_http_init_request(ngx_event_t *rev)
                 }
             }
 
-            addr_conf = &addr6[i].conf;
+            hc->addr_conf = &addr6[i].conf;
 
             break;
 #endif
@@ -360,7 +265,7 @@ ngx_http_init_request(ngx_event_t *rev)
                 }
             }
 
-            addr_conf = &addr[i].conf;
+            hc->addr_conf = &addr[i].conf;
 
             break;
         }
@@ -372,105 +277,275 @@ ngx_http_init_request(ngx_event_t *rev)
 #if (NGX_HAVE_INET6)
         case AF_INET6:
             addr6 = port->addrs;
-            addr_conf = &addr6[0].conf;
+            hc->addr_conf = &addr6[0].conf;
             break;
 #endif
 
         default: /* AF_INET */
             addr = port->addrs;
-            addr_conf = &addr[0].conf;
+            hc->addr_conf = &addr[0].conf;
             break;
         }
     }
 
-    r->virtual_names = addr_conf->virtual_names;
-
     /* the default server configuration for the address:port */
-    cscf = addr_conf->default_server;
+    hc->conf_ctx = hc->addr_conf->default_server->ctx;
 
-    r->main_conf = cscf->ctx->main_conf;
-    r->srv_conf = cscf->ctx->srv_conf;
-    r->loc_conf = cscf->ctx->loc_conf;
+    ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
+    if (ctx == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
 
-    rev->handler = ngx_http_process_request_line;
-    r->read_event_handler = ngx_http_block_reading;
+    ctx->connection = c;
+    ctx->request = NULL;
+    ctx->current_request = NULL;
 
-#if (NGX_HTTP_SSL)
+    c->log->connection = c->number;
+    c->log->handler = ngx_http_log_error;
+    c->log->data = ctx;
+    c->log->action = "waiting for request";
 
+    c->log_error = NGX_ERROR_INFO;
+
+    rev = c->read;
+    rev->handler = ngx_http_wait_request_handler;
+    c->write->handler = ngx_http_empty_handler;
+
+#if (NGX_HTTP_SPDY)
+    if (hc->addr_conf->spdy) {
+        rev->handler = ngx_http_spdy_init;
+    }
+#endif
+
+#if (NGX_HTTP_SSL)
     {
     ngx_http_ssl_srv_conf_t  *sscf;
 
-    sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
-    if (sscf->enable || addr_conf->ssl) {
+    sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
 
-        if (c->ssl == NULL) {
+    if (sscf->enable || hc->addr_conf->ssl) {
 
-            c->log->action = "SSL handshaking";
+        c->log->action = "SSL handshaking";
 
-            if (addr_conf->ssl && sscf->ssl.ctx == NULL) {
-                ngx_log_error(NGX_LOG_ERR, c->log, 0,
-                              "no \"ssl_certificate\" is defined "
-                              "in server listening on SSL port");
-                ngx_http_close_connection(c);
-                return;
-            }
+        if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) {
+            ngx_log_error(NGX_LOG_ERR, c->log, 0,
+                          "no \"ssl_certificate\" is defined "
+                          "in server listening on SSL port");
+            ngx_http_close_connection(c);
+            return;
+        }
 
-            if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)
-                != NGX_OK)
-            {
-                ngx_http_close_connection(c);
-                return;
-            }
+        hc->ssl = 1;
+
+        rev->handler = ngx_http_ssl_handshake;
+    }
+    }
+#endif
 
-            rev->handler = ngx_http_ssl_handshake;
+    if (rev->ready) {
+        /* the deferred accept(), rtsig, aio, iocp */
+
+        if (ngx_use_accept_mutex) {
+            ngx_post_event(rev, &ngx_posted_events);
+            return;
         }
 
-        r->main_filter_need_in_memory = 1;
+        rev->handler(rev);
+        return;
     }
+
+    ngx_add_timer(rev, c->listening->post_accept_timeout);
+    ngx_reusable_connection(c, 1);
+
+    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+        ngx_http_close_connection(c);
+        return;
     }
+}
 
-#endif
 
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-    c->log->file = clcf->error_log->file;
-    if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
-        c->log->log_level = clcf->error_log->log_level;
+static void
+ngx_http_wait_request_handler(ngx_event_t *rev)
+{
+    size_t                     size;
+    ssize_t                    n;
+    ngx_buf_t                 *b;
+    ngx_connection_t          *c;
+    ngx_http_connection_t     *hc;
+    ngx_http_core_srv_conf_t  *cscf;
+
+    c = rev->data;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http wait request handler");
+
+    if (rev->timedout) {
+        ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    if (c->close) {
+        ngx_http_close_connection(c);
+        return;
     }
 
-    if (c->buffer == NULL) {
-        c->buffer = ngx_create_temp_buf(c->pool,
-                                        cscf->client_header_buffer_size);
-        if (c->buffer == NULL) {
+    hc = c->data;
+    cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);
+
+    size = cscf->client_header_buffer_size;
+
+    b = c->buffer;
+
+    if (b == NULL) {
+        b = ngx_create_temp_buf(c->pool, size);
+        if (b == NULL) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        c->buffer = b;
+
+    } else if (b->start == NULL) {
+
+        b->start = ngx_palloc(c->pool, size);
+        if (b->start == NULL) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        b->pos = b->start;
+        b->last = b->start;
+        b->end = b->last + size;
+    }
+
+    n = c->recv(c, b->last, size);
+
+    if (n == NGX_AGAIN) {
+
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
+        if (c->listening->deferred_accept
+#if (NGX_HTTP_SSL)
+            && c->ssl == NULL
+#endif
+            )
+        {
+            ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
+                          "client timed out in deferred accept");
+            ngx_http_close_connection(c);
+            return;
+        }
+#endif
+
+        if (!rev->timer_set) {
+            ngx_add_timer(rev, c->listening->post_accept_timeout);
+            ngx_reusable_connection(c, 1);
+        }
+
+        if (ngx_handle_read_event(rev, 0) != NGX_OK) {
             ngx_http_close_connection(c);
             return;
         }
+
+        /*
+         * We are trying to not hold c->buffer's memory for an idle connection.
+         */
+
+        if (ngx_pfree(c->pool, b->start) == NGX_OK) {
+            b->start = NULL;
+        }
+
+        return;
+    }
+
+    if (n == NGX_ERROR) {
+        ngx_http_close_connection(c);
+        return;
     }
 
-    if (r->header_in == NULL) {
-        r->header_in = c->buffer;
-    }
+    if (n == 0) {
+        ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                      "client closed connection");
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    b->last += n;
+
+    c->log->action = "reading client request line";
+
+    ngx_reusable_connection(c, 0);
+
+    c->data = ngx_http_create_request(c);
+    if (c->data == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    rev->handler = ngx_http_process_request_line;
+    ngx_http_process_request_line(rev);
+}
+
+
+ngx_http_request_t *
+ngx_http_create_request(ngx_connection_t *c)
+{
+    ngx_pool_t                 *pool;
+    ngx_time_t                 *tp;
+    ngx_http_request_t         *r;
+    ngx_http_log_ctx_t         *ctx;
+    ngx_http_connection_t      *hc;
+    ngx_http_core_srv_conf_t   *cscf;
+    ngx_http_core_loc_conf_t   *clcf;
+    ngx_http_core_main_conf_t  *cmcf;
+
+    c->requests++;
+
+    hc = c->data;
+
+    cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);
+
+    pool = ngx_create_pool(cscf->request_pool_size, c->log);
+    if (pool == NULL) {
+        return NULL;
+    }
+
+    r = ngx_pcalloc(pool, sizeof(ngx_http_request_t));
+    if (r == NULL) {
+        ngx_destroy_pool(pool);
+        return NULL;
+    }
+
+    r->pool = pool;
+
+    r->http_connection = hc;
+    r->signature = NGX_HTTP_MODULE;
+    r->connection = c;
+
+    r->main_conf = hc->conf_ctx->main_conf;
+    r->srv_conf = hc->conf_ctx->srv_conf;
+    r->loc_conf = hc->conf_ctx->loc_conf;
 
-    r->pool = ngx_create_pool(cscf->request_pool_size, c->log);
-    if (r->pool == NULL) {
-        ngx_http_close_connection(c);
-        return;
-    }
+    r->read_event_handler = ngx_http_block_reading;
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
+    ngx_http_set_connection_log(r->connection, clcf->error_log);
+
+    r->header_in = hc->nbusy ? hc->busy[0] : c->buffer;
 
     if (ngx_list_init(&r->headers_out.headers, r->pool, 20,
                       sizeof(ngx_table_elt_t))
         != NGX_OK)
     {
         ngx_destroy_pool(r->pool);
-        ngx_http_close_connection(c);
-        return;
+        return NULL;
     }
 
     r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
     if (r->ctx == NULL) {
         ngx_destroy_pool(r->pool);
-        ngx_http_close_connection(c);
-        return;
+        return NULL;
     }
 
     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
@@ -479,12 +554,14 @@ ngx_http_init_request(ngx_event_t *rev)
                                         * sizeof(ngx_http_variable_value_t));
     if (r->variables == NULL) {
         ngx_destroy_pool(r->pool);
-        ngx_http_close_connection(c);
-        return;
+        return NULL;
     }
 
-    c->single_connection = 1;
-    c->destroyed = 0;
+#if (NGX_HTTP_SSL)
+    if (c->ssl) {
+        r->main_filter_need_in_memory = 1;
+    }
+#endif
 
     r->main = r;
     r->count = 1;
@@ -516,7 +593,7 @@ ngx_http_init_request(ngx_event_t *rev)
     (void) ngx_atomic_fetch_add(ngx_stat_requests, 1);
 #endif
 
-    rev->handler(rev);
+    return r;
 }
 
 
@@ -525,37 +602,63 @@ ngx_http_init_request(ngx_event_t *rev)
 static void
 ngx_http_ssl_handshake(ngx_event_t *rev)
 {
-    u_char               buf[1];
-    ssize_t              n;
-    ngx_int_t            rc;
-    ngx_connection_t    *c;
-    ngx_http_request_t  *r;
+    u_char                    buf[1];
+    ssize_t                   n;
+    ngx_err_t                 err;
+    ngx_int_t                 rc;
+    ngx_connection_t         *c;
+    ngx_http_connection_t    *hc;
+    ngx_http_ssl_srv_conf_t  *sscf;
 
     c = rev->data;
-    r = c->data;
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
                    "http check ssl handshake");
 
     if (rev->timedout) {
         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
-        c->timedout = 1;
-        ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    if (c->close) {
+        ngx_http_close_connection(c);
         return;
     }
 
     n = recv(c->fd, (char *) buf, 1, MSG_PEEK);
 
-    if (n == -1 && ngx_socket_errno == NGX_EAGAIN) {
+    err = ngx_socket_errno;
 
-        if (!rev->timer_set) {
-            ngx_add_timer(rev, c->listening->post_accept_timeout);
-        }
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %d", n);
 
-        if (ngx_handle_read_event(rev, 0) != NGX_OK) {
-            ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+    if (n == -1) {
+        if (err == NGX_EAGAIN) {
+
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
+            if (c->listening->deferred_accept) {
+                ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
+                              "client timed out in deferred accept");
+                ngx_http_close_connection(c);
+                return;
+            }
+#endif
+
+            if (!rev->timer_set) {
+                ngx_add_timer(rev, c->listening->post_accept_timeout);
+                ngx_reusable_connection(c, 1);
+            }
+
+            if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+                ngx_http_close_connection(c);
+            }
+
+            return;
         }
 
+        ngx_connection_error(c, err, "recv() failed");
+        ngx_http_close_connection(c);
+
         return;
     }
 
@@ -564,6 +667,17 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
             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);
+
+            if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)
+                != NGX_OK)
+            {
+                ngx_http_close_connection(c);
+                return;
+            }
+
             rc = ngx_ssl_handshake(c);
 
             if (rc == NGX_AGAIN) {
@@ -572,6 +686,8 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
                     ngx_add_timer(rev, c->listening->post_accept_timeout);
                 }
 
+                ngx_reusable_connection(c, 0);
+
                 c->ssl->handler = ngx_http_ssl_handshake_handler;
                 return;
             }
@@ -579,27 +695,26 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
             ngx_http_ssl_handshake_handler(c);
 
             return;
+        }
 
-        } else {
-            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
-                           "plain http");
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "plain http");
 
-            r->plain_http = 1;
-        }
-    }
+        c->log->action = "waiting for request";
 
-    c->log->action = "reading client request line";
+        rev->handler = ngx_http_wait_request_handler;
+        ngx_http_wait_request_handler(rev);
 
-    rev->handler = ngx_http_process_request_line;
-    ngx_http_process_request_line(rev);
+        return;
+    }
+
+    ngx_log_error(NGX_LOG_INFO, c->log, 0, "client closed connection");
+    ngx_http_close_connection(c);
 }
 
 
 static void
 ngx_http_ssl_handshake_handler(ngx_connection_t *c)
 {
-    ngx_http_request_t  *r;
-
     if (c->ssl->handshaked) {
 
         /*
@@ -612,21 +727,38 @@ ngx_http_ssl_handshake_handler(ngx_connection_t *c)
 
         c->ssl->no_wait_shutdown = 1;
 
-        c->log->action = "reading client request line";
+#if (NGX_HTTP_SPDY && 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);
+
+        SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
+
+        if (len == spdy.len && ngx_strncmp(data, spdy.data, spdy.len) == 0) {
+            ngx_http_spdy_init(c->read);
+            return;
+        }
+        }
+#endif
+
+        c->log->action = "waiting for request";
 
-        c->read->handler = ngx_http_process_request_line;
+        c->read->handler = ngx_http_wait_request_handler;
         /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler;
 
-        ngx_http_process_request_line(c->read);
+        ngx_reusable_connection(c, 1);
+
+        ngx_http_wait_request_handler(c->read);
 
         return;
     }
 
-    r = c->data;
-
-    ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
+    if (c->read->timedout) {
+        ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+    }
 
-    return;
+    ngx_http_close_connection(c);
 }
 
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
@@ -634,12 +766,13 @@ ngx_http_ssl_handshake_handler(ngx_connection_t *c)
 int
 ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
 {
-    size_t                    len;
-    u_char                   *host;
-    const char               *servername;
-    ngx_connection_t         *c;
-    ngx_http_request_t       *r;
-    ngx_http_ssl_srv_conf_t  *sscf;
+    ngx_str_t                  host;
+    const char                *servername;
+    ngx_connection_t          *c;
+    ngx_http_connection_t     *hc;
+    ngx_http_ssl_srv_conf_t   *sscf;
+    ngx_http_core_loc_conf_t  *clcf;
+    ngx_http_core_srv_conf_t  *cscf;
 
     servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
 
@@ -652,27 +785,41 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "SSL server name: \"%s\"", servername);
 
-    len = ngx_strlen(servername);
+    host.len = ngx_strlen(servername);
 
-    if (len == 0) {
+    if (host.len == 0) {
         return SSL_TLSEXT_ERR_NOACK;
     }
 
-    r = c->data;
+    host.data = (u_char *) servername;
 
-    host = (u_char *) servername;
+    if (ngx_http_validate_host(&host, c->pool, 1) != NGX_OK) {
+        return SSL_TLSEXT_ERR_NOACK;
+    }
 
-    len = ngx_http_validate_host(r, &host, len, 1);
+    hc = c->data;
 
-    if (len <= 0) {
+    if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host,
+                                     NULL, &cscf)
+        != NGX_OK)
+    {
         return SSL_TLSEXT_ERR_NOACK;
     }
 
-    if (ngx_http_find_virtual_server(r, host, len) != NGX_OK) {
+    hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
+    if (hc->ssl_servername == NULL) {
         return SSL_TLSEXT_ERR_NOACK;
     }
 
-    sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
+    *hc->ssl_servername = host;
+
+    hc->conf_ctx = cscf->ctx;
+
+    clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module);
+
+    ngx_http_set_connection_log(c, clcf->error_log);
+
+    sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
 
     if (sscf->ssl.ctx) {
         SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);
@@ -707,12 +854,11 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
 static void
 ngx_http_process_request_line(ngx_event_t *rev)
 {
-    u_char                    *host;
-    ssize_t                    n;
-    ngx_int_t                  rc, rv;
-    ngx_connection_t          *c;
-    ngx_http_request_t        *r;
-    ngx_http_core_srv_conf_t  *cscf;
+    ssize_t              n;
+    ngx_int_t            rc, rv;
+    ngx_str_t            host;
+    ngx_connection_t    *c;
+    ngx_http_request_t  *r;
 
     c = rev->data;
     r = c->data;
@@ -749,224 +895,223 @@ ngx_http_process_request_line(ngx_event_t *rev)
             r->request_line.data = r->request_start;
             r->request_length = r->header_in->pos - r->request_start;
 
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                           "http request line: \"%V\"", &r->request_line);
 
-            if (r->args_start) {
-                r->uri.len = r->args_start - 1 - r->uri_start;
-            } else {
-                r->uri.len = r->uri_end - r->uri_start;
-            }
+            r->method_name.len = r->method_end - r->request_start + 1;
+            r->method_name.data = r->request_line.data;
 
+            if (r->http_protocol.data) {
+                r->http_protocol.len = r->request_end - r->http_protocol.data;
+            }
 
-            if (r->complex_uri || r->quoted_uri) {
+            if (ngx_http_process_request_uri(r) != NGX_OK) {
+                return;
+            }
 
-                r->uri.data = ngx_pnalloc(r->pool, r->uri.len + 1);
-                if (r->uri.data == NULL) {
-                    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                    return;
-                }
+            if (r->host_start && r->host_end) {
 
-                cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+                host.len = r->host_end - r->host_start;
+                host.data = r->host_start;
 
-                rc = ngx_http_parse_complex_uri(r, cscf->merge_slashes);
+                rc = ngx_http_validate_host(&host, r->pool, 0);
 
-                if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) {
+                if (rc == NGX_DECLINED) {
                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                                  "client sent invalid request");
+                                  "client sent invalid host in request line");
                     ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
                     return;
                 }
 
-            } else {
-                r->uri.data = r->uri_start;
-            }
-
-
-            r->unparsed_uri.len = r->uri_end - r->uri_start;
-            r->unparsed_uri.data = r->uri_start;
-
-            r->valid_unparsed_uri = r->space_in_uri ? 0 : 1;
-
-            r->method_name.len = r->method_end - r->request_start + 1;
-            r->method_name.data = r->request_line.data;
+                if (rc == NGX_ERROR) {
+                    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                    return;
+                }
 
+                if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
+                    return;
+                }
 
-            if (r->http_protocol.data) {
-                r->http_protocol.len = r->request_end - r->http_protocol.data;
+                r->headers_in.server = host;
             }
 
+            if (r->http_version < NGX_HTTP_VERSION_10) {
 
-            if (r->uri_ext) {
-                if (r->args_start) {
-                    r->exten.len = r->args_start - 1 - r->uri_ext;
-                } else {
-                    r->exten.len = r->uri_end - r->uri_ext;
+                if (r->headers_in.server.len == 0
+                    && ngx_http_set_virtual_server(r, &r->headers_in.server)
+                       == NGX_ERROR)
+                {
+                    return;
                 }
 
-                r->exten.data = r->uri_ext;
+                ngx_http_process_request(r);
+                return;
             }
 
 
-            if (r->args_start && r->uri_end > r->args_start) {
-                r->args.len = r->uri_end - r->args_start;
-                r->args.data = r->args_start;
-            }
-
-#if (NGX_WIN32)
+            if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
+                              sizeof(ngx_table_elt_t))
+                != NGX_OK)
             {
-            u_char  *p, *last;
+                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return;
+            }
 
-            p = r->uri.data;
-            last = r->uri.data + r->uri.len;
+            c->log->action = "reading client request headers";
 
-            while (p < last) {
+            rev->handler = ngx_http_process_request_headers;
+            ngx_http_process_request_headers(rev);
 
-                if (*p++ == ':') {
+            return;
+        }
 
-                    /*
-                     * this check covers "::$data", "::$index_allocation" and
-                     * ":$i30:$index_allocation"
-                     */
+        if (rc != NGX_AGAIN) {
 
-                    if (p < last && *p == '$') {
-                        ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                                      "client sent unsafe win32 URI");
-                        ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
-                        return;
-                    }
-                }
-            }
+            /* there was error while a request line parsing */
 
-            p = r->uri.data + r->uri.len - 1;
+            ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                          ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
+            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+            return;
+        }
 
-            while (p > r->uri.data) {
+        /* NGX_AGAIN: a request line parsing is still incomplete */
 
-                if (*p == ' ') {
-                    p--;
-                    continue;
-                }
+        if (r->header_in->pos == r->header_in->end) {
 
-                if (*p == '.') {
-                    p--;
-                    continue;
-                }
+            rv = ngx_http_alloc_large_header_buffer(r, 1);
 
-                break;
+            if (rv == NGX_ERROR) {
+                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return;
             }
 
-            if (p != r->uri.data + r->uri.len - 1) {
-                r->uri.len = p + 1 - r->uri.data;
-                ngx_http_set_exten(r);
-            }
+            if (rv == NGX_DECLINED) {
+                r->request_line.len = r->header_in->end - r->request_start;
+                r->request_line.data = r->request_start;
 
+                ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                              "client sent too long URI");
+                ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
+                return;
             }
-#endif
-
-            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                           "http request line: \"%V\"", &r->request_line);
-
-            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                           "http uri: \"%V\"", &r->uri);
+        }
+    }
+}
 
-            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                           "http args: \"%V\"", &r->args);
 
-            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                           "http exten: \"%V\"", &r->exten);
+ngx_int_t
+ngx_http_process_request_uri(ngx_http_request_t *r)
+{
+    ngx_http_core_srv_conf_t  *cscf;
 
-            if (r->host_start && r->host_end) {
+    if (r->args_start) {
+        r->uri.len = r->args_start - 1 - r->uri_start;
+    } else {
+        r->uri.len = r->uri_end - r->uri_start;
+    }
 
-                host = r->host_start;
-                n = ngx_http_validate_host(r, &host,
-                                           r->host_end - r->host_start, 0);
+    if (r->complex_uri || r->quoted_uri) {
 
-                if (n == 0) {
-                    ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                                  "client sent invalid host in request line");
-                    ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
-                    return;
-                }
+        r->uri.data = ngx_pnalloc(r->pool, r->uri.len + 1);
+        if (r->uri.data == NULL) {
+            ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return NGX_ERROR;
+        }
 
-                if (n < 0) {
-                    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                    return;
-                }
+        cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
 
-                r->headers_in.server.len = n;
-                r->headers_in.server.data = host;
-            }
+        if (ngx_http_parse_complex_uri(r, cscf->merge_slashes) != NGX_OK) {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent invalid request");
+            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+            return NGX_ERROR;
+        }
 
-            if (r->http_version < NGX_HTTP_VERSION_10) {
+    } else {
+        r->uri.data = r->uri_start;
+    }
 
-                if (ngx_http_find_virtual_server(r, r->headers_in.server.data,
-                                                 r->headers_in.server.len)
-                    == NGX_ERROR)
-                {
-                    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                    return;
-                }
+    r->unparsed_uri.len = r->uri_end - r->uri_start;
+    r->unparsed_uri.data = r->uri_start;
 
-                ngx_http_process_request(r);
-                return;
-            }
+    r->valid_unparsed_uri = r->space_in_uri ? 0 : 1;
 
+    if (r->uri_ext) {
+        if (r->args_start) {
+            r->exten.len = r->args_start - 1 - r->uri_ext;
+        } else {
+            r->exten.len = r->uri_end - r->uri_ext;
+        }
 
-            if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
-                              sizeof(ngx_table_elt_t))
-                != NGX_OK)
-            {
-                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                return;
-            }
+        r->exten.data = r->uri_ext;
+    }
 
+    if (r->args_start && r->uri_end > r->args_start) {
+        r->args.len = r->uri_end - r->args_start;
+        r->args.data = r->args_start;
+    }
 
-            if (ngx_array_init(&r->headers_in.cookies, r->pool, 2,
-                               sizeof(ngx_table_elt_t *))
-                != NGX_OK)
-            {
-                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                return;
-            }
+#if (NGX_WIN32)
+    {
+    u_char  *p, *last;
 
-            c->log->action = "reading client request headers";
+    p = r->uri.data;
+    last = r->uri.data + r->uri.len;
 
-            rev->handler = ngx_http_process_request_headers;
-            ngx_http_process_request_headers(rev);
+    while (p < last) {
 
-            return;
+        if (*p++ == ':') {
+
+            /*
+             * this check covers "::$data", "::$index_allocation" and
+             * ":$i30:$index_allocation"
+             */
+
+            if (p < last && *p == '$') {
+                ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                              "client sent unsafe win32 URI");
+                ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+                return NGX_ERROR;
+            }
         }
+    }
 
-        if (rc != NGX_AGAIN) {
+    p = r->uri.data + r->uri.len - 1;
 
-            /* there was error while a request line parsing */
+    while (p > r->uri.data) {
 
-            ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                          ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
-            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
-            return;
+        if (*p == ' ') {
+            p--;
+            continue;
         }
 
-        /* NGX_AGAIN: a request line parsing is still incomplete */
+        if (*p == '.') {
+            p--;
+            continue;
+        }
 
-        if (r->header_in->pos == r->header_in->end) {
+        break;
+    }
 
-            rv = ngx_http_alloc_large_header_buffer(r, 1);
+    if (p != r->uri.data + r->uri.len - 1) {
+        r->uri.len = p + 1 - r->uri.data;
+        ngx_http_set_exten(r);
+    }
 
-            if (rv == NGX_ERROR) {
-                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                return;
-            }
+    }
+#endif
 
-            if (rv == NGX_DECLINED) {
-                r->request_line.len = r->header_in->end - r->request_start;
-                r->request_line.data = r->request_start;
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http uri: \"%V\"", &r->uri);
 
-                ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                              "client sent too long URI");
-                ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
-                return;
-            }
-        }
-    }
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http args: \"%V\"", &r->args);
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http exten: \"%V\"", &r->exten);
+
+    return NGX_OK;
 }
 
 
@@ -998,7 +1143,6 @@ ngx_http_process_request_headers(ngx_event_t *rev)
     }
 
     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-    cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
 
     rc = NGX_AGAIN;
 
@@ -1052,6 +1196,9 @@ ngx_http_process_request_headers(ngx_event_t *rev)
             }
         }
 
+        /* the host header could change the server configuration context */
+        cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
         rc = ngx_http_parse_header_line(r, r->header_in,
                                         cscf->underscores_in_headers);
 
@@ -1401,24 +1548,25 @@ static ngx_int_t
 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
     ngx_uint_t offset)
 {
-    u_char   *host;
-    ssize_t   len;
+    ngx_int_t  rc;
+    ngx_str_t  host;
 
     if (r->headers_in.host == NULL) {
         r->headers_in.host = h;
     }
 
-    host = h->value.data;
-    len = ngx_http_validate_host(r, &host, h->value.len, 0);
+    host = h->value;
+
+    rc = ngx_http_validate_host(&host, r->pool, 0);
 
-    if (len == 0) {
+    if (rc == NGX_DECLINED) {
         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
                       "client sent invalid host header");
         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
         return NGX_ERROR;
     }
 
-    if (len < 0) {
+    if (rc == NGX_ERROR) {
         ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
         return NGX_ERROR;
     }
@@ -1427,8 +1575,11 @@ ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
         return NGX_OK;
     }
 
-    r->headers_in.server.len = len;
-    r->headers_in.server.data = host;
+    if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
+        return NGX_ERROR;
+    }
+
+    r->headers_in.server = host;
 
     return NGX_OK;
 }
@@ -1523,31 +1674,41 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
 
 
 static ngx_int_t
-ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
+ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h,
     ngx_uint_t offset)
 {
-    ngx_table_elt_t  **cookie;
+    ngx_array_t       *headers;
+    ngx_table_elt_t  **ph;
 
-    cookie = ngx_array_push(&r->headers_in.cookies);
-    if (cookie) {
-        *cookie = h;
-        return NGX_OK;
+    headers = (ngx_array_t *) ((char *) &r->headers_in + offset);
+
+    if (headers->elts == NULL) {
+        if (ngx_array_init(headers, r->pool, 1, sizeof(ngx_table_elt_t *))
+            != NGX_OK)
+        {
+            ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return NGX_ERROR;
+        }
     }
 
-    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+    ph = ngx_array_push(headers);
+    if (ph == NULL) {
+        ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return NGX_ERROR;
+    }
 
-    return NGX_ERROR;
+    *ph = h;
+    return NGX_OK;
 }
 
 
-static ngx_int_t
+ngx_int_t
 ngx_http_process_request_header(ngx_http_request_t *r)
 {
-    if (ngx_http_find_virtual_server(r, r->headers_in.server.data,
-                                     r->headers_in.server.len)
-        == NGX_ERROR)
+    if (r->headers_in.server.len == 0
+        && ngx_http_set_virtual_server(r, &r->headers_in.server)
+           == NGX_ERROR)
     {
-        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
         return NGX_ERROR;
     }
 
@@ -1566,19 +1727,11 @@ ngx_http_process_request_header(ngx_http_request_t *r)
         if (r->headers_in.content_length_n == NGX_ERROR) {
             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
                           "client sent invalid \"Content-Length\" header");
-            ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED);
+            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
             return NGX_ERROR;
         }
     }
 
-    if (r->method & NGX_HTTP_PUT && r->headers_in.content_length_n == -1) {
-        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
-                  "client sent %V method without \"Content-Length\" header",
-                  &r->method_name);
-        ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED);
-        return NGX_ERROR;
-    }
-
     if (r->method & NGX_HTTP_TRACE) {
         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
                       "client sent TRACE method");
@@ -1586,14 +1739,25 @@ ngx_http_process_request_header(ngx_http_request_t *r)
         return NGX_ERROR;
     }
 
-    if (r->headers_in.transfer_encoding
-        && ngx_strcasestrn(r->headers_in.transfer_encoding->value.data,
-                           "chunked", 7 - 1))
-    {
-        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
-                      "client sent \"Transfer-Encoding: chunked\" header");
-        ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED);
-        return NGX_ERROR;
+    if (r->headers_in.transfer_encoding) {
+        if (r->headers_in.transfer_encoding->value.len == 7
+            && ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
+                               (u_char *) "chunked", 7) == 0)
+        {
+            r->headers_in.content_length = NULL;
+            r->headers_in.content_length_n = -1;
+            r->headers_in.chunked = 1;
+
+        } else if (r->headers_in.transfer_encoding->value.len != 8
+            || ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
+                               (u_char *) "identity", 8) != 0)
+        {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent unknown \"Transfer-Encoding\": \"%V\"",
+                          &r->headers_in.transfer_encoding->value);
+            ngx_http_finalize_request(r, NGX_HTTP_NOT_IMPLEMENTED);
+            return NGX_ERROR;
+        }
     }
 
     if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
@@ -1608,27 +1772,27 @@ ngx_http_process_request_header(ngx_http_request_t *r)
 }
 
 
-static void
+void
 ngx_http_process_request(ngx_http_request_t *r)
 {
     ngx_connection_t  *c;
 
     c = r->connection;
 
-    if (r->plain_http) {
-        ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                      "client sent plain HTTP request to HTTPS port");
-        ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
-        return;
-    }
-
 #if (NGX_HTTP_SSL)
 
-    if (c->ssl) {
+    if (r->http_connection->ssl) {
         long                      rc;
         X509                     *cert;
         ngx_http_ssl_srv_conf_t  *sscf;
 
+        if (c->ssl == NULL) {
+            ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                          "client sent plain HTTP request to HTTPS port");
+            ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
+            return;
+        }
+
         sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
 
         if (sscf->verify) {
@@ -1690,9 +1854,8 @@ ngx_http_process_request(ngx_http_request_t *r)
 }
 
 
-static ssize_t
-ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
-    ngx_uint_t alloc)
+static ngx_int_t
+ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc)
 {
     u_char  *h, ch;
     size_t   i, dot_pos, host_len;
@@ -1703,21 +1866,21 @@ ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
         sw_rest
     } state;
 
-    dot_pos = len;
-    host_len = len;
+    dot_pos = host->len;
+    host_len = host->len;
 
-    h = *host;
+    h = host->data;
 
     state = sw_usual;
 
-    for (i = 0; i < len; i++) {
+    for (i = 0; i < host->len; i++) {
         ch = h[i];
 
         switch (ch) {
 
         case '.':
             if (dot_pos == i - 1) {
-                return 0;
+                return NGX_DECLINED;
             }
             dot_pos = i;
             break;
@@ -1743,12 +1906,12 @@ ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
             break;
 
         case '\0':
-            return 0;
+            return NGX_DECLINED;
 
         default:
 
             if (ngx_path_separator(ch)) {
-                return 0;
+                return NGX_DECLINED;
             }
 
             if (ch >= 'A' && ch <= 'Z') {
@@ -1763,83 +1926,187 @@ ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
         host_len--;
     }
 
+    if (host_len == 0) {
+        return NGX_DECLINED;
+    }
+
     if (alloc) {
-        *host = ngx_pnalloc(r->pool, host_len);
-        if (*host == NULL) {
-            return -1;
+        host->data = ngx_pnalloc(pool, host_len);
+        if (host->data == NULL) {
+            return NGX_ERROR;
         }
 
-        ngx_strlow(*host, h, host_len);
+        ngx_strlow(host->data, h, host_len);
     }
 
-    return host_len;
+    host->len = host_len;
+
+    return NGX_OK;
 }
 
 
 static ngx_int_t
-ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
+ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host)
 {
+    ngx_int_t                  rc;
+    ngx_http_connection_t     *hc;
     ngx_http_core_loc_conf_t  *clcf;
     ngx_http_core_srv_conf_t  *cscf;
 
-    if (r->virtual_names == NULL) {
+    hc = r->http_connection;
+
+#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
+
+    if (hc->ssl_servername) {
+        if (hc->ssl_servername->len == host->len
+            && ngx_strncmp(hc->ssl_servername->data,
+                           host->data, host->len) == 0)
+        {
+#if (NGX_PCRE)
+            if (hc->ssl_servername_regex
+                && ngx_http_regex_exec(r, hc->ssl_servername_regex,
+                                          hc->ssl_servername) != NGX_OK)
+            {
+                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return NGX_ERROR;
+            }
+#endif
+            return NGX_OK;
+        }
+    }
+
+#endif
+
+    rc = ngx_http_find_virtual_server(r->connection,
+                                      hc->addr_conf->virtual_names,
+                                      host, r, &cscf);
+
+    if (rc == NGX_ERROR) {
+        ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return NGX_ERROR;
+    }
+
+#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
+
+    if (hc->ssl_servername) {
+        ngx_http_ssl_srv_conf_t  *sscf;
+
+        if (rc == NGX_DECLINED) {
+            cscf = hc->addr_conf->default_server;
+            rc = NGX_OK;
+        }
+
+        sscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_ssl_module);
+
+        if (sscf->verify) {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client attempted to request the server name "
+                          "different from that one was negotiated");
+            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+            return NGX_ERROR;
+        }
+    }
+
+#endif
+
+    if (rc == NGX_DECLINED) {
+        return NGX_OK;
+    }
+
+    r->srv_conf = cscf->ctx->srv_conf;
+    r->loc_conf = cscf->ctx->loc_conf;
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    ngx_http_set_connection_log(r->connection, clcf->error_log);
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_find_virtual_server(ngx_connection_t *c,
+    ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
+    ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp)
+{
+    ngx_http_core_srv_conf_t  *cscf;
+
+    if (virtual_names == NULL) {
         return NGX_DECLINED;
     }
 
-    cscf = ngx_hash_find_combined(&r->virtual_names->names,
-                                  ngx_hash_key(host, len), host, len);
+    cscf = ngx_hash_find_combined(&virtual_names->names,
+                                  ngx_hash_key(host->data, host->len),
+                                  host->data, host->len);
 
     if (cscf) {
-        goto found;
+        *cscfp = cscf;
+        return NGX_OK;
     }
 
 #if (NGX_PCRE)
 
-    if (len && r->virtual_names->nregex) {
+    if (host->len && virtual_names->nregex) {
         ngx_int_t                n;
         ngx_uint_t               i;
-        ngx_str_t                name;
         ngx_http_server_name_t  *sn;
 
-        name.len = len;
-        name.data = host;
+        sn = virtual_names->regex;
+
+#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
 
-        sn = r->virtual_names->regex;
+        if (r == NULL) {
+            ngx_http_connection_t  *hc;
 
-        for (i = 0; i < r->virtual_names->nregex; i++) {
+            for (i = 0; i < virtual_names->nregex; i++) {
 
-            n = ngx_http_regex_exec(r, sn[i].regex, &name);
+                n = ngx_regex_exec(sn[i].regex->regex, host, NULL, 0);
 
-            if (n == NGX_OK) {
-                cscf = sn[i].server;
-                goto found;
-            }
+                if (n == NGX_REGEX_NO_MATCHED) {
+                    continue;
+                }
 
-            if (n == NGX_DECLINED) {
-                continue;
+                if (n >= 0) {
+                    hc = c->data;
+                    hc->ssl_servername_regex = sn[i].regex;
+
+                    *cscfp = sn[i].server;
+                    return NGX_OK;
+                }
+
+                ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                              ngx_regex_exec_n " failed: %i "
+                              "on \"%V\" using \"%V\"",
+                              n, host, &sn[i].regex->name);
+
+                return NGX_ERROR;
             }
 
-            return NGX_ERROR;
+            return NGX_DECLINED;
         }
-    }
 
-#endif
+#endif /* NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME */
 
-    return NGX_DECLINED;
+        for (i = 0; i < virtual_names->nregex; i++) {
 
-found:
+            n = ngx_http_regex_exec(r, sn[i].regex, host);
 
-    r->srv_conf = cscf->ctx->srv_conf;
-    r->loc_conf = cscf->ctx->loc_conf;
+            if (n == NGX_DECLINED) {
+                continue;
+            }
 
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-    r->connection->log->file = clcf->error_log->file;
+            if (n == NGX_OK) {
+                *cscfp = sn[i].server;
+                return NGX_OK;
+            }
 
-    if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
-        r->connection->log->log_level = clcf->error_log->log_level;
+            return NGX_ERROR;
+        }
     }
 
-    return NGX_OK;
+#endif /* NGX_PCRE */
+
+    return NGX_DECLINED;
 }
 
 
@@ -2182,6 +2449,13 @@ ngx_http_finalize_connection(ngx_http_request_t *r)
 {
     ngx_http_core_loc_conf_t  *clcf;
 
+#if (NGX_HTTP_SPDY)
+    if (r->spdy_stream) {
+        ngx_http_close_request(r, 0);
+        return;
+    }
+#endif
+
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
     if (r->main->count != 1) {
@@ -2236,6 +2510,12 @@ ngx_http_set_write_handler(ngx_http_request_t *r)
                                 ngx_http_test_reading;
     r->write_event_handler = ngx_http_writer;
 
+#if (NGX_HTTP_SPDY)
+    if (r->spdy_stream) {
+        return NGX_OK;
+    }
+#endif
+
     wev = r->connection->write;
 
     if (wev->ready && wev->delayed) {
@@ -2383,6 +2663,19 @@ ngx_http_test_reading(ngx_http_request_t *r)
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http test reading");
 
+#if (NGX_HTTP_SPDY)
+
+    if (r->spdy_stream) {
+        if (c->error) {
+            err = 0;
+            goto closed;
+        }
+
+        return;
+    }
+
+#endif
+
 #if (NGX_HAVE_KQUEUE)
 
     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
@@ -2484,7 +2777,7 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
             /*
              * If the large header buffers were allocated while the previous
              * request processing then we do not use c->buffer for
-             * the pipelined request (see ngx_http_init_request()).
+             * the pipelined request (see ngx_http_create_request()).
              *
              * Now we would move the large header buffers to the free list.
              */
@@ -2513,14 +2806,13 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
         }
     }
 
+    /* guard against recursive call from ngx_http_finalize_connection() */
     r->keepalive = 0;
 
     ngx_http_free_request(r, 0);
 
     c->data = hc;
 
-    ngx_add_timer(rev, clcf->keepalive_timeout);
-
     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
         ngx_http_close_connection(c);
         return;
@@ -2533,32 +2825,37 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
 
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request");
 
-#if (NGX_STAT_STUB)
-        (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
-#endif
-
-        hc->pipeline = 1;
         c->log->action = "reading client pipelined request line";
 
-        rev->handler = ngx_http_init_request;
+        r = ngx_http_create_request(c);
+        if (r == NULL) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        r->pipeline = 1;
+
+        c->data = r;
+
+        c->sent = 0;
+        c->destroyed = 0;
+
+        if (rev->timer_set) {
+            ngx_del_timer(rev);
+        }
+
+        rev->handler = ngx_http_process_request_line;
         ngx_post_event(rev, &ngx_posted_events);
         return;
     }
 
-    hc->pipeline = 0;
-
     /*
-     * To keep a memory footprint as small as possible for an idle
-     * keepalive connection we try to free the ngx_http_request_t and
-     * c->buffer's memory if they were allocated outside the c->pool.
-     * The large header buffers are always allocated outside the c->pool and
-     * are freed too.
+     * To keep a memory footprint as small as possible for an idle keepalive
+     * connection we try to free c->buffer's memory if it was allocated outside
+     * the c->pool.  The large header buffers are always allocated outside the
+     * c->pool and are freed too.
      */
 
-    if (ngx_pfree(c->pool, r) == NGX_OK) {
-        hc->request = NULL;
-    }
-
     b = c->buffer;
 
     if (ngx_pfree(c->pool, b->start) == NGX_OK) {
@@ -2664,6 +2961,8 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
     c->idle = 1;
     ngx_reusable_connection(c, 1);
 
+    ngx_add_timer(rev, clcf->keepalive_timeout);
+
     if (rev->ready) {
         ngx_post_event(rev, &ngx_posted_events);
     }
@@ -2743,6 +3042,7 @@ ngx_http_keepalive_handler(ngx_event_t *rev)
     if (n == NGX_AGAIN) {
         if (ngx_handle_read_event(rev, 0) != NGX_OK) {
             ngx_http_close_connection(c);
+            return;
         }
 
         /*
@@ -2778,17 +3078,25 @@ ngx_http_keepalive_handler(ngx_event_t *rev)
 
     b->last += n;
 
-#if (NGX_STAT_STUB)
-    (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
-#endif
-
     c->log->handler = ngx_http_log_error;
     c->log->action = "reading client request line";
 
     c->idle = 0;
     ngx_reusable_connection(c, 0);
 
-    ngx_http_init_request(rev);
+    c->data = ngx_http_create_request(c);
+    if (c->data == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    c->sent = 0;
+    c->destroyed = 0;
+
+    ngx_del_timer(rev);
+
+    rev->handler = ngx_http_process_request_line;
+    ngx_http_process_request_line(rev);
 }
 
 
@@ -3003,15 +3311,23 @@ ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
         return;
     }
 
+#if (NGX_HTTP_SPDY)
+    if (r->spdy_stream) {
+        ngx_http_spdy_close_stream(r->spdy_stream, rc);
+        return;
+    }
+#endif
+
     ngx_http_free_request(r, rc);
     ngx_http_close_connection(c);
 }
 
 
-static void
+void
 ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
 {
     ngx_log_t                 *log;
+    ngx_pool_t                *pool;
     struct linger              linger;
     ngx_http_cleanup_t        *cln;
     ngx_http_log_ctx_t        *ctx;
@@ -3078,7 +3394,15 @@ ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
 
     r->connection->destroyed = 1;
 
-    ngx_destroy_pool(r->pool);
+    /*
+     * Setting r->pool to NULL will increase probability to catch double close
+     * of request since the request object is allocated from its own pool.
+     */
+
+    pool = r->pool;
+    r->pool = NULL;
+
+    ngx_destroy_pool(pool);
 }
 
 
@@ -3100,7 +3424,7 @@ ngx_http_log_request(ngx_http_request_t *r)
 }
 
 
-static void
+void
 ngx_http_close_connection(ngx_connection_t *c)
 {
     ngx_pool_t  *pool;

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_request.h (+37 -25) 92%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_request.h    2013-07-22 11:05:55 +0900 (c2651a8)
+++ vendor/nginx-1.4.2/src/http/ngx_http_request.h    2013-07-22 13:32:39 +0900 (bd842df)
@@ -64,6 +64,10 @@
 #define NGX_HTTP_LOG_UNSAFE                8
 
 
+#define NGX_HTTP_CONTINUE                  100
+#define NGX_HTTP_SWITCHING_PROTOCOLS       101
+#define NGX_HTTP_PROCESSING                102
+
 #define NGX_HTTP_OK                        200
 #define NGX_HTTP_CREATED                   201
 #define NGX_HTTP_ACCEPTED                  202
@@ -137,13 +141,6 @@
 #define NGX_HTTP_COPY_BUFFERED             0x04
 
 
-#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO)
-#ifndef NGX_HTTP_X_FORWARDED_FOR
-#define NGX_HTTP_X_FORWARDED_FOR           1
-#endif
-#endif
-
-
 typedef enum {
     NGX_HTTP_INITING_REQUEST_STATE = 0,
     NGX_HTTP_READING_REQUEST_STATE,
@@ -179,6 +176,8 @@ typedef struct {
     ngx_table_elt_t                  *connection;
     ngx_table_elt_t                  *if_modified_since;
     ngx_table_elt_t                  *if_unmodified_since;
+    ngx_table_elt_t                  *if_match;
+    ngx_table_elt_t                  *if_none_match;
     ngx_table_elt_t                  *user_agent;
     ngx_table_elt_t                  *referer;
     ngx_table_elt_t                  *content_length;
@@ -189,6 +188,7 @@ typedef struct {
 
     ngx_table_elt_t                  *transfer_encoding;
     ngx_table_elt_t                  *expect;
+    ngx_table_elt_t                  *upgrade;
 
 #if (NGX_HTTP_GZIP)
     ngx_table_elt_t                  *accept_encoding;
@@ -200,7 +200,7 @@ typedef struct {
     ngx_table_elt_t                  *keep_alive;
 
 #if (NGX_HTTP_X_FORWARDED_FOR)
-    ngx_table_elt_t                  *x_forwarded_for;
+    ngx_array_t                       x_forwarded_for;
 #endif
 
 #if (NGX_HTTP_REALIP)
@@ -229,6 +229,7 @@ typedef struct {
     time_t                            keep_alive_n;
 
     unsigned                          connection_type:2;
+    unsigned                          chunked:1;
     unsigned                          msie:1;
     unsigned                          msie6:1;
     unsigned                          opera:1;
@@ -281,13 +282,25 @@ typedef struct {
     ngx_chain_t                      *bufs;
     ngx_buf_t                        *buf;
     off_t                             rest;
-    ngx_chain_t                      *to_write;
+    ngx_chain_t                      *free;
+    ngx_chain_t                      *busy;
+    ngx_http_chunked_t               *chunked;
     ngx_http_client_body_handler_pt   post_handler;
 } ngx_http_request_body_t;
 
 
+typedef struct ngx_http_addr_conf_s  ngx_http_addr_conf_t;
+
 typedef struct {
-    ngx_http_request_t               *request;
+    ngx_http_addr_conf_t             *addr_conf;
+    ngx_http_conf_ctx_t              *conf_ctx;
+
+#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
+    ngx_str_t                        *ssl_servername;
+#if (NGX_PCRE)
+    ngx_http_regex_t                 *ssl_servername_regex;
+#endif
+#endif
 
     ngx_buf_t                       **busy;
     ngx_int_t                         nbusy;
@@ -295,21 +308,12 @@ typedef struct {
     ngx_buf_t                       **free;
     ngx_int_t                         nfree;
 
-    ngx_uint_t                        pipeline;    /* unsigned  pipeline:1; */
+#if (NGX_HTTP_SSL)
+    ngx_uint_t                        ssl;    /* unsigned  ssl:1; */
+#endif
 } ngx_http_connection_t;
 
 
-typedef struct ngx_http_server_name_s  ngx_http_server_name_t;
-
-
-typedef struct {
-     ngx_hash_combined_t              names;
-
-     ngx_uint_t                       nregex;
-     ngx_http_server_name_t          *regex;
-} ngx_http_virtual_names_t;
-
-
 typedef void (*ngx_http_cleanup_pt)(void *data);
 
 typedef struct ngx_http_cleanup_s  ngx_http_cleanup_t;
@@ -403,8 +407,6 @@ struct ngx_http_request_s {
     ngx_http_post_subrequest_t       *post_subrequest;
     ngx_http_posted_request_t        *posted_requests;
 
-    ngx_http_virtual_names_t         *virtual_names;
-
     ngx_int_t                         phase_handler;
     ngx_http_handler_pt               content_handler;
     ngx_uint_t                        access_code;
@@ -427,6 +429,9 @@ struct ngx_http_request_s {
     ngx_uint_t                        err_status;
 
     ngx_http_connection_t            *http_connection;
+#if (NGX_HTTP_SPDY)
+    ngx_http_spdy_stream_t           *spdy_stream;
+#endif
 
     ngx_http_log_handler_pt           log_handler;
 
@@ -497,7 +502,6 @@ struct ngx_http_request_s {
 #endif
 
     unsigned                          pipeline:1;
-    unsigned                          plain_http:1;
     unsigned                          chunked:1;
     unsigned                          header_only:1;
     unsigned                          keepalive:1;
@@ -577,4 +581,12 @@ extern ngx_http_header_t       ngx_http_headers_in[];
 extern ngx_http_header_out_t   ngx_http_headers_out[];
 
 
+#define ngx_http_set_connection_log(c, l)                                     \
+                                                                              \
+    c->log->file = l->file;                                                   \
+    if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {                    \
+        c->log->log_level = l->log_level;                                     \
+    }
+
+
 #endif /* _NGX_HTTP_REQUEST_H_INCLUDED_ */

  Added: vendor/nginx-1.4.2/src/http/ngx_http_request_body.c (+1082 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.4.2/src/http/ngx_http_request_body.c    2013-07-22 13:32:39 +0900 (2c61231)
@@ -0,0 +1,1082 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+
+static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r);
+static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r);
+static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r);
+static ngx_int_t ngx_http_read_discarded_request_body(ngx_http_request_t *r);
+static ngx_int_t ngx_http_discard_request_body_filter(ngx_http_request_t *r,
+    ngx_buf_t *b);
+static ngx_int_t ngx_http_test_expect(ngx_http_request_t *r);
+
+static ngx_int_t ngx_http_request_body_filter(ngx_http_request_t *r,
+    ngx_chain_t *in);
+static ngx_int_t ngx_http_request_body_length_filter(ngx_http_request_t *r,
+    ngx_chain_t *in);
+static ngx_int_t ngx_http_request_body_chunked_filter(ngx_http_request_t *r,
+    ngx_chain_t *in);
+static ngx_int_t ngx_http_request_body_save_filter(ngx_http_request_t *r,
+    ngx_chain_t *in);
+
+
+ngx_int_t
+ngx_http_read_client_request_body(ngx_http_request_t *r,
+    ngx_http_client_body_handler_pt post_handler)
+{
+    size_t                     preread;
+    ssize_t                    size;
+    ngx_int_t                  rc;
+    ngx_buf_t                 *b;
+    ngx_chain_t                out, *cl;
+    ngx_http_request_body_t   *rb;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    r->main->count++;
+
+#if (NGX_HTTP_SPDY)
+    if (r->spdy_stream) {
+        rc = ngx_http_spdy_read_request_body(r, post_handler);
+        goto done;
+    }
+#endif
+
+    if (r != r->main || r->request_body || r->discard_body) {
+        post_handler(r);
+        return NGX_OK;
+    }
+
+    if (ngx_http_test_expect(r) != NGX_OK) {
+        rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+        goto done;
+    }
+
+    rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
+    if (rb == NULL) {
+        rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+        goto done;
+    }
+
+    /*
+     * set by ngx_pcalloc():
+     *
+     *     rb->bufs = NULL;
+     *     rb->buf = NULL;
+     *     rb->free = NULL;
+     *     rb->busy = NULL;
+     *     rb->chunked = NULL;
+     */
+
+    rb->rest = -1;
+    rb->post_handler = post_handler;
+
+    r->request_body = rb;
+
+    if (r->headers_in.content_length_n < 0 && !r->headers_in.chunked) {
+        post_handler(r);
+        return NGX_OK;
+    }
+
+    preread = r->header_in->last - r->header_in->pos;
+
+    if (preread) {
+
+        /* there is the pre-read part of the request body */
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "http client request body preread %uz", preread);
+
+        out.buf = r->header_in;
+        out.next = NULL;
+
+        rc = ngx_http_request_body_filter(r, &out);
+
+        if (rc != NGX_OK) {
+            goto done;
+        }
+
+        r->request_length += preread - (r->header_in->last - r->header_in->pos);
+
+        if (!r->headers_in.chunked
+            && rb->rest > 0
+            && rb->rest <= (off_t) (r->header_in->end - r->header_in->last))
+        {
+            /* the whole request body may be placed in r->header_in */
+
+            b = ngx_calloc_buf(r->pool);
+            if (b == NULL) {
+                rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+                goto done;
+            }
+
+            b->temporary = 1;
+            b->start = r->header_in->pos;
+            b->pos = r->header_in->pos;
+            b->last = r->header_in->last;
+            b->end = r->header_in->end;
+
+            rb->buf = b;
+
+            r->read_event_handler = ngx_http_read_client_request_body_handler;
+            r->write_event_handler = ngx_http_request_empty_handler;
+
+            rc = ngx_http_do_read_client_request_body(r);
+            goto done;
+        }
+
+    } else {
+        /* set rb->rest */
+
+        if (ngx_http_request_body_filter(r, NULL) != NGX_OK) {
+            rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+            goto done;
+        }
+    }
+
+    if (rb->rest == 0) {
+        /* the whole request body was pre-read */
+
+        if (r->request_body_in_file_only) {
+            if (ngx_http_write_request_body(r) != NGX_OK) {
+                rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+                goto done;
+            }
+
+            cl = ngx_chain_get_free_buf(r->pool, &rb->free);
+            if (cl == NULL) {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
+
+            b = cl->buf;
+
+            ngx_memzero(b, sizeof(ngx_buf_t));
+
+            b->in_file = 1;
+            b->file_last = rb->temp_file->file.offset;
+            b->file = &rb->temp_file->file;
+
+            rb->bufs = cl;
+        }
+
+        post_handler(r);
+
+        return NGX_OK;
+    }
+
+    if (rb->rest < 0) {
+        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                      "negative request body rest");
+        rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+        goto done;
+    }
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    size = clcf->client_body_buffer_size;
+    size += size >> 2;
+
+    /* TODO: honor r->request_body_in_single_buf */
+
+    if (!r->headers_in.chunked && rb->rest < size) {
+        size = (ssize_t) rb->rest;
+
+        if (r->request_body_in_single_buf) {
+            size += preread;
+        }
+
+    } else {
+        size = clcf->client_body_buffer_size;
+    }
+
+    rb->buf = ngx_create_temp_buf(r->pool, size);
+    if (rb->buf == NULL) {
+        rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+        goto done;
+    }
+
+    r->read_event_handler = ngx_http_read_client_request_body_handler;
+    r->write_event_handler = ngx_http_request_empty_handler;
+
+    rc = ngx_http_do_read_client_request_body(r);
+
+done:
+
+    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
+        r->main->count--;
+    }
+
+    return rc;
+}
+
+
+static void
+ngx_http_read_client_request_body_handler(ngx_http_request_t *r)
+{
+    ngx_int_t  rc;
+
+    if (r->connection->read->timedout) {
+        r->connection->timedout = 1;
+        ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
+        return;
+    }
+
+    rc = ngx_http_do_read_client_request_body(r);
+
+    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
+        ngx_http_finalize_request(r, rc);
+    }
+}
+
+
+static ngx_int_t
+ngx_http_do_read_client_request_body(ngx_http_request_t *r)
+{
+    off_t                      rest;
+    size_t                     size;
+    ssize_t                    n;
+    ngx_int_t                  rc;
+    ngx_buf_t                 *b;
+    ngx_chain_t               *cl, out;
+    ngx_connection_t          *c;
+    ngx_http_request_body_t   *rb;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    c = r->connection;
+    rb = r->request_body;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http read client request body");
+
+    for ( ;; ) {
+        for ( ;; ) {
+            if (rb->buf->last == rb->buf->end) {
+
+                /* pass buffer to request body filter chain */
+
+                out.buf = rb->buf;
+                out.next = NULL;
+
+                rc = ngx_http_request_body_filter(r, &out);
+
+                if (rc != NGX_OK) {
+                    return rc;
+                }
+
+                /* write to file */
+
+                if (ngx_http_write_request_body(r) != NGX_OK) {
+                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
+                }
+
+                /* update chains */
+
+                rc = ngx_http_request_body_filter(r, NULL);
+
+                if (rc != NGX_OK) {
+                    return rc;
+                }
+
+                if (rb->busy != NULL) {
+                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
+                }
+
+                rb->buf->pos = rb->buf->start;
+                rb->buf->last = rb->buf->start;
+            }
+
+            size = rb->buf->end - rb->buf->last;
+            rest = rb->rest - (rb->buf->last - rb->buf->pos);
+
+            if ((off_t) size > rest) {
+                size = (size_t) rest;
+            }
+
+            n = c->recv(c, rb->buf->last, size);
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                           "http client request body recv %z", n);
+
+            if (n == NGX_AGAIN) {
+                break;
+            }
+
+            if (n == 0) {
+                ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                              "client prematurely closed connection");
+            }
+
+            if (n == 0 || n == NGX_ERROR) {
+                c->error = 1;
+                return NGX_HTTP_BAD_REQUEST;
+            }
+
+            rb->buf->last += n;
+            r->request_length += n;
+
+            if (n == rest) {
+                /* pass buffer to request body filter chain */
+
+                out.buf = rb->buf;
+                out.next = NULL;
+
+                rc = ngx_http_request_body_filter(r, &out);
+
+                if (rc != NGX_OK) {
+                    return rc;
+                }
+            }
+
+            if (rb->rest == 0) {
+                break;
+            }
+
+            if (rb->buf->last < rb->buf->end) {
+                break;
+            }
+        }
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "http client request body rest %O", rb->rest);
+
+        if (rb->rest == 0) {
+            break;
+        }
+
+        if (!c->read->ready) {
+            clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+            ngx_add_timer(c->read, clcf->client_body_timeout);
+
+            if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
+
+            return NGX_AGAIN;
+        }
+    }
+
+    if (c->read->timer_set) {
+        ngx_del_timer(c->read);
+    }
+
+    if (rb->temp_file || r->request_body_in_file_only) {
+
+        /* save the last part */
+
+        if (ngx_http_write_request_body(r) != NGX_OK) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
+
+        cl = ngx_chain_get_free_buf(r->pool, &rb->free);
+        if (cl == NULL) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
+
+        b = cl->buf;
+
+        ngx_memzero(b, sizeof(ngx_buf_t));
+
+        b->in_file = 1;
+        b->file_last = rb->temp_file->file.offset;
+        b->file = &rb->temp_file->file;
+
+        rb->bufs = cl;
+    }
+
+    r->read_event_handler = ngx_http_block_reading;
+
+    rb->post_handler(r);
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_write_request_body(ngx_http_request_t *r)
+{
+    ssize_t                    n;
+    ngx_chain_t               *cl;
+    ngx_temp_file_t           *tf;
+    ngx_http_request_body_t   *rb;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    rb = r->request_body;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http write client request body, bufs %p", rb->bufs);
+
+    if (rb->temp_file == NULL) {
+        tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
+        if (tf == NULL) {
+            return NGX_ERROR;
+        }
+
+        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+        tf->file.fd = NGX_INVALID_FILE;
+        tf->file.log = r->connection->log;
+        tf->path = clcf->client_body_temp_path;
+        tf->pool = r->pool;
+        tf->warn = "a client request body is buffered to a temporary file";
+        tf->log_level = r->request_body_file_log_level;
+        tf->persistent = r->request_body_in_persistent_file;
+        tf->clean = r->request_body_in_clean_file;
+
+        if (r->request_body_file_group_access) {
+            tf->access = 0660;
+        }
+
+        rb->temp_file = tf;
+
+        if (rb->bufs == NULL) {
+            /* empty body with r->request_body_in_file_only */
+
+            if (ngx_create_temp_file(&tf->file, tf->path, tf->pool,
+                                     tf->persistent, tf->clean, tf->access)
+                != NGX_OK)
+            {
+                return NGX_ERROR;
+            }
+
+            return NGX_OK;
+        }
+    }
+
+    if (rb->bufs == NULL) {
+        return NGX_OK;
+    }
+
+    n = ngx_write_chain_to_temp_file(rb->temp_file, rb->bufs);
+
+    /* TODO: n == 0 or not complete and level event */
+
+    if (n == NGX_ERROR) {
+        return NGX_ERROR;
+    }
+
+    rb->temp_file->offset += n;
+
+    /* mark all buffers as written */
+
+    for (cl = rb->bufs; cl; cl = cl->next) {
+        cl->buf->pos = cl->buf->last;
+    }
+
+    rb->bufs = NULL;
+
+    return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_http_discard_request_body(ngx_http_request_t *r)
+{
+    ssize_t       size;
+    ngx_int_t     rc;
+    ngx_event_t  *rev;
+
+#if (NGX_HTTP_SPDY)
+    if (r->spdy_stream && r == r->main) {
+        r->spdy_stream->skip_data = NGX_SPDY_DATA_DISCARD;
+        return NGX_OK;
+    }
+#endif
+
+    if (r != r->main || r->discard_body || r->request_body) {
+        return NGX_OK;
+    }
+
+    if (ngx_http_test_expect(r) != NGX_OK) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    rev = r->connection->read;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http set discard body");
+
+    if (rev->timer_set) {
+        ngx_del_timer(rev);
+    }
+
+    if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) {
+        return NGX_OK;
+    }
+
+    size = r->header_in->last - r->header_in->pos;
+
+    if (size || r->headers_in.chunked) {
+        rc = ngx_http_discard_request_body_filter(r, r->header_in);
+
+        if (rc != NGX_OK) {
+            return rc;
+        }
+
+        if (r->headers_in.content_length_n == 0) {
+            return NGX_OK;
+        }
+    }
+
+    rc = ngx_http_read_discarded_request_body(r);
+
+    if (rc == NGX_OK) {
+        r->lingering_close = 0;
+        return NGX_OK;
+    }
+
+    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
+        return rc;
+    }
+
+    /* rc == NGX_AGAIN */
+
+    r->read_event_handler = ngx_http_discarded_request_body_handler;
+
+    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    r->count++;
+    r->discard_body = 1;
+
+    return NGX_OK;
+}
+
+
+void
+ngx_http_discarded_request_body_handler(ngx_http_request_t *r)
+{
+    ngx_int_t                  rc;
+    ngx_msec_t                 timer;
+    ngx_event_t               *rev;
+    ngx_connection_t          *c;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    c = r->connection;
+    rev = c->read;
+
+    if (rev->timedout) {
+        c->timedout = 1;
+        c->error = 1;
+        ngx_http_finalize_request(r, NGX_ERROR);
+        return;
+    }
+
+    if (r->lingering_time) {
+        timer = (ngx_msec_t) (r->lingering_time - ngx_time());
+
+        if (timer <= 0) {
+            r->discard_body = 0;
+            r->lingering_close = 0;
+            ngx_http_finalize_request(r, NGX_ERROR);
+            return;
+        }
+
+    } else {
+        timer = 0;
+    }
+
+    rc = ngx_http_read_discarded_request_body(r);
+
+    if (rc == NGX_OK) {
+        r->discard_body = 0;
+        r->lingering_close = 0;
+        ngx_http_finalize_request(r, NGX_DONE);
+        return;
+    }
+
+    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
+        c->error = 1;
+        ngx_http_finalize_request(r, NGX_ERROR);
+        return;
+    }
+
+    /* rc == NGX_AGAIN */
+
+    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+        c->error = 1;
+        ngx_http_finalize_request(r, NGX_ERROR);
+        return;
+    }
+
+    if (timer) {
+
+        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+        timer *= 1000;
+
+        if (timer > clcf->lingering_timeout) {
+            timer = clcf->lingering_timeout;
+        }
+
+        ngx_add_timer(rev, timer);
+    }
+}
+
+
+static ngx_int_t
+ngx_http_read_discarded_request_body(ngx_http_request_t *r)
+{
+    size_t     size;
+    ssize_t    n;
+    ngx_int_t  rc;
+    ngx_buf_t  b;
+    u_char     buffer[NGX_HTTP_DISCARD_BUFFER_SIZE];
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http read discarded body");
+
+    ngx_memzero(&b, sizeof(ngx_buf_t));
+
+    b.temporary = 1;
+
+    for ( ;; ) {
+        if (r->headers_in.content_length_n == 0) {
+            r->read_event_handler = ngx_http_block_reading;
+            return NGX_OK;
+        }
+
+        if (!r->connection->read->ready) {
+            return NGX_AGAIN;
+        }
+
+        size = (size_t) ngx_min(r->headers_in.content_length_n,
+                                NGX_HTTP_DISCARD_BUFFER_SIZE);
+
+        n = r->connection->recv(r->connection, buffer, size);
+
+        if (n == NGX_ERROR) {
+            r->connection->error = 1;
+            return NGX_OK;
+        }
+
+        if (n == NGX_AGAIN) {
+            return NGX_AGAIN;
+        }
+
+        if (n == 0) {
+            return NGX_OK;
+        }
+
+        b.pos = buffer;
+        b.last = buffer + n;
+
+        rc = ngx_http_discard_request_body_filter(r, &b);
+
+        if (rc != NGX_OK) {
+            return rc;
+        }
+    }
+}
+
+
+static ngx_int_t
+ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b)
+{
+    size_t                    size;
+    ngx_int_t                 rc;
+    ngx_http_request_body_t  *rb;
+
+    if (r->headers_in.chunked) {
+
+        rb = r->request_body;
+
+        if (rb == NULL) {
+
+            rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
+            if (rb == NULL) {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
+
+            rb->chunked = ngx_pcalloc(r->pool, sizeof(ngx_http_chunked_t));
+            if (rb->chunked == NULL) {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
+
+            r->request_body = rb;
+        }
+
+        for ( ;; ) {
+
+            rc = ngx_http_parse_chunked(r, b, rb->chunked);
+
+            if (rc == NGX_OK) {
+
+                /* a chunk has been parsed successfully */
+
+                size = b->last - b->pos;
+
+                if ((off_t) size > rb->chunked->size) {
+                    b->pos += rb->chunked->size;
+                    rb->chunked->size = 0;
+
+                } else {
+                    rb->chunked->size -= size;
+                    b->pos = b->last;
+                }
+
+                continue;
+            }
+
+            if (rc == NGX_DONE) {
+
+                /* a whole response has been parsed successfully */
+
+                r->headers_in.content_length_n = 0;
+                break;
+            }
+
+            if (rc == NGX_AGAIN) {
+
+                /* set amount of data we want to see next time */
+
+                r->headers_in.content_length_n = rb->chunked->length;
+                break;
+            }
+
+            /* invalid */
+
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                          "client sent invalid chunked body");
+
+            return NGX_HTTP_BAD_REQUEST;
+        }
+
+    } else {
+        size = b->last - b->pos;
+
+        if ((off_t) size > r->headers_in.content_length_n) {
+            b->pos += r->headers_in.content_length_n;
+            r->headers_in.content_length_n = 0;
+
+        } else {
+            b->pos = b->last;
+            r->headers_in.content_length_n -= size;
+        }
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_test_expect(ngx_http_request_t *r)
+{
+    ngx_int_t   n;
+    ngx_str_t  *expect;
+
+    if (r->expect_tested
+        || r->headers_in.expect == NULL
+        || r->http_version < NGX_HTTP_VERSION_11)
+    {
+        return NGX_OK;
+    }
+
+    r->expect_tested = 1;
+
+    expect = &r->headers_in.expect->value;
+
+    if (expect->len != sizeof("100-continue") - 1
+        || ngx_strncasecmp(expect->data, (u_char *) "100-continue",
+                           sizeof("100-continue") - 1)
+           != 0)
+    {
+        return NGX_OK;
+    }
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "send 100 Continue");
+
+    n = r->connection->send(r->connection,
+                            (u_char *) "HTTP/1.1 100 Continue" CRLF CRLF,
+                            sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1);
+
+    if (n == sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1) {
+        return NGX_OK;
+    }
+
+    /* we assume that such small packet should be send successfully */
+
+    return NGX_ERROR;
+}
+
+
+static ngx_int_t
+ngx_http_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
+{
+    if (r->headers_in.chunked) {
+        return ngx_http_request_body_chunked_filter(r, in);
+
+    } else {
+        return ngx_http_request_body_length_filter(r, in);
+    }
+}
+
+
+static ngx_int_t
+ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in)
+{
+    size_t                     size;
+    ngx_int_t                  rc;
+    ngx_buf_t                 *b;
+    ngx_chain_t               *cl, *tl, *out, **ll;
+    ngx_http_request_body_t   *rb;
+
+    rb = r->request_body;
+
+    if (rb->rest == -1) {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "http request body content length filter");
+
+        rb->rest = r->headers_in.content_length_n;
+    }
+
+    out = NULL;
+    ll = &out;
+
+    for (cl = in; cl; cl = cl->next) {
+
+        tl = ngx_chain_get_free_buf(r->pool, &rb->free);
+        if (tl == NULL) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
+
+        b = tl->buf;
+
+        ngx_memzero(b, sizeof(ngx_buf_t));
+
+        b->temporary = 1;
+        b->tag = (ngx_buf_tag_t) &ngx_http_read_client_request_body;
+        b->start = cl->buf->pos;
+        b->pos = cl->buf->pos;
+        b->last = cl->buf->last;
+        b->end = cl->buf->end;
+
+        size = cl->buf->last - cl->buf->pos;
+
+        if ((off_t) size < rb->rest) {
+            cl->buf->pos = cl->buf->last;
+            rb->rest -= size;
+
+        } else {
+            cl->buf->pos += rb->rest;
+            rb->rest = 0;
+            b->last = cl->buf->pos;
+            b->last_buf = 1;
+        }
+
+        *ll = tl;
+        ll = &tl->next;
+    }
+
+    rc = ngx_http_request_body_save_filter(r, out);
+
+    ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out,
+                            (ngx_buf_tag_t) &ngx_http_read_client_request_body);
+
+    return rc;
+}
+
+
+static ngx_int_t
+ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
+{
+    size_t                     size;
+    ngx_int_t                  rc;
+    ngx_buf_t                 *b;
+    ngx_chain_t               *cl, *out, *tl, **ll;
+    ngx_http_request_body_t   *rb;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    rb = r->request_body;
+
+    if (rb->rest == -1) {
+
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "http request body chunked filter");
+
+        rb->chunked = ngx_pcalloc(r->pool, sizeof(ngx_http_chunked_t));
+        if (rb->chunked == NULL) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
+
+        r->headers_in.content_length_n = 0;
+        rb->rest = 3;
+    }
+
+    out = NULL;
+    ll = &out;
+
+    for (cl = in; cl; cl = cl->next) {
+
+        for ( ;; ) {
+
+            ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
+                           "http body chunked buf "
+                           "t:%d f:%d %p, pos %p, size: %z file: %O, size: %z",
+                           cl->buf->temporary, cl->buf->in_file,
+                           cl->buf->start, cl->buf->pos,
+                           cl->buf->last - cl->buf->pos,
+                           cl->buf->file_pos,
+                           cl->buf->file_last - cl->buf->file_pos);
+
+            rc = ngx_http_parse_chunked(r, cl->buf, rb->chunked);
+
+            if (rc == NGX_OK) {
+
+                /* a chunk has been parsed successfully */
+
+                clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+                if (clcf->client_max_body_size
+                    && clcf->client_max_body_size
+                       < r->headers_in.content_length_n + rb->chunked->size)
+                {
+                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                                  "client intended to send too large chunked "
+                                  "body: %O bytes",
+                                  r->headers_in.content_length_n
+                                  + rb->chunked->size);
+
+                    r->lingering_close = 1;
+
+                    return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
+                }
+
+                tl = ngx_chain_get_free_buf(r->pool, &rb->free);
+                if (tl == NULL) {
+                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
+                }
+
+                b = tl->buf;
+
+                ngx_memzero(b, sizeof(ngx_buf_t));
+
+                b->temporary = 1;
+                b->tag = (ngx_buf_tag_t) &ngx_http_read_client_request_body;
+                b->start = cl->buf->pos;
+                b->pos = cl->buf->pos;
+                b->last = cl->buf->last;
+                b->end = cl->buf->end;
+
+                *ll = tl;
+                ll = &tl->next;
+
+                size = cl->buf->last - cl->buf->pos;
+
+                if ((off_t) size > rb->chunked->size) {
+                    cl->buf->pos += rb->chunked->size;
+                    r->headers_in.content_length_n += rb->chunked->size;
+                    rb->chunked->size = 0;
+
+                } else {
+                    rb->chunked->size -= size;
+                    r->headers_in.content_length_n += size;
+                    cl->buf->pos = cl->buf->last;
+                }
+
+                b->last = cl->buf->pos;
+
+                continue;
+            }
+
+            if (rc == NGX_DONE) {
+
+                /* a whole response has been parsed successfully */
+
+                rb->rest = 0;
+
+                tl = ngx_chain_get_free_buf(r->pool, &rb->free);
+                if (tl == NULL) {
+                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
+                }
+
+                b = tl->buf;
+
+                ngx_memzero(b, sizeof(ngx_buf_t));
+
+                b->last_buf = 1;
+
+                *ll = tl;
+                ll = &tl->next;
+
+                break;
+            }
+
+            if (rc == NGX_AGAIN) {
+
+                /* set rb->rest, amount of data we want to see next time */
+
+                rb->rest = rb->chunked->length;
+
+                break;
+            }
+
+            /* invalid */
+
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                          "client sent invalid chunked body");
+
+            return NGX_HTTP_BAD_REQUEST;
+        }
+    }
+
+    rc = ngx_http_request_body_save_filter(r, out);
+
+    ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out,
+                            (ngx_buf_tag_t) &ngx_http_read_client_request_body);
+
+    return rc;
+}
+
+
+static ngx_int_t
+ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in)
+{
+#if (NGX_DEBUG)
+    ngx_chain_t               *cl;
+#endif
+    ngx_http_request_body_t   *rb;
+
+    rb = r->request_body;
+
+#if (NGX_DEBUG)
+
+    for (cl = rb->bufs; cl; cl = cl->next) {
+        ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
+                       "http body old buf t:%d f:%d %p, pos %p, size: %z "
+                       "file: %O, size: %z",
+                       cl->buf->temporary, cl->buf->in_file,
+                       cl->buf->start, cl->buf->pos,
+                       cl->buf->last - cl->buf->pos,
+                       cl->buf->file_pos,
+                       cl->buf->file_last - cl->buf->file_pos);
+    }
+
+    for (cl = in; cl; cl = cl->next) {
+        ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
+                       "http body new buf t:%d f:%d %p, pos %p, size: %z "
+                       "file: %O, size: %z",
+                       cl->buf->temporary, cl->buf->in_file,
+                       cl->buf->start, cl->buf->pos,
+                       cl->buf->last - cl->buf->pos,
+                       cl->buf->file_pos,
+                       cl->buf->file_last - cl->buf->file_pos);
+    }
+
+#endif
+
+    /* TODO: coalesce neighbouring buffers */
+
+    if (ngx_chain_add_copy(r->pool, &rb->bufs, in) != NGX_OK) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    return NGX_OK;
+}

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_script.c (+3 -7) 99%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_script.c    2013-07-22 11:05:55 +0900 (e214519)
+++ vendor/nginx-1.4.2/src/http/ngx_http_script.c    2013-07-22 13:32:39 +0900 (54d0195)
@@ -114,11 +114,6 @@ ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)
 
     v = ccv->value;
 
-    if (v->len == 0) {
-        ngx_conf_log_error(NGX_LOG_EMERG, ccv->cf, 0, "empty parameter");
-        return NGX_ERROR;
-    }
-
     nv = 0;
     nc = 0;
 
@@ -133,8 +128,9 @@ ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)
         }
     }
 
-    if (v->data[0] != '$' && (ccv->conf_prefix || ccv->root_prefix)) {
-
+    if ((v->len == 0 || v->data[0] != '$')
+        && (ccv->conf_prefix || ccv->root_prefix))
+    {
         if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
             return NGX_ERROR;
         }

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

  Added: vendor/nginx-1.4.2/src/http/ngx_http_spdy.c (+2882 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.4.2/src/http/ngx_http_spdy.c    2013-07-22 13:32:39 +0900 (3febc23)
@@ -0,0 +1,2882 @@
+
+/*
+ * Copyright (C) Nginx, Inc.
+ * Copyright (C) Valentin V. Bartenev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+#include <ngx_http_spdy_module.h>
+
+#include <zlib.h>
+
+
+#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
+
+#define ngx_str5cmp(m, c0, c1, c2, c3, c4)                                    \
+    *(uint32_t *) m == (c3 << 24 | c2 << 16 | c1 << 8 | c0)                   \
+        && m[4] == c4
+
+#else
+
+#define ngx_str5cmp(m, c0, c1, c2, c3, c4)                                    \
+    m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 && m[4] == c4
+
+#endif
+
+
+#if (NGX_HAVE_NONALIGNED)
+
+#define ngx_spdy_frame_parse_uint16(p)  ntohs(*(uint16_t *) (p))
+#define ngx_spdy_frame_parse_uint32(p)  ntohl(*(uint32_t *) (p))
+
+#else
+
+#define ngx_spdy_frame_parse_uint16(p) ((p)[0] << 8 | (p)[1])
+#define ngx_spdy_frame_parse_uint32(p)                                        \
+    ((p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3])
+
+#endif
+
+#define ngx_spdy_frame_parse_sid(p)                                           \
+    (ngx_spdy_frame_parse_uint32(p) & 0x7fffffff)
+
+
+#define ngx_spdy_ctl_frame_check(h)                                           \
+    (((h) & 0xffffff00) == 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_frame_flags(p)      ((p) >> 24)
+#define ngx_spdy_frame_length(p)     ((p) & 0x00ffffff)
+
+
+#define NGX_SPDY_SKIP_HEADERS_BUFFER_SIZE  4096
+#define NGX_SPDY_CTL_FRAME_BUFFER_SIZE     16
+
+#define NGX_SPDY_PROTOCOL_ERROR            1
+#define NGX_SPDY_INVALID_STREAM            2
+#define NGX_SPDY_REFUSED_STREAM            3
+#define NGX_SPDY_UNSUPPORTED_VERSION       4
+#define NGX_SPDY_CANCEL                    5
+#define NGX_SPDY_INTERNAL_ERROR            6
+#define NGX_SPDY_FLOW_CONTROL_ERROR        7
+
+#define NGX_SPDY_SETTINGS_MAX_STREAMS      4
+
+#define NGX_SPDY_SETTINGS_FLAG_PERSIST     0x01
+
+typedef struct {
+    ngx_uint_t    hash;
+    u_char        len;
+    u_char        header[7];
+    ngx_int_t   (*handler)(ngx_http_request_t *r);
+} ngx_http_spdy_request_header_t;
+
+
+static void ngx_http_spdy_read_handler(ngx_event_t *rev);
+static void ngx_http_spdy_write_handler(ngx_event_t *wev);
+static void ngx_http_spdy_handle_connection(ngx_http_spdy_connection_t *sc);
+
+static u_char *ngx_http_spdy_state_detect_settings(
+    ngx_http_spdy_connection_t *sc, u_char *pos, u_char *end);
+static u_char *ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc,
+    u_char *pos, u_char *end);
+static u_char *ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc,
+    u_char *pos, u_char *end);
+static u_char *ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc,
+    u_char *pos, u_char *end);
+static u_char *ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc,
+    u_char *pos, u_char *end);
+static u_char *ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc,
+    u_char *pos, u_char *end);
+static u_char *ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc,
+    u_char *pos, u_char *end);
+static u_char *ngx_http_spdy_state_rst_stream(ngx_http_spdy_connection_t *sc,
+    u_char *pos, u_char *end);
+static u_char *ngx_http_spdy_state_ping(ngx_http_spdy_connection_t *sc,
+    u_char *pos, u_char *end);
+static u_char *ngx_http_spdy_state_skip(ngx_http_spdy_connection_t *sc,
+    u_char *pos, u_char *end);
+static u_char *ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc,
+    u_char *pos, u_char *end);
+static u_char *ngx_http_spdy_state_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_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_rst_stream(ngx_http_spdy_connection_t *sc,
+    ngx_uint_t sid, ngx_uint_t status, ngx_uint_t priority);
+static ngx_int_t ngx_http_spdy_send_settings(ngx_http_spdy_connection_t *sc);
+static ngx_int_t ngx_http_spdy_settings_frame_handler(
+    ngx_http_spdy_connection_t *sc, ngx_http_spdy_out_frame_t *frame);
+static ngx_http_spdy_out_frame_t *ngx_http_spdy_get_ctl_frame(
+    ngx_http_spdy_connection_t *sc, size_t size, ngx_uint_t priority);
+static ngx_int_t ngx_http_spdy_ctl_frame_handler(
+    ngx_http_spdy_connection_t *sc, ngx_http_spdy_out_frame_t *frame);
+
+static ngx_http_spdy_stream_t *ngx_http_spdy_create_stream(
+    ngx_http_spdy_connection_t *sc, ngx_uint_t id, ngx_uint_t priority);
+static ngx_http_spdy_stream_t *ngx_http_spdy_get_stream_by_id(
+    ngx_http_spdy_connection_t *sc, ngx_uint_t sid);
+#define ngx_http_spdy_streams_index_size(sscf)  (sscf->streams_index_mask + 1)
+#define ngx_http_spdy_stream_index(sscf, sid)                                 \
+    ((sid >> 1) & sscf->streams_index_mask)
+
+static ngx_int_t ngx_http_spdy_parse_header(ngx_http_request_t *r);
+static ngx_int_t ngx_http_spdy_alloc_large_header_buffer(ngx_http_request_t *r);
+
+static ngx_int_t ngx_http_spdy_handle_request_header(ngx_http_request_t *r);
+static ngx_int_t ngx_http_spdy_parse_method(ngx_http_request_t *r);
+static ngx_int_t ngx_http_spdy_parse_scheme(ngx_http_request_t *r);
+static ngx_int_t ngx_http_spdy_parse_url(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 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 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 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, 7, "version", ngx_http_spdy_parse_version },
+};
+
+#define NGX_SPDY_REQUEST_HEADERS                                              \
+    (sizeof(ngx_http_spdy_request_headers)                                    \
+     / sizeof(ngx_http_spdy_request_header_t))
+
+
+void
+ngx_http_spdy_init(ngx_event_t *rev)
+{
+    int                          rc;
+    ngx_connection_t            *c;
+    ngx_pool_cleanup_t          *cln;
+    ngx_http_connection_t       *hc;
+    ngx_http_spdy_srv_conf_t    *sscf;
+    ngx_http_spdy_main_conf_t   *smcf;
+    ngx_http_spdy_connection_t  *sc;
+
+    c = rev->data;
+    hc = c->data;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "init spdy request");
+
+    c->log->action = "processing SPDY";
+
+    smcf = ngx_http_get_module_main_conf(hc->conf_ctx, ngx_http_spdy_module);
+
+    if (smcf->recv_buffer == NULL) {
+        smcf->recv_buffer = ngx_palloc(ngx_cycle->pool, smcf->recv_buffer_size);
+        if (smcf->recv_buffer == NULL) {
+            ngx_http_close_connection(c);
+            return;
+        }
+    }
+
+    sc = ngx_pcalloc(c->pool, sizeof(ngx_http_spdy_connection_t));
+    if (sc == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    sc->connection = c;
+    sc->http_connection = hc;
+
+    sc->handler = ngx_http_spdy_state_detect_settings;
+
+    sc->zstream_in.zalloc = ngx_http_spdy_zalloc;
+    sc->zstream_in.zfree = ngx_http_spdy_zfree;
+    sc->zstream_in.opaque = sc;
+
+    rc = inflateInit(&sc->zstream_in);
+    if (rc != Z_OK) {
+        ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                      "inflateInit() failed: %d", rc);
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    sc->zstream_out.zalloc = ngx_http_spdy_zalloc;
+    sc->zstream_out.zfree = ngx_http_spdy_zfree;
+    sc->zstream_out.opaque = sc;
+
+    sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_spdy_module);
+
+    rc = deflateInit2(&sc->zstream_out, (int) sscf->headers_comp,
+                      Z_DEFLATED, 11, 4, Z_DEFAULT_STRATEGY);
+
+    if (rc != Z_OK) {
+        ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                      "deflateInit2() failed: %d", rc);
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    rc = deflateSetDictionary(&sc->zstream_out, ngx_http_spdy_dict,
+                              sizeof(ngx_http_spdy_dict));
+    if (rc != Z_OK) {
+        ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                      "deflateSetDictionary() failed: %d", rc);
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    sc->pool = ngx_create_pool(sscf->pool_size, sc->connection->log);
+    if (sc->pool == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    cln = ngx_pool_cleanup_add(c->pool, sizeof(ngx_pool_cleanup_file_t));
+    if (cln == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    cln->handler = ngx_http_spdy_pool_cleanup;
+    cln->data = sc;
+
+    sc->streams_index = ngx_pcalloc(sc->pool,
+                                    ngx_http_spdy_streams_index_size(sscf)
+                                    * sizeof(ngx_http_spdy_stream_t *));
+    if (sc->streams_index == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    c->data = sc;
+
+    rev->handler = ngx_http_spdy_read_handler;
+    c->write->handler = ngx_http_spdy_write_handler;
+
+    ngx_http_spdy_read_handler(rev);
+}
+
+
+static void
+ngx_http_spdy_read_handler(ngx_event_t *rev)
+{
+    u_char                      *p, *end;
+    size_t                       available;
+    ssize_t                      n;
+    ngx_connection_t            *c;
+    ngx_http_spdy_main_conf_t   *smcf;
+    ngx_http_spdy_connection_t  *sc;
+
+    c = rev->data;
+    sc = c->data;
+
+    if (rev->timedout) {
+        ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+        ngx_http_spdy_finalize_connection(sc, NGX_HTTP_REQUEST_TIME_OUT);
+        return;
+    }
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy read handler");
+
+    sc->blocked = 1;
+
+    smcf = ngx_http_get_module_main_conf(sc->http_connection->conf_ctx,
+                                         ngx_http_spdy_module);
+
+    available = smcf->recv_buffer_size - 2 * NGX_SPDY_STATE_BUFFER_SIZE;
+
+    do {
+        p = smcf->recv_buffer;
+
+        ngx_memcpy(p, sc->buffer, NGX_SPDY_STATE_BUFFER_SIZE);
+        end = p + sc->buffer_used;
+
+        n = c->recv(c, end, available);
+
+        if (n == NGX_AGAIN) {
+            break;
+        }
+
+        if (n == 0 && (sc->waiting || sc->processing)) {
+            ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                          "client closed prematurely connection");
+        }
+
+        if (n == 0 || n == NGX_ERROR) {
+            ngx_http_spdy_finalize_connection(sc,
+                                              NGX_HTTP_CLIENT_CLOSED_REQUEST);
+            return;
+        }
+
+        end += n;
+
+        sc->buffer_used = 0;
+        sc->waiting = 0;
+
+        do {
+            p = sc->handler(sc, p, end);
+
+            if (p == NULL) {
+                return;
+            }
+
+        } while (p != end);
+
+    } while (rev->ready);
+
+    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+        ngx_http_spdy_finalize_connection(sc, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return;
+    }
+
+    sc->blocked = 0;
+
+    if (sc->processing) {
+        if (rev->timer_set) {
+            ngx_del_timer(rev);
+        }
+        return;
+    }
+
+    ngx_http_spdy_handle_connection(sc);
+}
+
+
+static void
+ngx_http_spdy_write_handler(ngx_event_t *wev)
+{
+    ngx_int_t                    rc;
+    ngx_connection_t            *c;
+    ngx_http_spdy_stream_t      *stream, *s, *sn;
+    ngx_http_spdy_connection_t  *sc;
+
+    c = wev->data;
+    sc = c->data;
+
+    if (wev->timedout) {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "spdy write event timed out");
+        ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
+        return;
+    }
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy write handler");
+
+    sc->blocked = 2;
+
+    rc = ngx_http_spdy_send_output_queue(sc);
+
+    if (rc == NGX_ERROR) {
+        ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
+        return;
+    }
+
+    stream = NULL;
+
+    for (s = sc->last_stream; s; s = sn) {
+         sn = s->next;
+         s->next = stream;
+         stream = s;
+    }
+
+    sc->last_stream = NULL;
+
+    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);
+
+        wev = stream->request->connection->write;
+        wev->handler(wev);
+    }
+
+    sc->blocked = 0;
+
+    if (rc == NGX_AGAIN) {
+        return;
+    }
+
+    ngx_http_spdy_handle_connection(sc);
+}
+
+
+ngx_int_t
+ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc)
+{
+    ngx_chain_t                *cl;
+    ngx_event_t                *wev;
+    ngx_connection_t           *c;
+    ngx_http_core_loc_conf_t   *clcf;
+    ngx_http_spdy_out_frame_t  *out, *frame, *fn;
+
+    c = sc->connection;
+
+    if (c->error) {
+        return NGX_ERROR;
+    }
+
+    wev = c->write;
+
+    if (!wev->ready) {
+        return NGX_OK;
+    }
+
+    cl = NULL;
+    out = NULL;
+
+    for (frame = sc->last_out; frame; frame = fn) {
+        frame->last->next = cl;
+        cl = frame->first;
+
+        fn = frame->next;
+        frame->next = out;
+        out = frame;
+
+        ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "spdy frame out: %p sid:%ui prio:%ui bl:%ui size:%uz",
+                       out, out->stream ? out->stream->id : 0, out->priority,
+                       out->blocked, out->size);
+    }
+
+    cl = c->send_chain(c, cl, 0);
+
+    if (cl == NGX_CHAIN_ERROR) {
+        c->error = 1;
+
+        if (!sc->blocked) {
+            ngx_post_event(wev, &ngx_posted_events);
+        }
+
+        return NGX_ERROR;
+    }
+
+    clcf = ngx_http_get_module_loc_conf(sc->http_connection->conf_ctx,
+                                        ngx_http_core_module);
+
+    if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
+        return NGX_ERROR; /* FIXME */
+    }
+
+    if (cl) {
+        ngx_add_timer(wev, clcf->send_timeout);
+
+    } else {
+        if (wev->timer_set) {
+            ngx_del_timer(wev);
+        }
+    }
+
+    for ( /* void */ ; out; out = out->next) {
+        if (out->handler(sc, out) != NGX_OK) {
+            out->blocked = 1;
+            out->priority = NGX_SPDY_HIGHEST_PRIORITY;
+            break;
+        }
+
+        ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "spdy frame sent: %p sid:%ui bl:%ui size:%uz",
+                       out, out->stream ? out->stream->id : 0,
+                       out->blocked, out->size);
+    }
+
+    frame = NULL;
+
+    for ( /* void */ ; out; out = fn) {
+        fn = out->next;
+        out->next = frame;
+        frame = out;
+    }
+
+    sc->last_out = frame;
+
+    return NGX_OK;
+}
+
+
+static void
+ngx_http_spdy_handle_connection(ngx_http_spdy_connection_t *sc)
+{
+    ngx_connection_t          *c;
+    ngx_http_spdy_srv_conf_t  *sscf;
+
+    if (sc->last_out || sc->processing) {
+        return;
+    }
+
+    c = sc->connection;
+
+    if (c->error) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    if (c->buffered) {
+        return;
+    }
+
+    sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
+                                        ngx_http_spdy_module);
+    if (sc->waiting) {
+        ngx_add_timer(c->read, sscf->recv_timeout);
+        return;
+    }
+
+    if (ngx_terminate || ngx_exiting) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    ngx_destroy_pool(sc->pool);
+
+    sc->pool = NULL;
+    sc->free_ctl_frames = NULL;
+    sc->free_fake_connections = NULL;
+
+#if (NGX_HTTP_SSL)
+    if (c->ssl) {
+        ngx_ssl_free_buffer(c);
+    }
+#endif
+
+    c->destroyed = 1;
+    c->idle = 1;
+    ngx_reusable_connection(c, 1);
+
+    c->write->handler = ngx_http_empty_handler;
+    c->read->handler = ngx_http_spdy_keepalive_handler;
+
+    if (c->write->timer_set) {
+        ngx_del_timer(c->write);
+    }
+
+    ngx_add_timer(c->read, sscf->keepalive_timeout);
+}
+
+
+static u_char *
+ngx_http_spdy_state_detect_settings(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
+     */
+
+    if (*(uint32_t *) pos == htonl(ngx_spdy_ctl_frame_head(NGX_SPDY_SETTINGS)))
+    {
+        sc->length = ngx_spdy_frame_length(htonl(((uint32_t *) pos)[1]));
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                       "spdy SETTINGS frame received, size: %uz", sc->length);
+
+        pos += NGX_SPDY_FRAME_HEADER_SIZE;
+
+        return ngx_http_spdy_state_settings(sc, pos, end);
+    }
+
+    ngx_http_spdy_send_settings(sc);
+
+    return ngx_http_spdy_state_head(sc, pos, end);
+}
+
+
+static u_char *
+ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos,
+    u_char *end)
+{
+    uint32_t  head, flen;
+
+    if (end - pos < NGX_SPDY_FRAME_HEADER_SIZE) {
+        return ngx_http_spdy_state_save(sc, pos, end,
+                                        ngx_http_spdy_state_head);
+    }
+
+    head = ngx_spdy_frame_parse_uint32(pos);
+
+    pos += sizeof(uint32_t);
+
+    flen = ngx_spdy_frame_parse_uint32(pos);
+
+    sc->flags = ngx_spdy_frame_flags(flen);
+    sc->length = ngx_spdy_frame_length(flen);
+
+    pos += sizeof(uint32_t);
+
+    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy process frame head:%08Xd f:%ui l:%ui",
+                   head, sc->flags, sc->length);
+
+    if (ngx_spdy_ctl_frame_check(head)) {
+        switch (ngx_spdy_ctl_frame_type(head)) {
+
+        case NGX_SPDY_SYN_STREAM:
+            return ngx_http_spdy_state_syn_stream(sc, pos, end);
+
+        case NGX_SPDY_SYN_REPLY:
+            return ngx_http_spdy_state_protocol_error(sc);
+
+        case NGX_SPDY_RST_STREAM:
+            return ngx_http_spdy_state_rst_stream(sc, pos, end);
+
+        case NGX_SPDY_SETTINGS:
+            return ngx_http_spdy_state_skip(sc, pos, end);
+
+        case NGX_SPDY_NOOP:
+            return ngx_http_spdy_state_noop(sc, pos, end);
+
+        case NGX_SPDY_PING:
+            return ngx_http_spdy_state_ping(sc, pos, end);
+
+        case NGX_SPDY_GOAWAY:
+            return ngx_http_spdy_state_skip(sc, pos, end); /* TODO */
+
+        case NGX_SPDY_HEADERS:
+            return ngx_http_spdy_state_protocol_error(sc);
+
+        default: /* TODO logging */
+            return ngx_http_spdy_state_skip(sc, pos, end);
+        }
+    }
+
+    if (ngx_spdy_data_frame_check(head)) {
+        sc->stream = ngx_http_spdy_get_stream_by_id(sc, head);
+        return ngx_http_spdy_state_data(sc, pos, end);
+    }
+
+
+    /* TODO version & type check */
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy unknown frame");
+
+    return ngx_http_spdy_state_protocol_error(sc);
+}
+
+
+static u_char *
+ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
+    u_char *end)
+{
+    ngx_uint_t                 sid, prio;
+    ngx_http_spdy_stream_t    *stream;
+    ngx_http_spdy_srv_conf_t  *sscf;
+
+    if (end - pos < NGX_SPDY_SYN_STREAM_SIZE) {
+        return ngx_http_spdy_state_save(sc, pos, end,
+                                        ngx_http_spdy_state_syn_stream);
+    }
+
+    if (sc->length <= NGX_SPDY_SYN_STREAM_SIZE) {
+        /* TODO logging */
+        return ngx_http_spdy_state_protocol_error(sc);
+    }
+
+    sc->length -= NGX_SPDY_SYN_STREAM_SIZE;
+
+    sid = ngx_spdy_frame_parse_sid(pos);
+    prio = pos[8] >> 6;
+
+    pos += NGX_SPDY_SYN_STREAM_SIZE;
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy SYN_STREAM frame sid:%ui prio:%ui", sid, prio);
+
+    sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
+                                        ngx_http_spdy_module);
+
+    if (sc->processing >= sscf->concurrent_streams) {
+
+        ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
+                      "spdy concurrent streams excessed %ui", sc->processing);
+
+        if (ngx_http_spdy_send_rst_stream(sc, sid, NGX_SPDY_REFUSED_STREAM,
+                                          prio)
+            != NGX_OK)
+        {
+            return ngx_http_spdy_state_internal_error(sc);
+        }
+
+        return ngx_http_spdy_state_headers_skip(sc, pos, end);
+    }
+
+    stream = ngx_http_spdy_create_stream(sc, sid, prio);
+    if (stream == NULL) {
+        return ngx_http_spdy_state_internal_error(sc);
+    }
+
+    stream->in_closed = (sc->flags & NGX_SPDY_FLAG_FIN) ? 1 : 0;
+
+    stream->request->request_length = NGX_SPDY_FRAME_HEADER_SIZE
+                                      + NGX_SPDY_SYN_STREAM_SIZE
+                                      + sc->length;
+
+    sc->stream = stream;
+
+    sc->last_sid = sid;
+
+    return ngx_http_spdy_state_headers(sc, pos, end);
+}
+
+
+static u_char *
+ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
+    u_char *end)
+{
+    int                  z;
+    size_t               size;
+    ngx_buf_t           *buf;
+    ngx_int_t            rc;
+    ngx_uint_t           complete;
+    ngx_http_request_t  *r;
+
+    size = end - pos;
+
+    if (size == 0) {
+        return ngx_http_spdy_state_save(sc, pos, end,
+                                        ngx_http_spdy_state_headers);
+    }
+
+    if (size >= sc->length) {
+        size = sc->length;
+        complete = 1;
+
+    } else {
+        complete = 0;
+    }
+
+    r = sc->stream->request;
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "spdy process HEADERS %uz of %uz", size, sc->length);
+
+    buf = r->header_in;
+
+    sc->zstream_in.next_in = pos;
+    sc->zstream_in.avail_in = size;
+    sc->zstream_in.next_out = buf->last;
+    sc->zstream_in.avail_out = buf->end - buf->last - 1;
+
+    z = inflate(&sc->zstream_in, Z_NO_FLUSH);
+
+    if (z == Z_NEED_DICT) {
+        z = inflateSetDictionary(&sc->zstream_in, ngx_http_spdy_dict,
+                                 sizeof(ngx_http_spdy_dict));
+        if (z != Z_OK) {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "spdy inflateSetDictionary() failed: %d", z);
+            ngx_http_spdy_close_stream(sc->stream, 0);
+            return ngx_http_spdy_state_protocol_error(sc);
+        }
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "spdy inflateSetDictionary(): %d", z);
+
+        z = sc->zstream_in.avail_in ? inflate(&sc->zstream_in, Z_NO_FLUSH)
+                                    : Z_OK;
+    }
+
+    if (z != Z_OK) {
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "spdy inflate() failed: %d", z);
+        ngx_http_spdy_close_stream(sc->stream, 0);
+        return ngx_http_spdy_state_protocol_error(sc);
+    }
+
+    ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "spdy inflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
+                   sc->zstream_in.next_in, sc->zstream_in.next_out,
+                   sc->zstream_in.avail_in, sc->zstream_in.avail_out,
+                   z);
+
+    sc->length -= sc->zstream_in.next_in - pos;
+    pos = sc->zstream_in.next_in;
+
+    buf->last = sc->zstream_in.next_out;
+
+    if (r->headers_in.headers.part.elts == NULL) {
+
+        if (buf->last - buf->pos < NGX_SPDY_NV_NUM_SIZE) {
+            return ngx_http_spdy_state_save(sc, pos, end,
+                                            ngx_http_spdy_state_headers);
+        }
+
+        sc->headers = ngx_spdy_frame_parse_uint16(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);
+
+        if (ngx_list_init(&r->headers_in.headers, r->pool, sc->headers + 3,
+                          sizeof(ngx_table_elt_t))
+            != NGX_OK)
+        {
+            ngx_http_spdy_close_stream(sc->stream,
+                                       NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return ngx_http_spdy_state_headers_error(sc, pos, end);
+        }
+
+        if (ngx_array_init(&r->headers_in.cookies, r->pool, 2,
+                           sizeof(ngx_table_elt_t *))
+            != NGX_OK)
+        {
+            ngx_http_spdy_close_stream(sc->stream,
+                                       NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return ngx_http_spdy_state_headers_error(sc, pos, end);
+        }
+    }
+
+    while (sc->headers) {
+
+        rc = ngx_http_spdy_parse_header(r);
+
+        switch (rc) {
+
+        case NGX_DONE:
+            sc->headers--;
+
+        case NGX_OK:
+            break;
+
+        case NGX_AGAIN:
+
+            if (sc->zstream_in.avail_in) {
+
+                rc = ngx_http_spdy_alloc_large_header_buffer(r);
+
+                if (rc == NGX_DECLINED) {
+                    /* TODO logging */
+                    ngx_http_finalize_request(r,
+                                            NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
+                    return ngx_http_spdy_state_headers_error(sc, pos, end);
+                }
+
+                if (rc != NGX_OK) {
+                    ngx_http_spdy_close_stream(sc->stream,
+                                               NGX_HTTP_INTERNAL_SERVER_ERROR);
+                    return ngx_http_spdy_state_headers_error(sc, pos, end);
+                }
+
+                buf = r->header_in;
+
+                sc->zstream_in.next_out = buf->last;
+                sc->zstream_in.avail_out = buf->end - buf->last - 1;
+
+                z = inflate(&sc->zstream_in, Z_NO_FLUSH);
+
+                if (z != Z_OK) {
+                    ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                                  "spdy inflate() failed: %d", z);
+                    ngx_http_spdy_close_stream(sc->stream, 0);
+                    return ngx_http_spdy_state_protocol_error(sc);
+                }
+
+                sc->length -= sc->zstream_in.next_in - pos;
+                pos = sc->zstream_in.next_in;
+
+                buf->last = sc->zstream_in.next_out;
+
+                continue;
+            }
+
+            if (complete) {
+                /* TODO: improve error message */
+                ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                               "spdy again while last chunk");
+                ngx_http_spdy_close_stream(sc->stream, 0);
+                return ngx_http_spdy_state_protocol_error(sc);
+            }
+
+            return ngx_http_spdy_state_save(sc, pos, end,
+                                            ngx_http_spdy_state_headers);
+
+        case NGX_HTTP_PARSE_INVALID_REQUEST:
+
+            /* TODO: improve error message */
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent invalid header line");
+
+            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+
+            return ngx_http_spdy_state_headers_error(sc, pos, end);
+
+        default: /* NGX_HTTP_PARSE_INVALID_HEADER */
+
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent invalid HEADERS spdy frame");
+            ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
+            return ngx_http_spdy_state_protocol_error(sc);
+        }
+
+        /* a header line has been parsed successfully */
+
+        rc = ngx_http_spdy_handle_request_header(r);
+
+        if (rc != NGX_OK) {
+            if (rc == NGX_HTTP_PARSE_INVALID_HEADER) {
+                ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                              "client sent invalid HEADERS spdy frame");
+                ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
+                return ngx_http_spdy_state_protocol_error(sc);
+            }
+
+            if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) {
+                ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+            }
+
+            return ngx_http_spdy_state_headers_error(sc, pos, end);
+        }
+    }
+
+    if (buf->pos != buf->last) {
+        /* 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 (!complete) {
+        return ngx_http_spdy_state_save(sc, pos, end,
+                                        ngx_http_spdy_state_headers);
+    }
+
+    ngx_http_spdy_run_request(r);
+
+    return ngx_http_spdy_state_complete(sc, pos, end);
+}
+
+
+static u_char *
+ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc, u_char *pos,
+    u_char *end)
+{
+    if (sc->connection->error) {
+        return ngx_http_spdy_state_internal_error(sc);
+    }
+
+    return ngx_http_spdy_state_headers_skip(sc, pos, end);
+}
+
+
+static u_char *
+ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
+    u_char *end)
+{
+    int     n;
+    size_t  size;
+    u_char  buffer[NGX_SPDY_SKIP_HEADERS_BUFFER_SIZE];
+
+    if (sc->length == 0) {
+        return ngx_http_spdy_state_complete(sc, pos, end);
+    }
+
+    size = end - pos;
+
+    if (size == 0) {
+        return ngx_http_spdy_state_save(sc, pos, end,
+                                        ngx_http_spdy_state_headers_skip);
+    }
+
+    sc->zstream_in.next_in = pos;
+    sc->zstream_in.avail_in = (size < sc->length) ? size : sc->length;
+
+    while (sc->zstream_in.avail_in) {
+        sc->zstream_in.next_out = buffer;
+        sc->zstream_in.avail_out = NGX_SPDY_SKIP_HEADERS_BUFFER_SIZE;
+
+        n = inflate(&sc->zstream_in, Z_NO_FLUSH);
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                       "spdy inflate(): %d", n);
+
+        if (n != Z_OK) {
+            /* TODO: logging */
+            return ngx_http_spdy_state_protocol_error(sc);
+        }
+    }
+
+    pos = sc->zstream_in.next_in;
+
+    if (size < sc->length) {
+        sc->length -= size;
+        return ngx_http_spdy_state_save(sc, pos, end,
+                                        ngx_http_spdy_state_headers_skip);
+    }
+
+    return ngx_http_spdy_state_complete(sc, pos, end);
+}
+
+
+static u_char *
+ngx_http_spdy_state_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;
+    ngx_http_request_body_t   *rb;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    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 */
+        return ngx_http_spdy_state_skip(sc, pos, end);
+    }
+
+    size = end - pos;
+
+    if (size >= sc->length) {
+        size = sc->length;
+        complete = 1;
+
+    } else {
+        sc->length -= size;
+        complete = 0;
+    }
+
+    r = stream->request;
+
+    if (r->request_body == NULL
+        && ngx_http_spdy_init_request_body(r) != NGX_OK)
+    {
+        stream->skip_data = NGX_SPDY_DATA_INTERNAL_ERROR;
+        return ngx_http_spdy_state_skip(sc, pos, end);
+    }
+
+    rb = r->request_body;
+    tf = rb->temp_file;
+    buf = rb->buf;
+
+    if (size) {
+        rb->rest += size;
+
+        if (r->headers_in.content_length_n != -1
+            && r->headers_in.content_length_n < rb->rest)
+        {
+            /* TODO logging */
+            stream->skip_data = NGX_SPDY_DATA_ERROR;
+            goto error;
+
+        } else {
+            clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+            if (clcf->client_max_body_size
+                && clcf->client_max_body_size < rb->rest)
+            {
+                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                              "client intended to send too large chunked "
+                              "body: %O bytes",
+                              rb->rest);
+
+                stream->skip_data = NGX_SPDY_DATA_ERROR;
+                goto error;
+            }
+        }
+
+        if (tf) {
+            buf->start = pos;
+            buf->pos = pos;
+
+            pos += size;
+
+            buf->end = pos;
+            buf->last = pos;
+
+            n = ngx_write_chain_to_temp_file(tf, rb->bufs);
+
+            /* TODO: n == 0 or not complete and level event */
+
+            if (n == NGX_ERROR) {
+                stream->skip_data = NGX_SPDY_DATA_INTERNAL_ERROR;
+                goto error;
+            }
+
+            tf->offset += n;
+
+        } else {
+            buf->last = ngx_cpymem(buf->last, pos, size);
+            pos += size;
+        }
+
+        r->request_length += size;
+    }
+
+    if (!complete) {
+        return ngx_http_spdy_state_save(sc, pos, end,
+                                        ngx_http_spdy_state_data);
+    }
+
+    if (sc->flags & NGX_SPDY_FLAG_FIN) {
+
+        stream->in_closed = 1;
+
+        if (tf) {
+            ngx_memzero(buf, sizeof(ngx_buf_t));
+
+            buf->in_file = 1;
+            buf->file_last = tf->file.offset;
+            buf->file = &tf->file;
+
+            rb->buf = NULL;
+        }
+
+        if (r->headers_in.content_length_n < 0) {
+            r->headers_in.content_length_n = rb->rest;
+        }
+
+        if (rb->post_handler) {
+            rb->post_handler(r);
+        }
+    }
+
+    return ngx_http_spdy_state_complete(sc, pos, end);
+
+error:
+
+    if (rb->post_handler) {
+
+        if (stream->skip_data == NGX_SPDY_DATA_ERROR) {
+            rc = (r->headers_in.content_length_n == -1)
+                 ? NGX_HTTP_REQUEST_ENTITY_TOO_LARGE
+                 : NGX_HTTP_BAD_REQUEST;
+
+        } else {
+            rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
+
+        ngx_http_finalize_request(r, rc);
+    }
+
+    return ngx_http_spdy_state_skip(sc, pos, end);
+}
+
+
+static u_char *
+ngx_http_spdy_state_rst_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
+    u_char *end)
+{
+    ngx_uint_t               sid, status;
+    ngx_event_t             *ev;
+    ngx_connection_t        *fc;
+    ngx_http_request_t      *r;
+    ngx_http_spdy_stream_t  *stream;
+
+    if (end - pos < NGX_SPDY_RST_STREAM_SIZE) {
+        return ngx_http_spdy_state_save(sc, pos, end,
+                                        ngx_http_spdy_state_rst_stream);
+    }
+
+    if (sc->length != NGX_SPDY_RST_STREAM_SIZE) {
+        /* TODO logging */
+        return ngx_http_spdy_state_protocol_error(sc);
+    }
+
+    sid = ngx_spdy_frame_parse_sid(pos);
+
+    pos += NGX_SPDY_SID_SIZE;
+
+    status = ngx_spdy_frame_parse_uint32(pos);
+
+    pos += sizeof(uint32_t);
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy RST_STREAM sid:%ui st:%ui", sid, status);
+
+
+    switch (status) {
+
+    case NGX_SPDY_PROTOCOL_ERROR:
+        /* TODO logging */
+        return ngx_http_spdy_state_protocol_error(sc);
+
+    case NGX_SPDY_INVALID_STREAM:
+        /* TODO */
+        break;
+
+    case NGX_SPDY_REFUSED_STREAM:
+        /* TODO */
+        break;
+
+    case NGX_SPDY_UNSUPPORTED_VERSION:
+        /* TODO logging */
+        return ngx_http_spdy_state_protocol_error(sc);
+
+    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);
+
+        break;
+
+    case NGX_SPDY_FLOW_CONTROL_ERROR:
+        /* TODO logging */
+        return ngx_http_spdy_state_protocol_error(sc);
+
+    default:
+        /* TODO */
+        return ngx_http_spdy_state_protocol_error(sc);
+    }
+
+    return ngx_http_spdy_state_complete(sc, pos, end);
+}
+
+
+static u_char *
+ngx_http_spdy_state_ping(ngx_http_spdy_connection_t *sc, u_char *pos,
+    u_char *end)
+{
+    u_char                     *p;
+    ngx_buf_t                  *buf;
+    ngx_http_spdy_out_frame_t  *frame;
+
+    if (end - pos < NGX_SPDY_PING_SIZE) {
+        return ngx_http_spdy_state_save(sc, pos, end,
+                                        ngx_http_spdy_state_ping);
+    }
+
+    if (sc->length != NGX_SPDY_PING_SIZE) {
+        /* TODO logging */
+        return ngx_http_spdy_state_protocol_error(sc);
+    }
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy PING frame");
+
+    frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_PING_SIZE,
+                                        NGX_SPDY_HIGHEST_PRIORITY);
+    if (frame == NULL) {
+        return ngx_http_spdy_state_internal_error(sc);
+    }
+
+    buf = frame->first->buf;
+
+    p = buf->pos;
+
+    p = ngx_spdy_frame_write_head(p, NGX_SPDY_PING);
+    p = ngx_spdy_frame_write_flags_and_len(p, 0, NGX_SPDY_PING_SIZE);
+
+    p = ngx_cpymem(p, pos, NGX_SPDY_PING_SIZE);
+
+    buf->last = p;
+
+    ngx_http_spdy_queue_frame(sc, frame);
+
+    pos += NGX_SPDY_PING_SIZE;
+
+    return ngx_http_spdy_state_complete(sc, pos, end);
+}
+
+
+static u_char *
+ngx_http_spdy_state_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
+    u_char *end)
+{
+    size_t  size;
+
+    size = end - pos;
+
+    if (size < sc->length) {
+        sc->length -= size;
+        return ngx_http_spdy_state_save(sc, end, end,
+                                        ngx_http_spdy_state_skip);
+    }
+
+    return ngx_http_spdy_state_complete(sc, pos + sc->length, end);
+}
+
+
+static u_char *
+ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc, u_char *pos,
+    u_char *end)
+{
+    ngx_uint_t                 v;
+    ngx_http_spdy_srv_conf_t  *sscf;
+
+    if (sc->headers == 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);
+
+        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 */
+            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);
+    }
+
+    while (sc->headers) {
+        if (end - pos < NGX_SPDY_SETTINGS_PAIR_SIZE) {
+            return ngx_http_spdy_state_save(sc, pos, end,
+                                            ngx_http_spdy_state_settings);
+        }
+
+        sc->headers--;
+
+        if (pos[0] != NGX_SPDY_SETTINGS_MAX_STREAMS) {
+            pos += NGX_SPDY_SETTINGS_PAIR_SIZE;
+            sc->length -= NGX_SPDY_SETTINGS_PAIR_SIZE;
+            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);
+
+        if (v != sscf->concurrent_streams) {
+            ngx_http_spdy_send_settings(sc);
+        }
+
+        return ngx_http_spdy_state_skip(sc, pos, end);
+    }
+
+    ngx_http_spdy_send_settings(sc);
+
+    return ngx_http_spdy_state_complete(sc, pos, end);
+}
+
+
+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);
+    }
+
+    return ngx_http_spdy_state_complete(sc, pos, end);
+}
+
+
+static u_char *
+ngx_http_spdy_state_complete(ngx_http_spdy_connection_t *sc, u_char *pos,
+    u_char *end)
+{
+    sc->handler = ngx_http_spdy_state_head;
+    return pos;
+}
+
+
+static u_char *
+ngx_http_spdy_state_save(ngx_http_spdy_connection_t *sc,
+    u_char *pos, u_char *end, ngx_http_spdy_handler_pt handler)
+{
+#if (NGX_DEBUG)
+    if (end - pos > NGX_SPDY_STATE_BUFFER_SIZE) {
+        ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
+                      "spdy state buffer overflow: "
+                      "%i bytes required", end - pos);
+        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->handler = handler;
+    sc->waiting = 1;
+
+    return end;
+}
+
+
+static u_char *
+ngx_http_spdy_state_protocol_error(ngx_http_spdy_connection_t *sc)
+{
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy state protocol error");
+
+    /* TODO */
+    ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
+    return NULL;
+}
+
+
+static u_char *
+ngx_http_spdy_state_internal_error(ngx_http_spdy_connection_t *sc)
+{
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy state internal error");
+
+    /* TODO */
+    ngx_http_spdy_finalize_connection(sc, NGX_HTTP_INTERNAL_SERVER_ERROR);
+    return NULL;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_send_rst_stream(ngx_http_spdy_connection_t *sc, ngx_uint_t sid,
+    ngx_uint_t status, ngx_uint_t priority)
+{
+    u_char                     *p;
+    ngx_buf_t                  *buf;
+    ngx_http_spdy_out_frame_t  *frame;
+
+    if (sc->connection->error) {
+        return NGX_OK;
+    }
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy write RST_STREAM sid:%ui st:%ui", sid, status);
+
+    frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_RST_STREAM_SIZE,
+                                        priority);
+    if (frame == NULL) {
+        return NGX_ERROR;
+    }
+
+    buf = frame->first->buf;
+
+    p = buf->pos;
+
+    p = ngx_spdy_frame_write_head(p, NGX_SPDY_RST_STREAM);
+    p = ngx_spdy_frame_write_flags_and_len(p, 0, NGX_SPDY_RST_STREAM_SIZE);
+
+    p = ngx_spdy_frame_write_sid(p, sid);
+    p = ngx_spdy_frame_aligned_write_uint32(p, status);
+
+    buf->last = p;
+
+    ngx_http_spdy_queue_frame(sc, frame);
+
+    return NGX_OK;
+}
+
+
+#if 0
+static ngx_int_t
+ngx_http_spdy_send_goaway(ngx_http_spdy_connection_t *sc)
+{
+    u_char                     *p;
+    ngx_buf_t                  *buf;
+    ngx_http_spdy_out_frame_t  *frame;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy create GOAWAY sid:%ui", sc->last_sid);
+
+    frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_GOAWAY_SIZE,
+                                        NGX_SPDY_HIGHEST_PRIORITY);
+    if (frame == NULL) {
+        return NGX_ERROR;
+    }
+
+    buf = frame->first->buf;
+
+    p = buf->pos;
+
+    p = ngx_spdy_frame_write_head(p, NGX_SPDY_GOAWAY);
+    p = ngx_spdy_frame_write_flags_and_len(p, 0, NGX_SPDY_GOAWAY_SIZE);
+
+    p = ngx_spdy_frame_write_sid(p, sc->last_sid);
+
+    buf->last = p;
+
+    ngx_http_spdy_queue_frame(sc, frame);
+
+    return NGX_OK;
+}
+#endif
+
+
+static ngx_int_t
+ngx_http_spdy_send_settings(ngx_http_spdy_connection_t *sc)
+{
+    u_char                     *p;
+    ngx_buf_t                  *buf;
+    ngx_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");
+
+    pool = sc->connection->pool;
+
+    frame = ngx_palloc(pool, sizeof(ngx_http_spdy_out_frame_t));
+    if (frame == NULL) {
+        return NGX_ERROR;
+    }
+
+    cl = ngx_alloc_chain_link(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);
+    if (buf == NULL) {
+        return NGX_ERROR;
+    }
+
+    buf->last_buf = 1;
+
+    cl->buf = buf;
+    cl->next = NULL;
+
+    frame->first = cl;
+    frame->last = cl;
+    frame->handler = ngx_http_spdy_settings_frame_handler;
+#if (NGX_DEBUG)
+    frame->stream = NULL;
+    frame->size = NGX_SPDY_FRAME_HEADER_SIZE
+                  + NGX_SPDY_SETTINGS_NUM_SIZE
+                  + NGX_SPDY_SETTINGS_PAIR_SIZE;
+#endif
+    frame->priority = NGX_SPDY_HIGHEST_PRIORITY;
+    frame->blocked = 0;
+
+    p = buf->pos;
+
+    p = ngx_spdy_frame_write_head(p, NGX_SPDY_SETTINGS);
+    p = ngx_spdy_frame_write_flags_and_len(p, NGX_SPDY_FLAG_CLEAR_SETTINGS,
+                                              NGX_SPDY_SETTINGS_NUM_SIZE
+                                              + 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);
+
+    sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
+                                        ngx_http_spdy_module);
+
+    p = ngx_spdy_frame_aligned_write_uint32(p, sscf->concurrent_streams);
+
+    buf->last = p;
+
+    ngx_http_spdy_queue_frame(sc, frame);
+
+    return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_http_spdy_settings_frame_handler(ngx_http_spdy_connection_t *sc,
+    ngx_http_spdy_out_frame_t *frame)
+{
+    ngx_buf_t  *buf;
+
+    buf = frame->first->buf;
+
+    if (buf->pos != buf->last) {
+        return NGX_AGAIN;
+    }
+
+    ngx_free_chain(sc->pool, frame->first);
+
+    return NGX_OK;
+}
+
+
+static ngx_http_spdy_out_frame_t *
+ngx_http_spdy_get_ctl_frame(ngx_http_spdy_connection_t *sc, size_t size,
+    ngx_uint_t priority)
+{
+    ngx_chain_t                *cl;
+    ngx_http_spdy_out_frame_t  *frame;
+
+    frame = sc->free_ctl_frames;
+
+    if (frame) {
+        sc->free_ctl_frames = frame->free;
+
+        cl = frame->first;
+        cl->buf->pos = cl->buf->start;
+
+    } else {
+        frame = ngx_palloc(sc->pool, sizeof(ngx_http_spdy_out_frame_t));
+        if (frame == NULL) {
+            return NULL;
+        }
+
+        cl = ngx_alloc_chain_link(sc->pool);
+        if (cl == NULL) {
+            return NULL;
+        }
+
+        cl->buf = ngx_create_temp_buf(sc->pool,
+                                      NGX_SPDY_CTL_FRAME_BUFFER_SIZE);
+        if (cl->buf == NULL) {
+            return NULL;
+        }
+
+        cl->buf->last_buf = 1;
+
+        frame->first = cl;
+        frame->last = cl;
+        frame->handler = ngx_http_spdy_ctl_frame_handler;
+    }
+
+    frame->free = NULL;
+
+#if (NGX_DEBUG)
+    if (size > 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);
+        return NULL;
+    }
+
+    frame->stream = NULL;
+    frame->size = size;
+#endif
+
+    frame->priority = priority;
+    frame->blocked = 0;
+
+    return frame;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_ctl_frame_handler(ngx_http_spdy_connection_t *sc,
+    ngx_http_spdy_out_frame_t *frame)
+{
+    ngx_buf_t  *buf;
+
+    buf = frame->first->buf;
+
+    if (buf->pos != buf->last) {
+        return NGX_AGAIN;
+    }
+
+    frame->free = sc->free_ctl_frames;
+    sc->free_ctl_frames = frame;
+
+    return NGX_OK;
+}
+
+
+static ngx_http_spdy_stream_t *
+ngx_http_spdy_create_stream(ngx_http_spdy_connection_t *sc, ngx_uint_t id,
+    ngx_uint_t priority)
+{
+    ngx_log_t                 *log;
+    ngx_uint_t                 index;
+    ngx_event_t               *rev, *wev;
+    ngx_connection_t          *fc;
+    ngx_http_log_ctx_t        *ctx;
+    ngx_http_request_t        *r;
+    ngx_http_spdy_stream_t    *stream;
+    ngx_http_core_srv_conf_t  *cscf;
+    ngx_http_spdy_srv_conf_t  *sscf;
+
+    fc = sc->free_fake_connections;
+
+    if (fc) {
+        sc->free_fake_connections = fc->data;
+
+        rev = fc->read;
+        wev = fc->write;
+        log = fc->log;
+        ctx = log->data;
+
+    } else {
+        fc = ngx_palloc(sc->pool, sizeof(ngx_connection_t));
+        if (fc == NULL) {
+            return NULL;
+        }
+
+        rev = ngx_palloc(sc->pool, sizeof(ngx_event_t));
+        if (rev == NULL) {
+            return NULL;
+        }
+
+        wev = ngx_palloc(sc->pool, sizeof(ngx_event_t));
+        if (wev == NULL) {
+            return NULL;
+        }
+
+        log = ngx_palloc(sc->pool, sizeof(ngx_log_t));
+        if (log == NULL) {
+            return NULL;
+        }
+
+        ctx = ngx_palloc(sc->pool, sizeof(ngx_http_log_ctx_t));
+        if (ctx == NULL) {
+            return NULL;
+        }
+
+        ctx->connection = fc;
+        ctx->request = NULL;
+    }
+
+    ngx_memcpy(log, sc->connection->log, sizeof(ngx_log_t));
+
+    log->data = ctx;
+
+    ngx_memzero(rev, sizeof(ngx_event_t));
+
+    rev->data = fc;
+    rev->ready = 1;
+    rev->handler = ngx_http_empty_handler;
+    rev->log = log;
+
+    ngx_memcpy(wev, rev, sizeof(ngx_event_t));
+
+    wev->write = 1;
+
+    ngx_memcpy(fc, sc->connection, sizeof(ngx_connection_t));
+
+    fc->data = sc->http_connection;
+    fc->read = rev;
+    fc->write = wev;
+    fc->sent = 0;
+    fc->log = log;
+    fc->buffered = 0;
+    fc->sndlowat = 1;
+    fc->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
+
+    r = ngx_http_create_request(fc);
+    if (r == NULL) {
+        return NULL;
+    }
+
+    r->valid_location = 1;
+
+    fc->data = r;
+    sc->connection->requests++;
+
+    cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+    r->header_in = ngx_create_temp_buf(r->pool,
+                                       cscf->client_header_buffer_size);
+    if (r->header_in == NULL) {
+        ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return NULL;
+    }
+
+    r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
+
+    stream = ngx_pcalloc(r->pool, sizeof(ngx_http_spdy_stream_t));
+    if (stream == NULL) {
+        ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return NULL;
+    }
+
+    r->spdy_stream = stream;
+
+    stream->id = id;
+    stream->request = r;
+    stream->connection = sc;
+    stream->priority = priority;
+
+    sscf = ngx_http_get_module_srv_conf(r, ngx_http_spdy_module);
+
+    index = ngx_http_spdy_stream_index(sscf, id);
+
+    stream->index = sc->streams_index[index];
+    sc->streams_index[index] = stream;
+
+    sc->processing++;
+
+    return stream;
+}
+
+
+static ngx_http_spdy_stream_t *
+ngx_http_spdy_get_stream_by_id(ngx_http_spdy_connection_t *sc,
+    ngx_uint_t sid)
+{
+    ngx_http_spdy_stream_t    *stream;
+    ngx_http_spdy_srv_conf_t  *sscf;
+
+    sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
+                                        ngx_http_spdy_module);
+
+    stream = sc->streams_index[ngx_http_spdy_stream_index(sscf, sid)];
+
+    while (stream) {
+        if (stream->id == sid) {
+            return stream;
+        }
+
+        stream = stream->index;
+    }
+
+    return NULL;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_parse_header(ngx_http_request_t *r)
+{
+    u_char                     *p, *end, ch;
+    ngx_uint_t                  len, hash;
+    ngx_http_core_srv_conf_t   *cscf;
+
+    enum {
+        sw_name_len = 0,
+        sw_name,
+        sw_value_len,
+        sw_value
+    } state;
+
+    state = r->state;
+
+    p = r->header_in->pos;
+    end = r->header_in->last;
+
+    switch (state) {
+
+    case sw_name_len:
+
+        if (end - p < NGX_SPDY_NV_NLEN_SIZE) {
+            return NGX_AGAIN;
+        }
+
+        len = ngx_spdy_frame_parse_uint16(p);
+
+        if (!len) {
+            return NGX_HTTP_PARSE_INVALID_HEADER;
+        }
+
+        p += NGX_SPDY_NV_NLEN_SIZE;
+
+        r->header_name_end = p + len;
+        r->lowcase_index = len;
+        r->invalid_header = 0;
+
+        state = sw_name;
+
+        /* fall through */
+
+    case sw_name:
+
+        if (r->header_name_end > end) {
+            break;
+        }
+
+        cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+        r->header_name_start = p;
+
+        hash = 0;
+
+        for ( /* void */ ; p != r->header_name_end; p++) {
+
+            ch = *p;
+
+            hash = ngx_hash(hash, ch);
+
+            if ((ch >= 'a' && ch <= 'z')
+                || (ch == '-')
+                || (ch >= '0' && ch <= '9')
+                || (ch == '_' && cscf->underscores_in_headers))
+            {
+                continue;
+            }
+
+            switch (ch) {
+            case '\0':
+            case LF:
+            case CR:
+            case ':':
+                return NGX_HTTP_PARSE_INVALID_REQUEST;
+            }
+
+            if (ch >= 'A' && ch <= 'Z') {
+                return NGX_HTTP_PARSE_INVALID_HEADER;
+            }
+
+            r->invalid_header = 1;
+        }
+
+        r->header_hash = hash;
+
+        state = sw_value_len;
+
+        /* fall through */
+
+    case sw_value_len:
+
+        if (end - p < NGX_SPDY_NV_VLEN_SIZE) {
+            break;
+        }
+
+        len = ngx_spdy_frame_parse_uint16(p);
+
+        if (!len) {
+            return NGX_ERROR;
+        }
+
+        p += NGX_SPDY_NV_VLEN_SIZE;
+
+        r->header_end = p + len;
+
+        state = sw_value;
+
+        /* fall through */
+
+    case sw_value:
+
+        if (r->header_end > end) {
+            break;
+        }
+
+        r->header_start = p;
+
+        for ( /* void */ ; p != r->header_end; p++) {
+
+            ch = *p;
+
+            if (ch == '\0') {
+
+                if (p == r->header_start) {
+                    return NGX_ERROR;
+                }
+
+                r->header_size = p - r->header_start;
+                r->header_in->pos = p + 1;
+
+                return NGX_OK;
+            }
+
+            if (ch == CR || ch == LF) {
+                return NGX_HTTP_PARSE_INVALID_HEADER;
+            }
+        }
+
+        r->header_size = p - r->header_start;
+        r->header_in->pos = p;
+
+        r->state = 0;
+
+        return NGX_DONE;
+    }
+
+    r->header_in->pos = p;
+    r->state = state;
+
+    return NGX_AGAIN;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_alloc_large_header_buffer(ngx_http_request_t *r)
+{
+    u_char                    *old, *new;
+    size_t                     rest;
+    ngx_buf_t                 *buf;
+    ngx_http_spdy_stream_t    *stream;
+    ngx_http_core_srv_conf_t  *cscf;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "spdy alloc large header buffer");
+
+    stream = r->spdy_stream;
+
+    cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+    if (stream->header_buffers
+        == (ngx_uint_t) cscf->large_client_header_buffers.num)
+    {
+        return NGX_DECLINED;
+    }
+
+    rest = r->header_in->last - r->header_in->pos;
+
+    if (rest >= cscf->large_client_header_buffers.size) {
+        return NGX_DECLINED;
+    }
+
+    buf = ngx_create_temp_buf(r->pool, cscf->large_client_header_buffers.size);
+    if (buf == NULL) {
+        return NGX_ERROR;
+    }
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "spdy large header alloc: %p %uz",
+                   buf->pos, buf->end - buf->last);
+
+    old = r->header_in->pos;
+    new = buf->pos;
+
+    if (rest) {
+        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++;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_handle_request_header(ngx_http_request_t *r)
+{
+    ngx_uint_t                       i;
+    ngx_table_elt_t                 *h;
+    ngx_http_core_srv_conf_t        *cscf;
+    ngx_http_spdy_request_header_t  *sh;
+
+    if (r->invalid_header) {
+        cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+        if (cscf->ignore_invalid_headers) {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent invalid header: \"%*s\"",
+                          r->header_end - r->header_name_start,
+                          r->header_name_start);
+            return NGX_OK;
+        }
+
+    } else {
+        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)
+            {
+                continue;
+            }
+
+            return sh->handler(r);
+        }
+    }
+
+    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.data = r->header_name_start;
+    h->key.data[h->key.len] = '\0';
+
+    h->value.len = r->header_size;
+    h->value.data = r->header_start;
+    h->value.data[h->value.len] = '\0';
+
+    h->lowcase_key = h->key.data;
+
+    return NGX_OK;
+}
+
+
+void
+ngx_http_spdy_request_headers_init()
+{
+    ngx_uint_t                       i;
+    ngx_http_spdy_request_header_t  *h;
+
+    for (i = 0; i < NGX_SPDY_REQUEST_HEADERS; i++) {
+        h = &ngx_http_spdy_request_headers[i];
+        h->hash = ngx_hash_key(h->header, h->len);
+    }
+}
+
+
+static ngx_int_t
+ngx_http_spdy_parse_method(ngx_http_request_t *r)
+{
+    size_t         k, len;
+    ngx_uint_t     n;
+    const u_char  *p, *m;
+
+    /*
+     * This array takes less than 256 sequential bytes,
+     * and if typical CPU cache line size is 64 bytes,
+     * it is prefetched for 4 load operations.
+     */
+    static const struct {
+        u_char            len;
+        const u_char      method[11];
+        uint32_t          value;
+    } tests[] = {
+        { 3, "GET",       NGX_HTTP_GET },
+        { 4, "POST",      NGX_HTTP_POST },
+        { 4, "HEAD",      NGX_HTTP_HEAD },
+        { 7, "OPTIONS",   NGX_HTTP_OPTIONS },
+        { 8, "PROPFIND",  NGX_HTTP_PROPFIND },
+        { 3, "PUT",       NGX_HTTP_PUT },
+        { 5, "MKCOL",     NGX_HTTP_MKCOL },
+        { 6, "DELETE",    NGX_HTTP_DELETE },
+        { 4, "COPY",      NGX_HTTP_COPY },
+        { 4, "MOVE",      NGX_HTTP_MOVE },
+        { 9, "PROPPATCH", NGX_HTTP_PROPPATCH },
+        { 4, "LOCK",      NGX_HTTP_LOCK },
+        { 6, "UNLOCK",    NGX_HTTP_UNLOCK },
+        { 5, "PATCH",     NGX_HTTP_PATCH },
+        { 5, "TRACE",     NGX_HTTP_TRACE }
+    }, *test;
+
+    if (r->method_name.len) {
+        return NGX_HTTP_PARSE_INVALID_HEADER;
+    }
+
+    len = r->header_size;
+
+    r->method_name.len = len;
+    r->method_name.data = r->header_start;
+
+    test = tests;
+    n = sizeof(tests) / sizeof(tests[0]);
+
+    do {
+        if (len == test->len) {
+            p = r->method_name.data;
+            m = test->method;
+            k = len;
+
+            do {
+                if (*p++ != *m++) {
+                    goto next;
+                }
+            } while (--k);
+
+            r->method = test->value;
+            return NGX_OK;
+        }
+
+    next:
+        test++;
+
+    } while (--n);
+
+    p = r->method_name.data;
+
+    do {
+        if ((*p < 'A' || *p > 'Z') && *p != '_') {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent invalid method");
+            return NGX_HTTP_PARSE_INVALID_REQUEST;
+        }
+
+        p++;
+
+    } while (--len);
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_parse_scheme(ngx_http_request_t *r)
+{
+    if (r->schema_start) {
+        return NGX_HTTP_PARSE_INVALID_HEADER;
+    }
+
+    r->schema_start = r->header_start;
+    r->schema_end = r->header_end;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_parse_url(ngx_http_request_t *r)
+{
+    if (r->unparsed_uri.len) {
+        return NGX_HTTP_PARSE_INVALID_HEADER;
+    }
+
+    r->uri_start = r->header_start;
+    r->uri_end = r->header_end;
+
+    if (ngx_http_parse_uri(r) != NGX_OK) {
+        return NGX_HTTP_PARSE_INVALID_REQUEST;
+    }
+
+    if (ngx_http_process_request_uri(r) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_parse_version(ngx_http_request_t *r)
+{
+    u_char  *p, ch;
+
+    if (r->http_protocol.len) {
+        return NGX_HTTP_PARSE_INVALID_HEADER;
+    }
+
+    p = r->header_start;
+
+    if (r->header_size < 8 || !(ngx_str5cmp(p, 'H', 'T', 'T', 'P', '/'))) {
+        return NGX_HTTP_PARSE_INVALID_REQUEST;
+    }
+
+    ch = *(p + 5);
+
+    if (ch < '1' || ch > '9') {
+        return NGX_HTTP_PARSE_INVALID_REQUEST;
+    }
+
+    r->http_major = ch - '0';
+
+    for (p += 6; p != r->header_end - 2; p++) {
+
+        ch = *p;
+
+        if (ch < '0' || ch > '9') {
+            return NGX_HTTP_PARSE_INVALID_REQUEST;
+        }
+
+        r->http_major = r->http_major * 10 + ch - '0';
+    }
+
+    if (*p != '.') {
+        return NGX_HTTP_PARSE_INVALID_REQUEST;
+    }
+
+    ch = *(p + 1);
+
+    if (ch < '0' || ch > '9') {
+        return NGX_HTTP_PARSE_INVALID_REQUEST;
+    }
+
+    r->http_minor = ch - '0';
+
+    for (p += 2; p != r->header_end; p++) {
+
+        ch = *p;
+
+        if (ch < '0' || ch > '9') {
+            return NGX_HTTP_PARSE_INVALID_REQUEST;
+        }
+
+        r->http_minor = r->http_minor * 10 + ch - '0';
+    }
+
+    r->http_protocol.len = r->header_size;
+    r->http_protocol.data = r->header_start;
+    r->http_version = r->http_major * 1000 + r->http_minor;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_construct_request_line(ngx_http_request_t *r)
+{
+    u_char  *p;
+
+    if (r->method_name.len == 0
+        || r->unparsed_uri.len == 0
+        || r->http_protocol.len == 0)
+    {
+        ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+        return NGX_ERROR;
+    }
+
+    r->request_line.len = r->method_name.len + 1
+                          + r->unparsed_uri.len + 1
+                          + r->http_protocol.len;
+
+    p = ngx_pnalloc(r->pool, r->request_line.len + 1);
+    if (p == NULL) {
+        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return NGX_ERROR;
+    }
+
+    r->request_line.data = p;
+
+    p = ngx_cpymem(p, r->method_name.data, r->method_name.len);
+
+    *p++ = ' ';
+
+    p = ngx_cpymem(p, r->unparsed_uri.data, r->unparsed_uri.len);
+
+    *p++ = ' ';
+
+    ngx_memcpy(p, r->http_protocol.data, r->http_protocol.len + 1);
+
+    /* some modules expect the space character after method name */
+    r->method_name.data = r->request_line.data;
+
+    return NGX_OK;
+}
+
+
+static void
+ngx_http_spdy_run_request(ngx_http_request_t *r)
+{
+    ngx_uint_t                  i;
+    ngx_list_part_t            *part;
+    ngx_table_elt_t            *h;
+    ngx_http_header_t          *hh;
+    ngx_http_core_main_conf_t  *cmcf;
+
+    if (ngx_http_spdy_construct_request_line(r) != NGX_OK) {
+        return;
+    }
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "spdy http request line: \"%V\"", &r->request_line);
+
+    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+
+    part = &r->headers_in.headers.part;
+    h = part->elts;
+
+    for (i = 0 ;; i++) {
+
+        if (i >= part->nelts) {
+            if (part->next == NULL) {
+                break;
+            }
+
+            part = part->next;
+            h = part->elts;
+            i = 0;
+        }
+
+        hh = ngx_hash_find(&cmcf->headers_in_hash, h[i].hash,
+                           h[i].lowcase_key, h[i].key.len);
+
+        if (hh && hh->handler(r, &h[i], hh->offset) != NGX_OK) {
+            return;
+        }
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "http header: \"%V: %V\"", &h[i].key, &h[i].value);
+    }
+
+    r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
+
+    if (ngx_http_process_request_header(r) != NGX_OK) {
+        return;
+    }
+
+    ngx_http_process_request(r);
+}
+
+
+static ngx_int_t
+ngx_http_spdy_init_request_body(ngx_http_request_t *r)
+{
+    ngx_buf_t                 *buf;
+    ngx_temp_file_t           *tf;
+    ngx_http_request_body_t   *rb;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
+    if (rb == NULL) {
+        return NGX_ERROR;
+    }
+
+    r->request_body = rb;
+
+    if (r->spdy_stream->in_closed) {
+        return NGX_OK;
+    }
+
+    rb->rest = r->headers_in.content_length_n;
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    if (r->request_body_in_file_only
+        || rb->rest > (off_t) clcf->client_body_buffer_size
+        || rb->rest < 0)
+    {
+        tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
+        if (tf == NULL) {
+            return NGX_ERROR;
+        }
+
+        tf->file.fd = NGX_INVALID_FILE;
+        tf->file.log = r->connection->log;
+        tf->path = clcf->client_body_temp_path;
+        tf->pool = r->pool;
+        tf->warn = "a client request body is buffered to a temporary file";
+        tf->log_level = r->request_body_file_log_level;
+        tf->persistent = r->request_body_in_persistent_file;
+        tf->clean = r->request_body_in_clean_file;
+
+        if (r->request_body_file_group_access) {
+            tf->access = 0660;
+        }
+
+        rb->temp_file = tf;
+
+        if (r->spdy_stream->in_closed
+            && ngx_create_temp_file(&tf->file, tf->path, tf->pool,
+                                    tf->persistent, tf->clean, tf->access)
+               != NGX_OK)
+        {
+            return NGX_ERROR;
+        }
+
+        buf = ngx_calloc_buf(r->pool);
+        if (buf == NULL) {
+            return NGX_ERROR;
+        }
+
+        if (rb->rest == 0) {
+            buf->in_file = 1;
+            buf->file = &tf->file;
+        } else {
+            rb->buf = buf;
+        }
+
+    } else {
+
+        if (rb->rest == 0) {
+            return NGX_OK;
+        }
+
+        buf = ngx_create_temp_buf(r->pool, (size_t) rb->rest);
+        if (buf == NULL) {
+            return NGX_ERROR;
+        }
+
+        rb->buf = buf;
+    }
+
+    rb->bufs = ngx_alloc_chain_link(r->pool);
+    if (rb->bufs == NULL) {
+        return NGX_ERROR;
+    }
+
+    rb->bufs->buf = buf;
+    rb->bufs->next = NULL;
+
+    rb->rest = 0;
+
+    return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_http_spdy_read_request_body(ngx_http_request_t *r,
+    ngx_http_client_body_handler_pt post_handler)
+{
+    ngx_http_spdy_stream_t  *stream;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "spdy read request body");
+
+    stream = r->spdy_stream;
+
+    switch (stream->skip_data) {
+
+    case NGX_SPDY_DATA_DISCARD:
+        post_handler(r);
+        return NGX_OK;
+
+    case NGX_SPDY_DATA_ERROR:
+        if (r->headers_in.content_length_n == -1) {
+            return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
+        } else {
+            return NGX_HTTP_BAD_REQUEST;
+        }
+
+    case NGX_SPDY_DATA_INTERNAL_ERROR:
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    if (!r->request_body && ngx_http_spdy_init_request_body(r) != NGX_OK) {
+        stream->skip_data = NGX_SPDY_DATA_INTERNAL_ERROR;
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    if (stream->in_closed) {
+        post_handler(r);
+        return NGX_OK;
+    }
+
+    r->request_body->post_handler = post_handler;
+
+    return NGX_AGAIN;
+}
+
+
+void
+ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
+{
+    ngx_event_t                  *ev;
+    ngx_connection_t             *fc;
+    ngx_http_spdy_stream_t      **index, *s;
+    ngx_http_spdy_srv_conf_t     *sscf;
+    ngx_http_spdy_connection_t   *sc;
+
+    sc = stream->connection;
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy close stream %ui, processing %ui",
+                   stream->id, sc->processing);
+
+    if (!stream->out_closed) {
+        if (ngx_http_spdy_send_rst_stream(sc, stream->id,
+                                          NGX_SPDY_INTERNAL_ERROR,
+                                          stream->priority)
+            != NGX_OK)
+        {
+            sc->connection->error = 1;
+        }
+    }
+
+    sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
+                                        ngx_http_spdy_module);
+
+    index = sc->streams_index + ngx_http_spdy_stream_index(sscf, stream->id);
+
+    for ( ;; ) {
+        s = *index;
+
+        if (s == NULL) {
+            break;
+        }
+
+        if (s == stream) {
+            *index = s->index;
+            break;
+        }
+
+        index = &s->index;
+    }
+
+    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);
+    }
+
+    if (ev->timer_set) {
+        ngx_del_timer(ev);
+    }
+
+    if (ev->prev) {
+        ngx_delete_posted_event(ev);
+    }
+
+    ev = fc->write;
+
+    if (ev->active || ev->disabled) {
+        ngx_del_event(ev, NGX_WRITE_EVENT, 0);
+    }
+
+    if (ev->timer_set) {
+        ngx_del_timer(ev);
+    }
+
+    if (ev->prev) {
+        ngx_delete_posted_event(ev);
+    }
+
+    fc->data = sc->free_fake_connections;
+    sc->free_fake_connections = fc;
+
+    sc->processing--;
+
+    if (sc->processing || sc->blocked) {
+        return;
+    }
+
+    ev = sc->connection->read;
+
+    ev->handler = ngx_http_spdy_handle_connection_handler;
+    ngx_post_event(ev, &ngx_posted_events);
+}
+
+
+static void
+ngx_http_spdy_handle_connection_handler(ngx_event_t *rev)
+{
+    ngx_connection_t  *c;
+
+    rev->handler = ngx_http_spdy_read_handler;
+
+    if (rev->ready) {
+        ngx_http_spdy_read_handler(rev);
+        return;
+    }
+
+    c = rev->data;
+
+    ngx_http_spdy_handle_connection(c->data);
+}
+
+
+static void
+ngx_http_spdy_keepalive_handler(ngx_event_t *rev)
+{
+    ngx_connection_t            *c;
+    ngx_http_spdy_srv_conf_t    *sscf;
+    ngx_http_spdy_connection_t  *sc;
+
+    c = rev->data;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy keepalive handler");
+
+    if (rev->timedout || c->close) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+#if (NGX_HAVE_KQUEUE)
+
+    if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
+        if (rev->pending_eof) {
+            c->log->handler = NULL;
+            ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
+                          "kevent() reported that client %V closed "
+                          "keepalive connection", &c->addr_text);
+#if (NGX_HTTP_SSL)
+            if (c->ssl) {
+                c->ssl->no_send_shutdown = 1;
+            }
+#endif
+            ngx_http_close_connection(c);
+            return;
+        }
+    }
+
+#endif
+
+    c->destroyed = 0;
+    c->idle = 0;
+    ngx_reusable_connection(c, 0);
+
+    sc = c->data;
+
+    sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
+                                        ngx_http_spdy_module);
+
+    sc->pool = ngx_create_pool(sscf->pool_size, sc->connection->log);
+    if (sc->pool == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    sc->streams_index = ngx_pcalloc(sc->pool,
+                                    ngx_http_spdy_streams_index_size(sscf)
+                                    * sizeof(ngx_http_spdy_stream_t *));
+    if (sc->streams_index == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    c->write->handler = ngx_http_spdy_write_handler;
+
+    rev->handler = ngx_http_spdy_read_handler;
+    ngx_http_spdy_read_handler(rev);
+}
+
+
+static void
+ngx_http_spdy_finalize_connection(ngx_http_spdy_connection_t *sc,
+    ngx_int_t rc)
+{
+    ngx_uint_t                 i, size;
+    ngx_event_t               *ev;
+    ngx_connection_t          *c, *fc;
+    ngx_http_request_t        *r;
+    ngx_http_spdy_stream_t    *stream;
+    ngx_http_spdy_srv_conf_t  *sscf;
+
+    c = sc->connection;
+
+    if (!sc->processing) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    c->error = 1;
+    c->read->handler = ngx_http_empty_handler;
+
+    sc->last_out = NULL;
+
+    sc->blocked = 1;
+
+    sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
+                                        ngx_http_spdy_module);
+
+    size = ngx_http_spdy_streams_index_size(sscf);
+
+    for (i = 0; i < size; i++) {
+        stream = sc->streams_index[i];
+
+        while (stream) {
+            r = stream->request;
+
+            fc = r->connection;
+            fc->error = 1;
+
+            if (stream->waiting) {
+                r->blocked -= stream->waiting;
+                stream->waiting = 0;
+                ev = fc->write;
+
+            } else {
+                ev = fc->read;
+            }
+
+            stream = stream->index;
+
+            ev->eof = 1;
+            ev->handler(ev);
+        }
+    }
+
+    sc->blocked = 0;
+
+    if (sc->processing) {
+        return;
+    }
+
+    ngx_http_close_connection(c);
+}
+
+
+static void
+ngx_http_spdy_pool_cleanup(void *data)
+{
+    ngx_http_spdy_connection_t  *sc = data;
+
+    if (sc->pool) {
+        ngx_destroy_pool(sc->pool);
+    }
+}
+
+
+static void *
+ngx_http_spdy_zalloc(void *opaque, u_int items, u_int size)
+{
+    ngx_http_spdy_connection_t *sc = opaque;
+
+    return ngx_palloc(sc->connection->pool, items * size);
+}
+
+
+static void
+ngx_http_spdy_zfree(void *opaque, void *address)
+{
+#if 0
+    ngx_http_spdy_connection_t *sc = opaque;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy zfree: %p", address);
+#endif
+}

  Added: vendor/nginx-1.4.2/src/http/ngx_http_spdy.h (+235 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.4.2/src/http/ngx_http_spdy.h    2013-07-22 13:32:39 +0900 (4294e3d)
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) Nginx, Inc.
+ * Copyright (C) Valentin V. Bartenev
+ */
+
+
+#ifndef _NGX_HTTP_SPDY_H_INCLUDED_
+#define _NGX_HTTP_SPDY_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+#include <zlib.h>
+
+
+#define NGX_SPDY_VERSION              2
+
+#ifdef TLSEXT_TYPE_next_proto_neg
+#define NGX_SPDY_NPN_ADVERTISE        "\x06spdy/2"
+#define NGX_SPDY_NPN_NEGOTIATED       "spdy/2"
+#endif
+
+#define NGX_SPDY_STATE_BUFFER_SIZE    16
+
+#define NGX_SPDY_CTL_BIT              1
+
+#define NGX_SPDY_SYN_STREAM           1
+#define NGX_SPDY_SYN_REPLY            2
+#define NGX_SPDY_RST_STREAM           3
+#define NGX_SPDY_SETTINGS             4
+#define NGX_SPDY_NOOP                 5
+#define NGX_SPDY_PING                 6
+#define NGX_SPDY_GOAWAY               7
+#define NGX_SPDY_HEADERS              8
+
+#define NGX_SPDY_FRAME_HEADER_SIZE    8
+
+#define NGX_SPDY_SID_SIZE             4
+
+#define NGX_SPDY_SYN_STREAM_SIZE      10
+#define NGX_SPDY_SYN_REPLY_SIZE       6
+#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_SETTINGS_NUM_SIZE    4
+#define NGX_SPDY_SETTINGS_IDF_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)
+
+#define NGX_SPDY_HIGHEST_PRIORITY     0
+#define NGX_SPDY_LOWEST_PRIORITY      3
+
+#define NGX_SPDY_FLAG_FIN             0x01
+#define NGX_SPDY_FLAG_UNIDIRECTIONAL  0x02
+#define NGX_SPDY_FLAG_CLEAR_SETTINGS  0x01
+
+#define NGX_SPDY_MAX_FRAME_SIZE       ((1 << 24) - 1)
+
+#define NGX_SPDY_DATA_DISCARD         1
+#define NGX_SPDY_DATA_ERROR           2
+#define NGX_SPDY_DATA_INTERNAL_ERROR  3
+
+
+typedef struct ngx_http_spdy_connection_s   ngx_http_spdy_connection_t;
+typedef struct ngx_http_spdy_out_frame_s    ngx_http_spdy_out_frame_t;
+
+
+typedef u_char *(*ngx_http_spdy_handler_pt) (ngx_http_spdy_connection_t *sc,
+    u_char *pos, u_char *end);
+
+struct ngx_http_spdy_connection_s {
+    ngx_connection_t                *connection;
+    ngx_http_connection_t           *http_connection;
+
+    ngx_uint_t                       processing;
+
+    u_char                           buffer[NGX_SPDY_STATE_BUFFER_SIZE];
+    size_t                           buffer_used;
+    ngx_http_spdy_handler_pt         handler;
+
+    z_stream                         zstream_in;
+    z_stream                         zstream_out;
+
+    ngx_pool_t                      *pool;
+
+    ngx_http_spdy_out_frame_t       *free_ctl_frames;
+    ngx_connection_t                *free_fake_connections;
+
+    ngx_http_spdy_stream_t         **streams_index;
+
+    ngx_http_spdy_out_frame_t       *last_out;
+    ngx_http_spdy_stream_t          *last_stream;
+
+    ngx_http_spdy_stream_t          *stream;
+
+    ngx_uint_t                       headers;
+    size_t                           length;
+    u_char                           flags;
+
+    ngx_uint_t                       last_sid;
+
+    unsigned                         blocked:2;
+    unsigned                         waiting:1; /* FIXME better name */
+};
+
+
+struct ngx_http_spdy_stream_s {
+    ngx_uint_t                       id;
+    ngx_http_request_t              *request;
+    ngx_http_spdy_connection_t      *connection;
+    ngx_http_spdy_stream_t          *index;
+    ngx_http_spdy_stream_t          *next;
+
+    ngx_uint_t                       header_buffers;
+    ngx_uint_t                       waiting;
+    ngx_http_spdy_out_frame_t       *free_frames;
+    ngx_chain_t                     *free_data_headers;
+
+    unsigned                         priority:2;
+    unsigned                         handled:1;
+    unsigned                         in_closed:1;
+    unsigned                         out_closed:1;
+    unsigned                         skip_data:2;
+};
+
+
+struct ngx_http_spdy_out_frame_s {
+    ngx_http_spdy_out_frame_t       *next;
+    ngx_chain_t                     *first;
+    ngx_chain_t                     *last;
+    ngx_int_t                      (*handler)(ngx_http_spdy_connection_t *sc,
+                                        ngx_http_spdy_out_frame_t *frame);
+
+    ngx_http_spdy_out_frame_t       *free;
+
+    ngx_http_spdy_stream_t          *stream;
+    size_t                           size;
+
+    ngx_uint_t                       priority;
+    unsigned                         blocked:1;
+    unsigned                         fin:1;
+};
+
+
+static ngx_inline void
+ngx_http_spdy_queue_frame(ngx_http_spdy_connection_t *sc,
+    ngx_http_spdy_out_frame_t *frame)
+{
+    ngx_http_spdy_out_frame_t  **out;
+
+    for (out = &sc->last_out; *out; out = &(*out)->next)
+    {
+        if (frame->priority >= (*out)->priority) {
+            break;
+        }
+    }
+
+    frame->next = *out;
+    *out = frame;
+}
+
+
+static ngx_inline void
+ngx_http_spdy_queue_blocked_frame(ngx_http_spdy_connection_t *sc,
+    ngx_http_spdy_out_frame_t *frame)
+{
+    ngx_http_spdy_out_frame_t  **out;
+
+    for (out = &sc->last_out; *out && !(*out)->blocked; out = &(*out)->next)
+    {
+        if (frame->priority >= (*out)->priority) {
+            break;
+        }
+    }
+
+    frame->next = *out;
+    *out = frame;
+}
+
+
+void ngx_http_spdy_init(ngx_event_t *rev);
+void ngx_http_spdy_request_headers_init();
+
+ngx_int_t ngx_http_spdy_read_request_body(ngx_http_request_t *r,
+    ngx_http_client_body_handler_pt post_handler);
+
+void ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc);
+
+ngx_int_t ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc);
+
+
+#define ngx_spdy_frame_aligned_write_uint16(p, s)                             \
+    (*(uint16_t *) (p) = htons((uint16_t) (s)), (p) + sizeof(uint16_t))
+
+#define ngx_spdy_frame_aligned_write_uint32(p, s)                             \
+    (*(uint32_t *) (p) = htonl((uint32_t) (s)), (p) + sizeof(uint32_t))
+
+#if (NGX_HAVE_NONALIGNED)
+
+#define ngx_spdy_frame_write_uint16  ngx_spdy_frame_aligned_write_uint16
+#define ngx_spdy_frame_write_uint32  ngx_spdy_frame_aligned_write_uint32
+
+#else
+
+#define ngx_spdy_frame_write_uint16(p, s)                                     \
+    ((p)[0] = (u_char) (s) >> 8, (p)[1] = (u_char) (s), (p) + sizeof(uint16_t))
+
+#define ngx_spdy_frame_write_uint32(p, s)                                     \
+    ((p)[0] = (u_char) (s) >> 24,                                             \
+    (p)[1] = (u_char) (s) >> 16,                                              \
+    (p)[2] = (u_char) (s) >> 8,                                               \
+    (p)[3] = (u_char) (s), (p) + sizeof(uint32_t))
+
+#endif
+
+
+#define ngx_spdy_ctl_frame_head(t)                                            \
+    ((uint32_t) NGX_SPDY_CTL_BIT << 31 | NGX_SPDY_VERSION << 16 | (t))
+
+#define ngx_spdy_frame_write_head(p, t)                                       \
+    ngx_spdy_frame_aligned_write_uint32(p, ngx_spdy_ctl_frame_head(t))
+
+#define ngx_spdy_frame_write_flags_and_len(p, f, l)                           \
+    ngx_spdy_frame_aligned_write_uint32(p, (f) << 24 | (l))
+
+#define ngx_spdy_frame_write_sid  ngx_spdy_frame_aligned_write_uint32
+
+#endif /* _NGX_HTTP_SPDY_H_INCLUDED_ */

  Added: vendor/nginx-1.4.2/src/http/ngx_http_spdy_filter_module.c (+999 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.4.2/src/http/ngx_http_spdy_filter_module.c    2013-07-22 13:32:39 +0900 (8fe46b2)
@@ -0,0 +1,999 @@
+
+/*
+ * Copyright (C) Nginx, Inc.
+ * Copyright (C) Valentin V. Bartenev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+#include <nginx.h>
+#include <ngx_http_spdy_module.h>
+
+#include <zlib.h>
+
+
+#define NGX_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_name(p, h)                                     \
+    ngx_cpymem(ngx_http_spdy_nv_write_nlen(p, sizeof(h) - 1), h, sizeof(h) - 1)
+
+#define ngx_http_spdy_nv_write_val(p, h)                                      \
+    ngx_cpymem(ngx_http_spdy_nv_write_vlen(p, sizeof(h) - 1), h, sizeof(h) - 1)
+
+static ngx_inline ngx_int_t ngx_http_spdy_filter_send(
+    ngx_connection_t *fc, ngx_http_spdy_stream_t *stream);
+
+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);
+
+static ngx_int_t ngx_http_spdy_syn_frame_handler(
+    ngx_http_spdy_connection_t *sc, ngx_http_spdy_out_frame_t *frame);
+static ngx_int_t ngx_http_spdy_data_frame_handler(
+    ngx_http_spdy_connection_t *sc, ngx_http_spdy_out_frame_t *frame);
+static ngx_inline void ngx_http_spdy_handle_frame(
+    ngx_http_spdy_stream_t *stream, ngx_http_spdy_out_frame_t *frame);
+static ngx_inline void ngx_http_spdy_handle_stream(
+    ngx_http_spdy_connection_t *sc, ngx_http_spdy_stream_t *stream);
+
+static void ngx_http_spdy_filter_cleanup(void *data);
+
+static ngx_int_t ngx_http_spdy_filter_init(ngx_conf_t *cf);
+
+
+static ngx_http_module_t  ngx_http_spdy_filter_module_ctx = {
+    NULL,                                  /* preconfiguration */
+    ngx_http_spdy_filter_init,             /* postconfiguration */
+
+    NULL,                                  /* create main configuration */
+    NULL,                                  /* init main configuration */
+
+    NULL,                                  /* create server configuration */
+    NULL,                                  /* merge server configuration */
+
+    NULL,                                  /* create location configuration */
+    NULL                                   /* merge location configuration */
+};
+
+
+ngx_module_t  ngx_http_spdy_filter_module = {
+    NGX_MODULE_V1,
+    &ngx_http_spdy_filter_module_ctx,      /* module context */
+    NULL,                                  /* module directives */
+    NGX_HTTP_MODULE,                       /* module type */
+    NULL,                                  /* init master */
+    NULL,                                  /* init module */
+    NULL,                                  /* init process */
+    NULL,                                  /* init thread */
+    NULL,                                  /* exit thread */
+    NULL,                                  /* exit process */
+    NULL,                                  /* exit master */
+    NGX_MODULE_V1_PADDING
+};
+
+
+static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;
+static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;
+
+
+static ngx_int_t
+ngx_http_spdy_header_filter(ngx_http_request_t *r)
+{
+    int                           rc;
+    size_t                        len;
+    u_char                       *p, *buf, *last;
+    ngx_buf_t                    *b;
+    ngx_str_t                     host;
+    ngx_uint_t                    i, j, count, port;
+    ngx_chain_t                  *cl;
+    ngx_list_part_t              *part, *pt;
+    ngx_table_elt_t              *header, *h;
+    ngx_connection_t             *c;
+    ngx_http_cleanup_t           *cln;
+    ngx_http_core_loc_conf_t     *clcf;
+    ngx_http_core_srv_conf_t     *cscf;
+    ngx_http_spdy_stream_t       *stream;
+    ngx_http_spdy_out_frame_t    *frame;
+    ngx_http_spdy_connection_t   *sc;
+    struct sockaddr_in           *sin;
+#if (NGX_HAVE_INET6)
+    struct sockaddr_in6          *sin6;
+#endif
+    u_char                        addr[NGX_SOCKADDR_STRLEN];
+
+    if (!r->spdy_stream) {
+        return ngx_http_next_header_filter(r);
+    }
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "spdy header filter");
+
+    if (r->header_sent) {
+        return NGX_OK;
+    }
+
+    r->header_sent = 1;
+
+    if (r != r->main) {
+        return NGX_OK;
+    }
+
+    c = r->connection;
+
+    if (r->method == NGX_HTTP_HEAD) {
+        r->header_only = 1;
+    }
+
+    switch (r->headers_out.status) {
+
+    case NGX_HTTP_OK:
+    case NGX_HTTP_PARTIAL_CONTENT:
+        break;
+
+    case NGX_HTTP_NOT_MODIFIED:
+        r->header_only = 1;
+        break;
+
+    case NGX_HTTP_NO_CONTENT:
+        r->header_only = 1;
+
+        ngx_str_null(&r->headers_out.content_type);
+
+        r->headers_out.content_length = NULL;
+        r->headers_out.content_length_n = -1;
+
+        /* fall through */
+
+    default:
+        r->headers_out.last_modified_time = -1;
+        r->headers_out.last_modified = NULL;
+    }
+
+    len = NGX_SPDY_NV_NUM_SIZE
+          + ngx_http_spdy_nv_nsize("version")
+          + ngx_http_spdy_nv_vsize("HTTP/1.1")
+          + ngx_http_spdy_nv_nsize("status")
+          + ngx_http_spdy_nv_vsize("418");
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    if (r->headers_out.server == NULL) {
+        len += ngx_http_spdy_nv_nsize("server");
+        len += clcf->server_tokens ? ngx_http_spdy_nv_vsize(NGINX_VER)
+                                   : ngx_http_spdy_nv_vsize("nginx");
+    }
+
+    if (r->headers_out.date == NULL) {
+        len += ngx_http_spdy_nv_nsize("date")
+               + ngx_http_spdy_nv_vsize("Wed, 31 Dec 1986 10:00:00 GMT");
+    }
+
+    if (r->headers_out.content_type.len) {
+        len += ngx_http_spdy_nv_nsize("content-type")
+               + NGX_SPDY_NV_VLEN_SIZE + r->headers_out.content_type.len;
+
+        if (r->headers_out.content_type_len == r->headers_out.content_type.len
+            && r->headers_out.charset.len)
+        {
+            len += sizeof("; charset=") - 1 + r->headers_out.charset.len;
+        }
+    }
+
+    if (r->headers_out.content_length == NULL
+        && r->headers_out.content_length_n >= 0)
+    {
+        len += ngx_http_spdy_nv_nsize("content-length")
+               + NGX_SPDY_NV_VLEN_SIZE + NGX_OFF_T_LEN;
+    }
+
+    if (r->headers_out.last_modified == NULL
+        && r->headers_out.last_modified_time != -1)
+    {
+        len += ngx_http_spdy_nv_nsize("last-modified")
+               + ngx_http_spdy_nv_vsize("Wed, 31 Dec 1986 10:00:00 GMT");
+    }
+
+    if (r->headers_out.location
+        && r->headers_out.location->value.len
+        && r->headers_out.location->value.data[0] == '/')
+    {
+        r->headers_out.location->hash = 0;
+
+        if (clcf->server_name_in_redirect) {
+            cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+            host = cscf->server_name;
+
+        } else if (r->headers_in.server.len) {
+            host = r->headers_in.server;
+
+        } else {
+            host.len = NGX_SOCKADDR_STRLEN;
+            host.data = addr;
+
+            if (ngx_connection_local_sockaddr(c, &host, 0) != NGX_OK) {
+                return NGX_ERROR;
+            }
+        }
+
+        switch (c->local_sockaddr->sa_family) {
+
+#if (NGX_HAVE_INET6)
+        case AF_INET6:
+            sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
+            port = ntohs(sin6->sin6_port);
+            break;
+#endif
+#if (NGX_HAVE_UNIX_DOMAIN)
+        case AF_UNIX:
+            port = 0;
+            break;
+#endif
+        default: /* AF_INET */
+            sin = (struct sockaddr_in *) c->local_sockaddr;
+            port = ntohs(sin->sin_port);
+            break;
+        }
+
+        len += ngx_http_spdy_nv_nsize("location")
+               + ngx_http_spdy_nv_vsize("https://")
+               + host.len
+               + r->headers_out.location->value.len;
+
+        if (clcf->port_in_redirect) {
+
+#if (NGX_HTTP_SSL)
+            if (c->ssl)
+                port = (port == 443) ? 0 : port;
+            else
+#endif
+                port = (port == 80) ? 0 : port;
+
+        } else {
+            port = 0;
+        }
+
+        if (port) {
+            len += sizeof(":65535") - 1;
+        }
+
+    } else {
+        ngx_str_null(&host);
+        port = 0;
+    }
+
+    part = &r->headers_out.headers.part;
+    header = part->elts;
+
+    for (i = 0; /* void */; i++) {
+
+        if (i >= part->nelts) {
+            if (part->next == NULL) {
+                break;
+            }
+
+            part = part->next;
+            header = part->elts;
+            i = 0;
+        }
+
+        if (header[i].hash == 0) {
+            continue;
+        }
+
+        len += NGX_SPDY_NV_NLEN_SIZE + header[i].key.len
+               + NGX_SPDY_NV_VLEN_SIZE  + header[i].value.len;
+    }
+
+    buf = ngx_alloc(len, r->pool->log);
+    if (buf == NULL) {
+        return NGX_ERROR;
+    }
+
+    last = buf + NGX_SPDY_NV_NUM_SIZE;
+
+    last = ngx_http_spdy_nv_write_name(last, "version");
+    last = ngx_http_spdy_nv_write_val(last, "HTTP/1.1");
+
+    last = ngx_http_spdy_nv_write_name(last, "status");
+    last = ngx_spdy_frame_write_uint16(last, 3);
+    last = ngx_sprintf(last, "%03ui", r->headers_out.status);
+
+    count = 2;
+
+    if (r->headers_out.server == NULL) {
+        last = ngx_http_spdy_nv_write_name(last, "server");
+        last = clcf->server_tokens
+               ? ngx_http_spdy_nv_write_val(last, NGINX_VER)
+               : ngx_http_spdy_nv_write_val(last, "nginx");
+
+        count++;
+    }
+
+    if (r->headers_out.date == NULL) {
+        last = ngx_http_spdy_nv_write_name(last, "date");
+
+        last = ngx_http_spdy_nv_write_vlen(last, ngx_cached_http_time.len);
+
+        last = ngx_cpymem(last, ngx_cached_http_time.data,
+                          ngx_cached_http_time.len);
+
+        count++;
+    }
+
+    if (r->headers_out.content_type.len) {
+
+        last = ngx_http_spdy_nv_write_name(last, "content-type");
+
+        p = last + NGX_SPDY_NV_VLEN_SIZE;
+
+        last = ngx_cpymem(p, r->headers_out.content_type.data,
+                          r->headers_out.content_type.len);
+
+        if (r->headers_out.content_type_len == r->headers_out.content_type.len
+            && r->headers_out.charset.len)
+        {
+            last = ngx_cpymem(last, "; charset=", sizeof("; charset=") - 1);
+
+            last = ngx_cpymem(last, r->headers_out.charset.data,
+                              r->headers_out.charset.len);
+
+            /* update r->headers_out.content_type for possible logging */
+
+            r->headers_out.content_type.len = last - p;
+            r->headers_out.content_type.data = p;
+        }
+
+        (void) ngx_http_spdy_nv_write_vlen(p - NGX_SPDY_NV_VLEN_SIZE,
+                                           r->headers_out.content_type.len);
+
+        count++;
+    }
+
+    if (r->headers_out.content_length == NULL
+        && r->headers_out.content_length_n >= 0)
+    {
+        last = ngx_http_spdy_nv_write_name(last, "content-length");
+
+        p = last + NGX_SPDY_NV_VLEN_SIZE;
+
+        last = ngx_sprintf(p, "%O", r->headers_out.content_length_n);
+
+        (void) ngx_http_spdy_nv_write_vlen(p - NGX_SPDY_NV_VLEN_SIZE,
+                                           last - p);
+
+        count++;
+    }
+
+    if (r->headers_out.last_modified == NULL
+        && r->headers_out.last_modified_time != -1)
+    {
+        last = ngx_http_spdy_nv_write_name(last, "last-modified");
+
+        p = last + NGX_SPDY_NV_VLEN_SIZE;
+
+        last = ngx_http_time(p, r->headers_out.last_modified_time);
+
+        (void) ngx_http_spdy_nv_write_vlen(p - NGX_SPDY_NV_VLEN_SIZE,
+                                           last - p);
+
+        count++;
+    }
+
+    if (host.data) {
+
+        last = ngx_http_spdy_nv_write_name(last, "location");
+
+        p = last + NGX_SPDY_NV_VLEN_SIZE;
+
+        last = ngx_cpymem(p, "http", sizeof("http") - 1);
+
+#if (NGX_HTTP_SSL)
+        if (c->ssl) {
+            *last++ ='s';
+        }
+#endif
+
+        *last++ = ':'; *last++ = '/'; *last++ = '/';
+
+        last = ngx_cpymem(last, host.data, host.len);
+
+        if (port) {
+            last = ngx_sprintf(last, ":%ui", port);
+        }
+
+        last = ngx_cpymem(last, r->headers_out.location->value.data,
+                          r->headers_out.location->value.len);
+
+        /* update r->headers_out.location->value for possible logging */
+
+        r->headers_out.location->value.len = last - p;
+        r->headers_out.location->value.data = p;
+        ngx_str_set(&r->headers_out.location->key, "location");
+
+        (void) ngx_http_spdy_nv_write_vlen(p - NGX_SPDY_NV_VLEN_SIZE,
+                                           r->headers_out.location->value.len);
+
+        count++;
+    }
+
+    part = &r->headers_out.headers.part;
+    header = part->elts;
+
+    for (i = 0; /* void */; i++) {
+
+        if (i >= part->nelts) {
+            if (part->next == NULL) {
+                break;
+            }
+
+            part = part->next;
+            header = part->elts;
+            i = 0;
+        }
+
+        if (header[i].hash == 0 || header[i].hash == 2) {
+            continue;
+        }
+
+        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);
+        last += header[i].key.len;
+
+        p = last + NGX_SPDY_NV_VLEN_SIZE;
+
+        last = ngx_cpymem(p, header[i].value.data, header[i].value.len);
+
+        pt = part;
+        h = header;
+
+        for (j = i + 1; /* void */; j++) {
+
+            if (j >= pt->nelts) {
+                if (pt->next == NULL) {
+                    break;
+                }
+
+                pt = pt->next;
+                h = pt->elts;
+                j = 0;
+            }
+
+            if (h[j].hash == 0 || h[j].hash == 2
+                || h[j].key.len != header[i].key.len
+                || ngx_strncasecmp(header[i].key.data, h[j].key.data,
+                                   header[i].key.len))
+            {
+                continue;
+            }
+
+            *last++ = '\0';
+
+            last = ngx_cpymem(last, h[j].value.data, h[j].value.len);
+
+            h[j].hash = 2;
+        }
+
+        (void) ngx_http_spdy_nv_write_vlen(p - NGX_SPDY_NV_VLEN_SIZE,
+                                           last - p);
+
+        count++;
+    }
+
+    (void) ngx_spdy_frame_write_uint16(buf, count);
+
+    stream = r->spdy_stream;
+    sc = stream->connection;
+
+    len = last - buf;
+
+    b = ngx_create_temp_buf(r->pool, NGX_SPDY_FRAME_HEADER_SIZE
+                                     + NGX_SPDY_SYN_REPLY_SIZE
+                                     + deflateBound(&sc->zstream_out, len));
+    if (b == NULL) {
+        ngx_free(buf);
+        return NGX_ERROR;
+    }
+
+    b->last += NGX_SPDY_FRAME_HEADER_SIZE + NGX_SPDY_SYN_REPLY_SIZE;
+
+    sc->zstream_out.next_in = buf;
+    sc->zstream_out.avail_in = len;
+    sc->zstream_out.next_out = b->last;
+    sc->zstream_out.avail_out = b->end - b->last;
+
+    rc = deflate(&sc->zstream_out, Z_SYNC_FLUSH);
+
+    ngx_free(buf);
+
+    if (rc != Z_OK) {
+        ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                      "spdy deflate() failed: %d", rc);
+        return NGX_ERROR;
+    }
+
+    ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "spdy deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
+                   sc->zstream_out.next_in, sc->zstream_out.next_out,
+                   sc->zstream_out.avail_in, sc->zstream_out.avail_out,
+                   rc);
+
+    b->last = sc->zstream_out.next_out;
+
+    p = b->pos;
+    p = ngx_spdy_frame_write_head(p, NGX_SPDY_SYN_REPLY);
+
+    len = b->last - b->pos;
+
+    r->header_size = len;
+
+    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);
+    } else {
+        p = ngx_spdy_frame_write_flags_and_len(p, 0,
+                                             len - NGX_SPDY_FRAME_HEADER_SIZE);
+    }
+
+    (void) ngx_spdy_frame_write_sid(p, stream->id);
+
+    cl = ngx_alloc_chain_link(r->pool);
+    if (cl == NULL) {
+        return NGX_ERROR;
+    }
+
+    cl->buf = b;
+    cl->next = NULL;
+
+    frame = ngx_palloc(r->pool, sizeof(ngx_http_spdy_out_frame_t));
+    if (frame == NULL) {
+        return NGX_ERROR;
+    }
+
+    frame->first = cl;
+    frame->last = cl;
+    frame->handler = ngx_http_spdy_syn_frame_handler;
+    frame->free = NULL;
+    frame->stream = stream;
+    frame->size = 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);
+
+    ngx_http_spdy_queue_blocked_frame(sc, frame);
+
+    r->blocked++;
+
+    cln = ngx_http_cleanup_add(r, 0);
+    if (cln == NULL) {
+        return NGX_ERROR;
+    }
+
+    cln->handler = ngx_http_spdy_filter_cleanup;
+    cln->data = stream;
+
+    stream->waiting = 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)
+{
+    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;
+
+    stream = r->spdy_stream;
+
+    if (stream == NULL) {
+        return ngx_http_next_body_filter(r, in);
+    }
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "spdy body filter \"%V?%V\"", &r->uri, &r->args);
+
+    if (in == NULL || r->header_only) {
+
+        if (stream->waiting) {
+            return NGX_AGAIN;
+        }
+
+        r->connection->buffered &= ~NGX_SPDY_WRITE_BUFFERED;
+
+        return NGX_OK;
+    }
+
+    size = 0;
+    ln = &out;
+    ll = in;
+
+    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;
+        }
+#endif
+        cl = ngx_alloc_chain_link(r->pool);
+        if (cl == NULL) {
+            return NGX_ERROR;
+        }
+
+        size += ngx_buf_size(b);
+        cl->buf = b;
+
+        *ln = cl;
+        ln = &cl->next;
+
+        if (ll->next == NULL) {
+            break;
+        }
+
+        ll = ll->next;
+    }
+
+    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;
+    }
+
+    frame = ngx_http_spdy_filter_get_data_frame(stream, (size_t) size,
+                                                b->last_buf, out, cl);
+    if (frame == NULL) {
+        return NGX_ERROR;
+    }
+
+    ngx_http_spdy_queue_frame(stream->connection, frame);
+
+    stream->waiting++;
+
+    r->main->blocked++;
+
+    return ngx_http_spdy_filter_send(r->connection, stream);
+}
+
+
+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)
+{
+    u_char                     *p;
+    ngx_buf_t                  *buf;
+    ngx_uint_t                  flags;
+    ngx_chain_t                *cl;
+    ngx_http_spdy_out_frame_t  *frame;
+
+
+    frame = stream->free_frames;
+
+    if (frame) {
+        stream->free_frames = frame->free;
+
+    } else {
+        frame = ngx_palloc(stream->request->pool,
+                           sizeof(ngx_http_spdy_out_frame_t));
+        if (frame == NULL) {
+            return NULL;
+        }
+    }
+
+    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);
+
+    if (len || fin) {
+
+        flags = fin ? NGX_SPDY_FLAG_FIN : 0;
+
+        cl = ngx_chain_get_free_buf(stream->request->pool,
+                                    &stream->free_data_headers);
+        if (cl == NULL) {
+            return NULL;
+        }
+
+        buf = cl->buf;
+
+        if (buf->start) {
+            p = buf->start;
+            buf->pos = p;
+
+            p += sizeof(uint32_t);
+
+            (void) ngx_spdy_frame_write_flags_and_len(p, flags, len);
+
+        } else {
+            p = ngx_palloc(stream->request->pool, NGX_SPDY_FRAME_HEADER_SIZE);
+            if (p == NULL) {
+                return NULL;
+            }
+
+            buf->pos = p;
+            buf->start = p;
+
+            p = ngx_spdy_frame_write_sid(p, stream->id);
+            p = ngx_spdy_frame_write_flags_and_len(p, flags, len);
+
+            buf->last = p;
+            buf->end = p;
+
+            buf->tag = (ngx_buf_tag_t) &ngx_http_spdy_filter_module;
+            buf->memory = 1;
+        }
+
+        cl->next = first;
+        first = cl;
+    }
+
+    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->priority = stream->priority;
+    frame->blocked = 0;
+    frame->fin = fin;
+
+    return frame;
+}
+
+
+static ngx_inline ngx_int_t
+ngx_http_spdy_filter_send(ngx_connection_t *fc, ngx_http_spdy_stream_t *stream)
+{
+    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;
+        fc->write->delayed = 1;
+        return NGX_AGAIN;
+    }
+
+    fc->buffered &= ~NGX_SPDY_WRITE_BUFFERED;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_syn_frame_handler(ngx_http_spdy_connection_t *sc,
+    ngx_http_spdy_out_frame_t *frame)
+{
+    ngx_buf_t               *buf;
+    ngx_http_spdy_stream_t  *stream;
+
+    buf = frame->first->buf;
+
+    if (buf->pos != buf->last) {
+        return NGX_AGAIN;
+    }
+
+    stream = frame->stream;
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy:%ui SYN_REPLY frame %p was sent", stream->id, frame);
+
+    ngx_free_chain(stream->request->pool, frame->first);
+
+    ngx_http_spdy_handle_frame(stream, frame);
+
+    ngx_http_spdy_handle_stream(sc, stream);
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_data_frame_handler(ngx_http_spdy_connection_t *sc,
+    ngx_http_spdy_out_frame_t *frame)
+{
+    ngx_chain_t             *cl, *ln;
+    ngx_http_spdy_stream_t  *stream;
+
+    stream = frame->stream;
+
+    cl = frame->first;
+
+    if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_spdy_filter_module) {
+
+        if (cl->buf->pos != cl->buf->last) {
+            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                           "spdy:%ui DATA frame %p was sent partially",
+                           stream->id, frame);
+
+            return NGX_AGAIN;
+        }
+
+        ln = cl->next;
+
+        cl->next = stream->free_data_headers;
+        stream->free_data_headers = cl;
+
+        if (cl == frame->last) {
+            goto done;
+        }
+
+        cl = ln;
+    }
+
+    for ( ;; ) {
+        if (ngx_buf_size(cl->buf) != 0) {
+
+            if (cl != frame->first) {
+                frame->first = cl;
+                ngx_http_spdy_handle_stream(sc, stream);
+            }
+
+            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                           "spdy:%ui DATA frame %p was sent partially",
+                           stream->id, frame);
+
+            return NGX_AGAIN;
+        }
+
+        ln = cl->next;
+
+        ngx_free_chain(stream->request->pool, cl);
+
+        if (cl == frame->last) {
+            goto done;
+        }
+
+        cl = ln;
+    }
+
+done:
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+                   "spdy:%ui DATA frame %p was sent", stream->id, frame);
+
+    stream->request->header_size += NGX_SPDY_FRAME_HEADER_SIZE;
+
+    ngx_http_spdy_handle_frame(stream, frame);
+
+    ngx_http_spdy_handle_stream(sc, stream);
+
+    return NGX_OK;
+}
+
+
+static ngx_inline void
+ngx_http_spdy_handle_frame(ngx_http_spdy_stream_t *stream,
+    ngx_http_spdy_out_frame_t *frame)
+{
+    ngx_http_request_t  *r;
+
+    r = stream->request;
+
+    r->connection->sent += frame->size;
+    r->blocked--;
+
+    if (frame->fin) {
+        stream->out_closed = 1;
+    }
+
+    frame->free = stream->free_frames;
+    stream->free_frames = frame;
+
+    stream->waiting--;
+}
+
+
+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;
+
+    if (stream->handled) {
+        return;
+    }
+
+    if (sc->blocked == 2) {
+        stream->handled = 1;
+
+        stream->next = sc->last_stream;
+        sc->last_stream = stream;
+    }
+}
+
+
+static void
+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;
+
+    if (stream->waiting == 0) {
+        return;
+    }
+
+    r = stream->request;
+
+    fn = &stream->connection->last_out;
+
+    for ( ;; ) {
+        frame = *fn;
+
+        if (frame == NULL) {
+            break;
+        }
+
+        if (frame->stream == stream && !frame->blocked) {
+
+            stream->waiting--;
+            r->blocked--;
+
+            *fn = frame->next;
+            continue;
+        }
+
+        fn = &frame->next;
+    }
+}
+
+
+static ngx_int_t
+ngx_http_spdy_filter_init(ngx_conf_t *cf)
+{
+    ngx_http_next_header_filter = ngx_http_top_header_filter;
+    ngx_http_top_header_filter = ngx_http_spdy_header_filter;
+
+    ngx_http_next_body_filter = ngx_http_top_body_filter;
+    ngx_http_top_body_filter = ngx_http_spdy_body_filter;
+
+    return NGX_OK;
+}

  Added: vendor/nginx-1.4.2/src/http/ngx_http_spdy_module.c (+351 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.4.2/src/http/ngx_http_spdy_module.c    2013-07-22 13:32:39 +0900 (7f02a18)
@@ -0,0 +1,351 @@
+
+/*
+ * Copyright (C) Nginx, Inc.
+ * Copyright (C) Valentin V. Bartenev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+#include <ngx_http_spdy_module.h>
+
+
+static ngx_int_t ngx_http_spdy_add_variables(ngx_conf_t *cf);
+
+static ngx_int_t ngx_http_spdy_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_spdy_request_priority_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
+
+static ngx_int_t ngx_http_spdy_module_init(ngx_cycle_t *cycle);
+
+static void *ngx_http_spdy_create_main_conf(ngx_conf_t *cf);
+static char *ngx_http_spdy_init_main_conf(ngx_conf_t *cf, void *conf);
+
+static void *ngx_http_spdy_create_srv_conf(ngx_conf_t *cf);
+static char *ngx_http_spdy_merge_srv_conf(ngx_conf_t *cf, void *parent,
+    void *child);
+
+static 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 ngx_conf_num_bounds_t  ngx_http_spdy_headers_comp_bounds = {
+    ngx_conf_check_num_bounds, 0, 9
+};
+
+static ngx_conf_post_t  ngx_http_spdy_recv_buffer_size_post =
+    { ngx_http_spdy_recv_buffer_size };
+static ngx_conf_post_t  ngx_http_spdy_pool_size_post =
+    { ngx_http_spdy_pool_size };
+static ngx_conf_post_t  ngx_http_spdy_streams_index_mask_post =
+    { ngx_http_spdy_streams_index_mask };
+
+
+static ngx_command_t  ngx_http_spdy_commands[] = {
+
+    { ngx_string("spdy_recv_buffer_size"),
+      NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_size_slot,
+      NGX_HTTP_MAIN_CONF_OFFSET,
+      offsetof(ngx_http_spdy_main_conf_t, recv_buffer_size),
+      &ngx_http_spdy_recv_buffer_size_post },
+
+    { ngx_string("spdy_pool_size"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_size_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_spdy_srv_conf_t, pool_size),
+      &ngx_http_spdy_pool_size_post },
+
+    { ngx_string("spdy_max_concurrent_streams"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_num_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_spdy_srv_conf_t, concurrent_streams),
+      NULL },
+
+    { ngx_string("spdy_streams_index_size"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_num_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_spdy_srv_conf_t, streams_index_mask),
+      &ngx_http_spdy_streams_index_mask_post },
+
+    { ngx_string("spdy_recv_timeout"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_msec_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_spdy_srv_conf_t, recv_timeout),
+      NULL },
+
+    { ngx_string("spdy_keepalive_timeout"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_msec_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_spdy_srv_conf_t, keepalive_timeout),
+      NULL },
+
+    { ngx_string("spdy_headers_comp"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_num_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_spdy_srv_conf_t, headers_comp),
+      &ngx_http_spdy_headers_comp_bounds },
+
+      ngx_null_command
+};
+
+
+static ngx_http_module_t  ngx_http_spdy_module_ctx = {
+    ngx_http_spdy_add_variables,           /* preconfiguration */
+    NULL,                                  /* postconfiguration */
+
+    ngx_http_spdy_create_main_conf,        /* create main configuration */
+    ngx_http_spdy_init_main_conf,          /* init main configuration */
+
+    ngx_http_spdy_create_srv_conf,         /* create server configuration */
+    ngx_http_spdy_merge_srv_conf,          /* merge server configuration */
+
+    NULL,                                  /* create location configuration */
+    NULL                                   /* merge location configuration */
+};
+
+
+ngx_module_t  ngx_http_spdy_module = {
+    NGX_MODULE_V1,
+    &ngx_http_spdy_module_ctx,             /* module context */
+    ngx_http_spdy_commands,                /* module directives */
+    NGX_HTTP_MODULE,                       /* module type */
+    NULL,                                  /* init master */
+    ngx_http_spdy_module_init,             /* init module */
+    NULL,                                  /* init process */
+    NULL,                                  /* init thread */
+    NULL,                                  /* exit thread */
+    NULL,                                  /* exit process */
+    NULL,                                  /* exit master */
+    NGX_MODULE_V1_PADDING
+};
+
+
+static ngx_http_variable_t  ngx_http_spdy_vars[] = {
+
+    { ngx_string("spdy"), NULL,
+      ngx_http_spdy_variable, 0, 0, 0 },
+
+    { ngx_string("spdy_request_priority"), NULL,
+      ngx_http_spdy_request_priority_variable, 0, 0, 0 },
+
+    { ngx_null_string, NULL, NULL, 0, 0, 0 }
+};
+
+
+static ngx_int_t
+ngx_http_spdy_add_variables(ngx_conf_t *cf)
+{
+   ngx_http_variable_t  *var, *v;
+
+    for (v = ngx_http_spdy_vars; v->name.len; v++) {
+        var = ngx_http_add_variable(cf, &v->name, v->flags);
+        if (var == NULL) {
+            return NGX_ERROR;
+        }
+
+        var->get_handler = v->get_handler;
+        var->data = v->data;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    if (r->spdy_stream) {
+        v->len = 1;
+        v->valid = 1;
+        v->no_cacheable = 0;
+        v->not_found = 0;
+        v->data = (u_char *) "2";
+
+        return NGX_OK;
+    }
+
+    *v = ngx_http_variable_null_value;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_request_priority_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    if (r->spdy_stream) {
+        v->len = 1;
+        v->valid = 1;
+        v->no_cacheable = 0;
+        v->not_found = 0;
+
+        v->data = ngx_pnalloc(r->pool, 1);
+        if (v->data == NULL) {
+            return NGX_ERROR;
+        }
+
+        v->data[0] = '0' + (u_char) r->spdy_stream->priority;
+
+        return NGX_OK;
+    }
+
+    *v = ngx_http_variable_null_value;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_spdy_module_init(ngx_cycle_t *cycle)
+{
+    ngx_http_spdy_request_headers_init();
+
+    return NGX_OK;
+}
+
+
+static void *
+ngx_http_spdy_create_main_conf(ngx_conf_t *cf)
+{
+    ngx_http_spdy_main_conf_t  *smcf;
+
+    smcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_spdy_main_conf_t));
+    if (smcf == NULL) {
+        return NULL;
+    }
+
+    smcf->recv_buffer_size = NGX_CONF_UNSET_SIZE;
+
+    return smcf;
+}
+
+
+static char *
+ngx_http_spdy_init_main_conf(ngx_conf_t *cf, void *conf)
+{
+    ngx_http_spdy_main_conf_t *smcf = conf;
+
+    if (smcf->recv_buffer_size == NGX_CONF_UNSET_SIZE) {
+        smcf->recv_buffer_size = 256 * 1024;
+    }
+
+    return NGX_CONF_OK;
+}
+
+
+static void *
+ngx_http_spdy_create_srv_conf(ngx_conf_t *cf)
+{
+    ngx_http_spdy_srv_conf_t  *sscf;
+
+    sscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_spdy_srv_conf_t));
+    if (sscf == NULL) {
+        return NULL;
+    }
+
+    sscf->pool_size = NGX_CONF_UNSET_SIZE;
+
+    sscf->concurrent_streams = NGX_CONF_UNSET_UINT;
+    sscf->streams_index_mask = NGX_CONF_UNSET_UINT;
+
+    sscf->recv_timeout = NGX_CONF_UNSET_MSEC;
+    sscf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
+
+    sscf->headers_comp = NGX_CONF_UNSET;
+
+    return sscf;
+}
+
+
+static char *
+ngx_http_spdy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
+{
+    ngx_http_spdy_srv_conf_t *prev = parent;
+    ngx_http_spdy_srv_conf_t *conf = child;
+
+    ngx_conf_merge_size_value(conf->pool_size, prev->pool_size, 4096);
+
+    ngx_conf_merge_uint_value(conf->concurrent_streams,
+                              prev->concurrent_streams, 100);
+
+    ngx_conf_merge_uint_value(conf->streams_index_mask,
+                              prev->streams_index_mask, 32 - 1);
+
+    ngx_conf_merge_msec_value(conf->recv_timeout,
+                              prev->recv_timeout, 30000);
+    ngx_conf_merge_msec_value(conf->keepalive_timeout,
+                              prev->keepalive_timeout, 180000);
+
+    ngx_conf_merge_value(conf->headers_comp, prev->headers_comp, 0);
+
+    return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_http_spdy_recv_buffer_size(ngx_conf_t *cf, void *post, void *data)
+{
+    size_t *sp = data;
+
+    if (*sp <= 2 * NGX_SPDY_STATE_BUFFER_SIZE) {
+        return "value is too small";
+    }
+
+    return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_http_spdy_pool_size(ngx_conf_t *cf, void *post, void *data)
+{
+    size_t *sp = data;
+
+    if (*sp < NGX_MIN_POOL_SIZE) {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "the pool size must be no less than %uz",
+                           NGX_MIN_POOL_SIZE);
+        return NGX_CONF_ERROR;
+    }
+
+    if (*sp % NGX_POOL_ALIGNMENT) {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "the pool size must be a multiple of %uz",
+                           NGX_POOL_ALIGNMENT);
+        return NGX_CONF_ERROR;
+    }
+
+    return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_http_spdy_streams_index_mask(ngx_conf_t *cf, void *post, void *data)
+{
+    ngx_uint_t *np = data;
+
+    ngx_uint_t  mask;
+
+    mask = *np - 1;
+
+    if (*np == 0 || (*np & mask)) {
+        return "must be a power of two";
+    }
+
+    *np = mask;
+
+    return NGX_CONF_OK;
+}

  Added: vendor/nginx-1.4.2/src/http/ngx_http_spdy_module.h (+36 -0) 100644
===================================================================
--- /dev/null
+++ vendor/nginx-1.4.2/src/http/ngx_http_spdy_module.h    2013-07-22 13:32:39 +0900 (97a7a13)
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright (C) Nginx, Inc.
+ * Copyright (C) Valentin V. Bartenev
+ */
+
+
+#ifndef _NGX_HTTP_SPDY_MODULE_H_INCLUDED_
+#define _NGX_HTTP_SPDY_MODULE_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+
+typedef struct {
+    size_t                          recv_buffer_size;
+    u_char                         *recv_buffer;
+} ngx_http_spdy_main_conf_t;
+
+
+typedef struct {
+    size_t                          pool_size;
+    ngx_uint_t                      concurrent_streams;
+    ngx_uint_t                      streams_index_mask;
+    ngx_msec_t                      recv_timeout;
+    ngx_msec_t                      keepalive_timeout;
+    ngx_int_t                       headers_comp;
+} ngx_http_spdy_srv_conf_t;
+
+
+extern ngx_module_t  ngx_http_spdy_module;
+
+
+#endif /* _NGX_HTTP_SPDY_MODULE_H_INCLUDED_ */

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_special_response.c (+3 -1) 99%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_special_response.c    2013-07-22 11:05:55 +0900 (be495f9)
+++ vendor/nginx-1.4.2/src/http/ngx_http_special_response.c    2013-07-22 13:32:39 +0900 (875c24d)
@@ -421,7 +421,7 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
     r->expect_tested = 1;
 
     if (ngx_http_discard_request_body(r) != NGX_OK) {
-        error = NGX_HTTP_INTERNAL_SERVER_ERROR;
+        r->keepalive = 0;
     }
 
     if (clcf->msie_refresh
@@ -657,6 +657,7 @@ ngx_http_send_special_response(ngx_http_request_t *r,
 
     ngx_http_clear_accept_ranges(r);
     ngx_http_clear_last_modified(r);
+    ngx_http_clear_etag(r);
 
     rc = ngx_http_send_header(r);
 
@@ -755,6 +756,7 @@ ngx_http_send_refresh(ngx_http_request_t *r)
 
     ngx_http_clear_accept_ranges(r);
     ngx_http_clear_last_modified(r);
+    ngx_http_clear_etag(r);
 
     rc = ngx_http_send_header(r);
 

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_upstream.c (+442 -35) 90%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_upstream.c    2013-07-22 11:05:55 +0900 (703017f)
+++ vendor/nginx-1.4.2/src/http/ngx_http_upstream.c    2013-07-22 13:32:39 +0900 (45e2eb7)
@@ -46,6 +46,16 @@ static void ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
     ngx_http_upstream_t *u);
 static void ngx_http_upstream_send_response(ngx_http_request_t *r,
     ngx_http_upstream_t *u);
+static void ngx_http_upstream_upgrade(ngx_http_request_t *r,
+    ngx_http_upstream_t *u);
+static void ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r);
+static void ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r);
+static void ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r,
+    ngx_http_upstream_t *u);
+static void ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r,
+    ngx_http_upstream_t *u);
+static void ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
+    ngx_uint_t from_upstream, ngx_uint_t do_write);
 static void
     ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r);
 static void
@@ -134,6 +144,9 @@ static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy);
 static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
 
+static ngx_addr_t *ngx_http_upstream_get_local(ngx_http_request_t *r,
+    ngx_http_upstream_local_t *local);
+
 static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf);
 static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf);
 
@@ -427,6 +440,13 @@ ngx_http_upstream_init(ngx_http_request_t *r)
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http init upstream, client timer: %d", c->read->timer_set);
 
+#if (NGX_HTTP_SPDY)
+    if (r->spdy_stream) {
+        ngx_http_upstream_init_request(r);
+        return;
+    }
+#endif
+
     if (c->read->timer_set) {
         ngx_del_timer(c->read);
     }
@@ -507,7 +527,7 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
         return;
     }
 
-    u->peer.local = u->conf->local;
+    u->peer.local = ngx_http_upstream_get_local(r, u->conf->local);
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
@@ -636,6 +656,14 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
 
 found:
 
+    if (uscf == NULL) {
+        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                      "no upstream configuration");
+        ngx_http_upstream_finalize_request(r, u,
+                                           NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return;
+    }
+
     if (uscf->peer.init(r, uscf) != NGX_OK) {
         ngx_http_upstream_finalize_request(r, u,
                                            NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -857,11 +885,13 @@ ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u)
 static void
 ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
 {
+    ngx_connection_t              *c;
     ngx_http_request_t            *r;
     ngx_http_upstream_t           *u;
     ngx_http_upstream_resolved_t  *ur;
 
     r = ctx->data;
+    c = r->connection;
 
     u = r->upstream;
     ur = u->resolved;
@@ -873,7 +903,7 @@ ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
                       ngx_resolver_strerror(ctx->state));
 
         ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
-        return;
+        goto failed;
     }
 
     ur->naddrs = ctx->naddrs;
@@ -898,13 +928,17 @@ ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
     if (ngx_http_upstream_create_round_robin_peer(r, ur) != NGX_OK) {
         ngx_http_upstream_finalize_request(r, u,
                                            NGX_HTTP_INTERNAL_SERVER_ERROR);
-        return;
+        goto failed;
     }
 
     ngx_resolve_name_done(ctx);
     ur->ctx = NULL;
 
     ngx_http_upstream_connect(r, u);
+
+failed:
+
+    ngx_http_run_posted_requests(c);
 }
 
 
@@ -991,6 +1025,12 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
         return;
     }
 
+#if (NGX_HTTP_SPDY)
+    if (r->spdy_stream) {
+        return;
+    }
+#endif
+
 #if (NGX_HAVE_KQUEUE)
 
     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
@@ -1097,8 +1137,6 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
 
     r->connection->log->action = "connecting to upstream";
 
-    r->connection->single_connection = 0;
-
     if (u->state && u->state->response_sec) {
         tp = ngx_timeofday();
         u->state->response_sec = tp->sec - u->state->response_sec;
@@ -1316,6 +1354,7 @@ ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u)
     }
 
     u->keepalive = 0;
+    u->upgrade = 0;
 
     ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
     u->headers_in.content_length_n = -1;
@@ -2067,6 +2106,11 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
         return;
     }
 
+    if (u->upgrade) {
+        ngx_http_upstream_upgrade(r, u);
+        return;
+    }
+
     c = r->connection;
 
     if (r->header_only) {
@@ -2350,6 +2394,284 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
 
 
 static void
+ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
+{
+    int                        tcp_nodelay;
+    ngx_connection_t          *c;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    c = r->connection;
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    /* TODO: prevent upgrade if not requested or not possible */
+
+    r->keepalive = 0;
+    c->log->action = "proxying upgraded connection";
+
+    u->read_event_handler = ngx_http_upstream_upgraded_read_upstream;
+    u->write_event_handler = ngx_http_upstream_upgraded_write_upstream;
+    r->read_event_handler = ngx_http_upstream_upgraded_read_downstream;
+    r->write_event_handler = ngx_http_upstream_upgraded_write_downstream;
+
+    if (clcf->tcp_nodelay) {
+        tcp_nodelay = 1;
+
+        if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
+            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
+
+            if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
+                           (const void *) &tcp_nodelay, sizeof(int)) == -1)
+            {
+                ngx_connection_error(c, ngx_socket_errno,
+                                     "setsockopt(TCP_NODELAY) failed");
+                ngx_http_upstream_finalize_request(r, u, 0);
+                return;
+            }
+
+            c->tcp_nodelay = NGX_TCP_NODELAY_SET;
+        }
+
+        if (u->peer.connection->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
+            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, u->peer.connection->log, 0,
+                           "tcp_nodelay");
+
+            if (setsockopt(u->peer.connection->fd, IPPROTO_TCP, TCP_NODELAY,
+                           (const void *) &tcp_nodelay, sizeof(int)) == -1)
+            {
+                ngx_connection_error(u->peer.connection, ngx_socket_errno,
+                                     "setsockopt(TCP_NODELAY) failed");
+                ngx_http_upstream_finalize_request(r, u, 0);
+                return;
+            }
+
+            u->peer.connection->tcp_nodelay = NGX_TCP_NODELAY_SET;
+        }
+    }
+
+    if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) {
+        ngx_http_upstream_finalize_request(r, u, 0);
+        return;
+    }
+
+    if (u->peer.connection->read->ready
+        || u->buffer.pos != u->buffer.last)
+    {
+        ngx_http_upstream_process_upgraded(r, 1, 1);
+    }
+
+    if (c->read->ready
+        || r->header_in->pos != r->header_in->last)
+    {
+        ngx_http_upstream_process_upgraded(r, 0, 1);
+    }
+}
+
+
+static void
+ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r)
+{
+    ngx_http_upstream_process_upgraded(r, 0, 0);
+}
+
+
+static void
+ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r)
+{
+    ngx_http_upstream_process_upgraded(r, 1, 1);
+}
+
+
+static void
+ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r,
+    ngx_http_upstream_t *u)
+{
+    ngx_http_upstream_process_upgraded(r, 1, 0);
+}
+
+
+static void
+ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r,
+    ngx_http_upstream_t *u)
+{
+    ngx_http_upstream_process_upgraded(r, 0, 1);
+}
+
+
+static void
+ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
+    ngx_uint_t from_upstream, ngx_uint_t do_write)
+{
+    size_t                     size;
+    ssize_t                    n;
+    ngx_buf_t                 *b;
+    ngx_connection_t          *c, *downstream, *upstream, *dst, *src;
+    ngx_http_upstream_t       *u;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    c = r->connection;
+    u = r->upstream;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http upstream process upgraded, fu:%ui", from_upstream);
+
+    downstream = c;
+    upstream = u->peer.connection;
+
+    if (downstream->write->timedout) {
+        c->timedout = 1;
+        ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
+        ngx_http_upstream_finalize_request(r, u, NGX_HTTP_REQUEST_TIME_OUT);
+        return;
+    }
+
+    if (upstream->read->timedout || upstream->write->timedout) {
+        ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
+        ngx_http_upstream_finalize_request(r, u, 0);
+        return;
+    }
+
+    if (from_upstream) {
+        src = upstream;
+        dst = downstream;
+        b = &u->buffer;
+
+    } else {
+        src = downstream;
+        dst = upstream;
+        b = &u->from_client;
+
+        if (r->header_in->last > r->header_in->pos) {
+            b = r->header_in;
+            b->end = b->last;
+            do_write = 1;
+        }
+
+        if (b->start == NULL) {
+            b->start = ngx_palloc(r->pool, u->conf->buffer_size);
+            if (b->start == NULL) {
+                ngx_http_upstream_finalize_request(r, u, 0);
+                return;
+            }
+
+            b->pos = b->start;
+            b->last = b->start;
+            b->end = b->start + u->conf->buffer_size;
+            b->temporary = 1;
+            b->tag = u->output.tag;
+        }
+    }
+
+    for ( ;; ) {
+
+        if (do_write) {
+
+            size = b->last - b->pos;
+
+            if (size && dst->write->ready) {
+
+                n = dst->send(dst, b->pos, size);
+
+                if (n == NGX_ERROR) {
+                    ngx_http_upstream_finalize_request(r, u, 0);
+                    return;
+                }
+
+                if (n > 0) {
+                    b->pos += n;
+
+                    if (b->pos == b->last) {
+                        b->pos = b->start;
+                        b->last = b->start;
+                    }
+                }
+            }
+        }
+
+        size = b->end - b->last;
+
+        if (size && src->read->ready) {
+
+            n = src->recv(src, b->last, size);
+
+            if (n == NGX_AGAIN || n == 0) {
+                break;
+            }
+
+            if (n > 0) {
+                do_write = 1;
+                b->last += n;
+
+                continue;
+            }
+
+            if (n == NGX_ERROR) {
+                src->read->eof = 1;
+            }
+        }
+
+        break;
+    }
+
+    if ((upstream->read->eof && u->buffer.pos == u->buffer.last)
+        || (downstream->read->eof && u->from_client.pos == u->from_client.last)
+        || (downstream->read->eof && upstream->read->eof))
+    {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "http upstream upgraded done");
+        ngx_http_upstream_finalize_request(r, u, 0);
+        return;
+    }
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    if (ngx_handle_write_event(upstream->write, u->conf->send_lowat)
+        != NGX_OK)
+    {
+        ngx_http_upstream_finalize_request(r, u, 0);
+        return;
+    }
+
+    if (upstream->write->active && !upstream->write->ready) {
+        ngx_add_timer(upstream->write, u->conf->send_timeout);
+
+    } else if (upstream->write->timer_set) {
+        ngx_del_timer(upstream->write);
+    }
+
+    if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) {
+        ngx_http_upstream_finalize_request(r, u, 0);
+        return;
+    }
+
+    if (upstream->read->active && !upstream->read->ready) {
+        ngx_add_timer(upstream->read, u->conf->read_timeout);
+
+    } else if (upstream->read->timer_set) {
+        ngx_del_timer(upstream->read);
+    }
+
+    if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
+        != NGX_OK)
+    {
+        ngx_http_upstream_finalize_request(r, u, 0);
+        return;
+    }
+
+    if (ngx_handle_read_event(downstream->read, 0) != NGX_OK) {
+        ngx_http_upstream_finalize_request(r, u, 0);
+        return;
+    }
+
+    if (downstream->write->active && !downstream->write->ready) {
+        ngx_add_timer(downstream->write, clcf->send_timeout);
+
+    } else if (downstream->write->timer_set) {
+        ngx_del_timer(downstream->write);
+    }
+}
+
+
+static void
 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r)
 {
     ngx_event_t          *wev;
@@ -2832,14 +3154,16 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
     ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
 #endif
 
-    if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) {
-        state = NGX_PEER_NEXT;
-    } else {
-        state = NGX_PEER_FAILED;
-    }
+    if (u->peer.sockaddr) {
+
+        if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) {
+            state = NGX_PEER_NEXT;
+        } else {
+            state = NGX_PEER_FAILED;
+        }
 
-    if (ft_type != NGX_HTTP_UPSTREAM_FT_NOLIVE) {
         u->peer.free(&u->peer, u->peer.data, state);
+        u->peer.sockaddr = NULL;
     }
 
     if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) {
@@ -2952,19 +3276,10 @@ ngx_http_upstream_cleanup(void *data)
 {
     ngx_http_request_t *r = data;
 
-    ngx_http_upstream_t  *u;
-
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "cleanup http upstream request: \"%V\"", &r->uri);
 
-    u = r->upstream;
-
-    if (u->resolved && u->resolved->ctx) {
-        ngx_resolve_name_done(u->resolved->ctx);
-        u->resolved->ctx = NULL;
-    }
-
-    ngx_http_upstream_finalize_request(r, u, NGX_DONE);
+    ngx_http_upstream_finalize_request(r, r->upstream, NGX_DONE);
 }
 
 
@@ -2992,15 +3307,16 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
         u->state->response_sec = tp->sec - u->state->response_sec;
         u->state->response_msec = tp->msec - u->state->response_msec;
 
-        if (u->pipe) {
+        if (u->pipe && u->pipe->read_length) {
             u->state->response_length = u->pipe->read_length;
         }
     }
 
     u->finalize_request(r, rc);
 
-    if (u->peer.free) {
+    if (u->peer.free && u->peer.sockaddr) {
         u->peer.free(&u->peer, u->peer.data, 0);
+        u->peer.sockaddr = NULL;
     }
 
     if (u->peer.connection) {
@@ -3091,6 +3407,7 @@ 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
@@ -4112,6 +4429,7 @@ ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
     value = cf->args->elts;
     u.host = value[1];
     u.no_resolve = 1;
+    u.no_port = 1;
 
     uscf = ngx_http_upstream_add(cf, &u, NGX_HTTP_UPSTREAM_CREATE
                                          |NGX_HTTP_UPSTREAM_WEIGHT
@@ -4382,14 +4700,14 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
             return NULL;
         }
 
-        if ((uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE) && u->port) {
+        if ((uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE) && !u->no_port) {
             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                                "upstream \"%V\" may not have port %d",
                                &u->host, u->port);
             return NULL;
         }
 
-        if ((flags & NGX_HTTP_UPSTREAM_CREATE) && uscfp[i]->port) {
+        if ((flags & NGX_HTTP_UPSTREAM_CREATE) && !uscfp[i]->no_port) {
             ngx_log_error(NGX_LOG_WARN, cf->log, 0,
                           "upstream \"%V\" may not have port %d in %s:%ui",
                           &u->host, uscfp[i]->port,
@@ -4397,7 +4715,9 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
             return NULL;
         }
 
-        if (uscfp[i]->port != u->port) {
+        if (uscfp[i]->port && u->port
+            && uscfp[i]->port != u->port)
+        {
             continue;
         }
 
@@ -4425,6 +4745,7 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
     uscf->line = cf->conf_file->line;
     uscf->port = u->port;
     uscf->default_port = u->default_port;
+    uscf->no_port = u->no_port;
 
     if (u->naddrs == 1) {
         uscf->servers = ngx_array_create(cf->pool, 1,
@@ -4461,24 +4782,63 @@ ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
 {
     char  *p = conf;
 
-    ngx_int_t     rc;
-    ngx_str_t    *value;
-    ngx_addr_t  **paddr;
+    ngx_int_t                           rc;
+    ngx_str_t                          *value;
+    ngx_http_complex_value_t            cv;
+    ngx_http_upstream_local_t         **plocal, *local;
+    ngx_http_compile_complex_value_t    ccv;
 
-    paddr = (ngx_addr_t **) (p + cmd->offset);
+    plocal = (ngx_http_upstream_local_t **) (p + cmd->offset);
 
-    *paddr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
-    if (*paddr == NULL) {
-        return NGX_CONF_ERROR;
+    if (*plocal != NGX_CONF_UNSET_PTR) {
+        return "is duplicate";
     }
 
     value = cf->args->elts;
 
-    rc = ngx_parse_addr(cf->pool, *paddr, value[1].data, value[1].len);
+    if (ngx_strcmp(value[1].data, "off") == 0) {
+        *plocal = NULL;
+        return NGX_CONF_OK;
+    }
+
+    ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+
+    ccv.cf = cf;
+    ccv.value = &value[1];
+    ccv.complex_value = &cv;
+
+    if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
+    local = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_local_t));
+    if (local == NULL) {
+        return NGX_CONF_ERROR;
+    }
+
+    *plocal = local;
+
+    if (cv.lengths) {
+        local->value = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
+        if (local->value == NULL) {
+            return NGX_CONF_ERROR;
+        }
+
+        *local->value = cv;
+
+        return NGX_CONF_OK;
+    }
+
+    local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
+    if (local->addr == NULL) {
+        return NGX_CONF_ERROR;
+    }
+
+    rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len);
 
     switch (rc) {
     case NGX_OK:
-        (*paddr)->name = value[1];
+        local->addr->name = value[1];
         return NGX_CONF_OK;
 
     case NGX_DECLINED:
@@ -4492,6 +4852,53 @@ ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
 }
 
 
+static ngx_addr_t *
+ngx_http_upstream_get_local(ngx_http_request_t *r,
+    ngx_http_upstream_local_t *local)
+{
+    ngx_int_t    rc;
+    ngx_str_t    val;
+    ngx_addr_t  *addr;
+
+    if (local == NULL) {
+        return NULL;
+    }
+
+    if (local->value == NULL) {
+        return local->addr;
+    }
+
+    if (ngx_http_complex_value(r, local->value, &val) != NGX_OK) {
+        return NULL;
+    }
+
+    if (val.len == 0) {
+        return NULL;
+    }
+
+    addr = ngx_palloc(r->pool, sizeof(ngx_addr_t));
+    if (addr == NULL) {
+        return NULL;
+    }
+
+    rc = ngx_parse_addr(r->pool, addr, val.data, val.len);
+
+    switch (rc) {
+    case NGX_OK:
+        addr->name = val;
+        return addr;
+
+    case NGX_DECLINED:
+        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                      "invalid local address \"%V\"", &val);
+        /* fall through */
+
+    default:
+        return NULL;
+    }
+}
+
+
 char *
 ngx_http_upstream_param_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf)

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_upstream.h (+11 -1) 97%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_upstream.h    2013-07-22 11:05:55 +0900 (f32c985)
+++ vendor/nginx-1.4.2/src/http/ngx_http_upstream.h    2013-07-22 13:32:39 +0900 (29ebf9b)
@@ -116,10 +116,17 @@ struct ngx_http_upstream_srv_conf_s {
     ngx_uint_t                       line;
     in_port_t                        port;
     in_port_t                        default_port;
+    ngx_uint_t                       no_port;  /* unsigned no_port:1 */
 };
 
 
 typedef struct {
+    ngx_addr_t                      *addr;
+    ngx_http_complex_value_t        *value;
+} ngx_http_upstream_local_t;
+
+
+typedef struct {
     ngx_http_upstream_srv_conf_t    *upstream;
 
     ngx_msec_t                       connect_timeout;
@@ -157,7 +164,7 @@ typedef struct {
     ngx_array_t                     *hide_headers;
     ngx_array_t                     *pass_headers;
 
-    ngx_addr_t                      *local;
+    ngx_http_upstream_local_t       *local;
 
 #if (NGX_HTTP_CACHE)
     ngx_shm_zone_t                  *cache;
@@ -277,6 +284,8 @@ struct ngx_http_upstream_s {
 
     ngx_http_upstream_resolved_t    *resolved;
 
+    ngx_buf_t                        from_client;
+
     ngx_buf_t                        buffer;
     off_t                            length;
 
@@ -322,6 +331,7 @@ struct ngx_http_upstream_s {
 
     unsigned                         buffering:1;
     unsigned                         keepalive:1;
+    unsigned                         upgrade:1;
 
     unsigned                         request_sent:1;
     unsigned                         header_sent:1;

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_upstream_round_robin.c (+9 -51) 92%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_upstream_round_robin.c    2013-07-22 11:05:55 +0900 (4b78cff)
+++ vendor/nginx-1.4.2/src/http/ngx_http_upstream_round_robin.c    2013-07-22 13:32:39 +0900 (e0c6c58)
@@ -10,8 +10,6 @@
 #include <ngx_http.h>
 
 
-static ngx_int_t ngx_http_upstream_cmp_servers(const void *one,
-    const void *two);
 static ngx_http_upstream_rr_peer_t *ngx_http_upstream_get_peer(
     ngx_http_upstream_rr_peer_data_t *rrp);
 
@@ -93,10 +91,6 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
 
         us->peer.data = peers;
 
-        ngx_sort(&peers->peer[0], (size_t) n,
-                 sizeof(ngx_http_upstream_rr_peer_t),
-                 ngx_http_upstream_cmp_servers);
-
         /* backup servers */
 
         n = 0;
@@ -151,17 +145,13 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
 
         peers->next = backup;
 
-        ngx_sort(&backup->peer[0], (size_t) n,
-                 sizeof(ngx_http_upstream_rr_peer_t),
-                 ngx_http_upstream_cmp_servers);
-
         return NGX_OK;
     }
 
 
     /* an upstream implicitly defined by proxy_pass, etc. */
 
-    if (us->port == 0 && us->default_port == 0) {
+    if (us->port == 0) {
         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                       "no port in upstream \"%V\" in %s:%ui",
                       &us->host, us->file_name, us->line);
@@ -171,7 +161,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
     ngx_memzero(&u, sizeof(ngx_url_t));
 
     u.host = us->host;
-    u.port = (in_port_t) (us->port ? us->port : us->default_port);
+    u.port = us->port;
 
     if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
         if (u.err) {
@@ -216,18 +206,6 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
 }
 
 
-static ngx_int_t
-ngx_http_upstream_cmp_servers(const void *one, const void *two)
-{
-    ngx_http_upstream_rr_peer_t  *first, *second;
-
-    first = (ngx_http_upstream_rr_peer_t *) one;
-    second = (ngx_http_upstream_rr_peer_t *) two;
-
-    return (first->weight < second->weight);
-}
-
-
 ngx_int_t
 ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,
     ngx_http_upstream_srv_conf_t *us)
@@ -395,7 +373,6 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
 
     ngx_int_t                      rc;
     ngx_uint_t                     i, n;
-    ngx_connection_t              *c;
     ngx_http_upstream_rr_peer_t   *peer;
     ngx_http_upstream_rr_peers_t  *peers;
 
@@ -404,26 +381,6 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
 
     /* ngx_lock_mutex(rrp->peers->mutex); */
 
-    if (rrp->peers->last_cached) {
-
-        /* cached connection */
-
-        c = rrp->peers->cached[rrp->peers->last_cached];
-        rrp->peers->last_cached--;
-
-        /* ngx_unlock_mutex(ppr->peers->mutex); */
-
-#if (NGX_THREADS)
-        c->read->lock = c->read->own_lock;
-        c->write->lock = c->write->own_lock;
-#endif
-
-        pc->connection = c;
-        pc->cached = 1;
-
-        return NGX_OK;
-    }
-
     pc->cached = 0;
     pc->connection = NULL;
 
@@ -474,7 +431,9 @@ failed:
         rrp->peers = peers->next;
         pc->tries = rrp->peers->number;
 
-        n = rrp->peers->number / (8 * sizeof(uintptr_t)) + 1;
+        n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
+                / (8 * sizeof(uintptr_t));
+
         for (i = 0; i < n; i++) {
              rrp->tried[i] = 0;
         }
@@ -564,7 +523,10 @@ ngx_http_upstream_get_peer(ngx_http_upstream_rr_peer_data_t *rrp)
     rrp->tried[n] |= m;
 
     best->current_weight -= total;
-    best->checked = now;
+
+    if (now - best->checked > best->fail_timeout) {
+        best->checked = now;
+    }
 
     return best;
 }
@@ -582,10 +544,6 @@ ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data,
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    "free rr peer %ui %ui", pc->tries, state);
 
-    if (state == 0 && pc->tries == 0) {
-        return;
-    }
-
     /* TODO: NGX_PEER_KEEPALIVE */
 
     if (rrp->peers->single) {

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_upstream_round_robin.h (+0 -2) 96%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_upstream_round_robin.h    2013-07-22 11:05:55 +0900 (3f8cbf8)
+++ vendor/nginx-1.4.2/src/http/ngx_http_upstream_round_robin.h    2013-07-22 13:32:39 +0900 (ea90ab9)
@@ -42,10 +42,8 @@ typedef struct ngx_http_upstream_rr_peers_s  ngx_http_upstream_rr_peers_t;
 
 struct ngx_http_upstream_rr_peers_s {
     ngx_uint_t                      number;
-    ngx_uint_t                      last_cached;
 
  /* ngx_mutex_t                    *mutex; */
-    ngx_connection_t              **cached;
 
     ngx_uint_t                      total_weight;
 

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_variables.c (+186 -12) 91%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_variables.c    2013-07-22 11:05:55 +0900 (298064a)
+++ vendor/nginx-1.4.2/src/http/ngx_http_variables.c    2013-07-22 13:32:39 +0900 (6f1e034)
@@ -21,8 +21,13 @@ static void ngx_http_variable_request_set_size(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+
+static ngx_int_t ngx_http_variable_cookies(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_headers_internal(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data, u_char sep);
 
 static ngx_int_t ngx_http_variable_unknown_header_in(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
@@ -39,6 +44,8 @@ static ngx_int_t ngx_http_variable_tcpinfo(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 #endif
 
+static ngx_int_t ngx_http_variable_content_length(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_host(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_binary_remote_addr(ngx_http_request_t *r,
@@ -73,12 +80,16 @@ static ngx_int_t ngx_http_variable_bytes_sent(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_pipe(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_request_body(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_request_body_file(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_request_length(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_request_time(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r,
@@ -112,6 +123,10 @@ static ngx_int_t ngx_http_variable_pid(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_msec(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_time_iso8601(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_time_local(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 
 /*
  * TODO:
@@ -123,8 +138,8 @@ static ngx_int_t ngx_http_variable_msec(ngx_http_request_t *r,
  */
 
 /*
- * the $http_host, $http_user_agent, $http_referer, $http_via,
- * and $http_x_forwarded_for variables may be handled by generic
+ * the $http_host, $http_user_agent, $http_referer, and $http_via
+ * variables may be handled by generic
  * ngx_http_variable_unknown_header_in(), but for performance reasons
  * they are handled using dedicated entries
  */
@@ -146,15 +161,15 @@ static ngx_http_variable_t  ngx_http_core_variables[] = {
 #endif
 
 #if (NGX_HTTP_X_FORWARDED_FOR)
-    { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_header,
+    { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_headers,
       offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 },
 #endif
 
-    { ngx_string("http_cookie"), NULL, ngx_http_variable_headers,
+    { ngx_string("http_cookie"), NULL, ngx_http_variable_cookies,
       offsetof(ngx_http_request_t, headers_in.cookies), 0, 0 },
 
-    { ngx_string("content_length"), NULL, ngx_http_variable_header,
-      offsetof(ngx_http_request_t, headers_in.content_length), 0, 0 },
+    { ngx_string("content_length"), NULL, ngx_http_variable_content_length,
+      0, 0, 0 },
 
     { ngx_string("content_type"), NULL, ngx_http_variable_header,
       offsetof(ngx_http_request_t, headers_in.content_type), 0, 0 },
@@ -229,6 +244,9 @@ static ngx_http_variable_t  ngx_http_core_variables[] = {
     { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent,
       0, 0, 0 },
 
+    { ngx_string("pipe"), NULL, ngx_http_variable_pipe,
+      0, 0, 0 },
+
     { ngx_string("request_completion"), NULL,
       ngx_http_variable_request_completion,
       0, 0, 0 },
@@ -241,6 +259,9 @@ static ngx_http_variable_t  ngx_http_core_variables[] = {
       ngx_http_variable_request_body_file,
       0, 0, 0 },
 
+    { ngx_string("request_length"), NULL, ngx_http_variable_request_length,
+      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
     { ngx_string("request_time"), NULL, ngx_http_variable_request_time,
       0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
@@ -295,6 +316,12 @@ static ngx_http_variable_t  ngx_http_core_variables[] = {
     { ngx_string("msec"), NULL, ngx_http_variable_msec,
       0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
+    { ngx_string("time_iso8601"), NULL, ngx_http_variable_time_iso8601,
+      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
+    { ngx_string("time_local"), NULL, ngx_http_variable_time_local,
+      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
 #if (NGX_HAVE_TCP_INFO)
     { ngx_string("tcpinfo_rtt"), NULL, ngx_http_variable_tcpinfo,
       0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
@@ -328,6 +355,12 @@ ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
     ngx_http_variable_t        *v;
     ngx_http_core_main_conf_t  *cmcf;
 
+    if (name->len == 0) {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "invalid variable name \"$\"");
+        return NULL;
+    }
+
     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
 
     key = cmcf->variables_keys->keys.elts;
@@ -391,6 +424,12 @@ ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name)
     ngx_http_variable_t        *v;
     ngx_http_core_main_conf_t  *cmcf;
 
+    if (name->len == 0) {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "invalid variable name \"$\"");
+        return NGX_ERROR;
+    }
+
     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
 
     v = cmcf->variables.elts;
@@ -692,8 +731,24 @@ ngx_http_variable_header(ngx_http_request_t *r, ngx_http_variable_value_t *v,
 
 
 static ngx_int_t
-ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v,
-    uintptr_t data)
+ngx_http_variable_cookies(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    return ngx_http_variable_headers_internal(r, v, data, ';');
+}
+
+
+static ngx_int_t
+ngx_http_variable_headers(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    return ngx_http_variable_headers_internal(r, v, data, ',');
+}
+
+
+static ngx_int_t
+ngx_http_variable_headers_internal(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data, u_char sep)
 {
     size_t             len;
     u_char            *p, *end;
@@ -714,7 +769,7 @@ ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v,
             continue;
         }
 
-        len += h[i]->value.len + sizeof("; ") - 1;
+        len += h[i]->value.len + 2;
     }
 
     if (len == 0) {
@@ -722,7 +777,7 @@ ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v,
         return NGX_OK;
     }
 
-    len -= sizeof("; ") - 1;
+    len -= 2;
 
     v->valid = 1;
     v->no_cacheable = 0;
@@ -757,7 +812,7 @@ ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v,
             break;
         }
 
-        *p++ = ';'; *p++ = ' ';
+        *p++ = sep; *p++ = ' ';
     }
 
     return NGX_OK;
@@ -990,6 +1045,39 @@ ngx_http_variable_tcpinfo(ngx_http_request_t *r, ngx_http_variable_value_t *v,
 
 
 static ngx_int_t
+ngx_http_variable_content_length(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    u_char  *p;
+
+    if (r->headers_in.content_length) {
+        v->len = r->headers_in.content_length->value.len;
+        v->data = r->headers_in.content_length->value.data;
+        v->valid = 1;
+        v->no_cacheable = 0;
+        v->not_found = 0;
+
+    } else if (r->headers_in.content_length_n >= 0) {
+        p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN);
+        if (p == NULL) {
+            return NGX_ERROR;
+        }
+
+        v->len = ngx_sprintf(p, "%O", r->headers_in.content_length_n) - p;
+        v->data = p;
+        v->valid = 1;
+        v->no_cacheable = 0;
+        v->not_found = 0;
+
+    } else {
+        v->not_found = 1;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_variable_host(ngx_http_request_t *r, ngx_http_variable_value_t *v,
     uintptr_t data)
 {
@@ -1509,6 +1597,20 @@ ngx_http_variable_body_bytes_sent(ngx_http_request_t *r,
 
 
 static ngx_int_t
+ngx_http_variable_pipe(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    v->data = (u_char *) (r->pipeline ? "p" : ".");
+    v->len = 1;
+    v->valid = 1;
+    v->no_cacheable = 0;
+    v->not_found = 0;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_variable_status(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
 {
@@ -1666,7 +1768,11 @@ ngx_http_variable_sent_connection(ngx_http_request_t *r,
     size_t   len;
     char    *p;
 
-    if (r->keepalive) {
+    if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {
+        len = sizeof("upgrade") - 1;
+        p = "upgrade";
+
+    } else if (r->keepalive) {
         len = sizeof("keep-alive") - 1;
         p = "keep-alive";
 
@@ -1843,6 +1949,27 @@ ngx_http_variable_request_body_file(ngx_http_request_t *r,
 
 
 static ngx_int_t
+ngx_http_variable_request_length(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    u_char  *p;
+
+    p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN);
+    if (p == NULL) {
+        return NGX_ERROR;
+    }
+
+    v->len = ngx_sprintf(p, "%O", r->request_length) - p;
+    v->valid = 1;
+    v->no_cacheable = 0;
+    v->not_found = 0;
+    v->data = p;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_variable_request_time(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
 {
@@ -1986,6 +2113,53 @@ ngx_http_variable_msec(ngx_http_request_t *r,
 }
 
 
+static ngx_int_t
+ngx_http_variable_time_iso8601(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    u_char  *p;
+
+    p = ngx_pnalloc(r->pool, ngx_cached_http_log_iso8601.len);
+    if (p == NULL) {
+        return NGX_ERROR;
+    }
+
+    ngx_memcpy(p, ngx_cached_http_log_iso8601.data,
+               ngx_cached_http_log_iso8601.len);
+
+    v->len = ngx_cached_http_log_iso8601.len;
+    v->valid = 1;
+    v->no_cacheable = 0;
+    v->not_found = 0;
+    v->data = p;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_variable_time_local(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    u_char  *p;
+
+    p = ngx_pnalloc(r->pool, ngx_cached_http_log_time.len);
+    if (p == NULL) {
+        return NGX_ERROR;
+    }
+
+    ngx_memcpy(p, ngx_cached_http_log_time.data, ngx_cached_http_log_time.len);
+
+    v->len = ngx_cached_http_log_time.len;
+    v->valid = 1;
+    v->no_cacheable = 0;
+    v->not_found = 0;
+    v->data = p;
+
+    return NGX_OK;
+}
+
+
 void *
 ngx_http_map_find(ngx_http_request_t *r, ngx_http_map_t *map, ngx_str_t *match)
 {

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_variables.h (+0 -3) 97%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_variables.h    2013-07-22 11:05:55 +0900 (d2bb4db)
+++ vendor/nginx-1.4.2/src/http/ngx_http_variables.h    2013-07-22 13:32:39 +0900 (829fab3)
@@ -57,9 +57,6 @@ ngx_int_t ngx_http_variable_unknown_header(ngx_http_variable_value_t *v,
     ngx_str_t *var, ngx_list_part_t *part, size_t prefix);
 
 
-#define ngx_http_clear_variable(r, index) r->variables0[index].text.data = NULL;
-
-
 #if (NGX_PCRE)
 
 typedef struct {

  Renamed: vendor/nginx-1.4.2/src/http/ngx_http_write_filter_module.c (+1 -1) 99%
===================================================================
--- vendor/nginx-1.2.6/src/http/ngx_http_write_filter_module.c    2013-07-22 11:05:55 +0900 (fd44bc6)
+++ vendor/nginx-1.4.2/src/http/ngx_http_write_filter_module.c    2013-07-22 13:32:39 +0900 (5594c7f)
@@ -207,7 +207,7 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
     }
 
     if (r->limit_rate) {
-        limit = r->limit_rate * (ngx_time() - r->start_sec + 1)
+        limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1)
                 - (c->sent - clcf->limit_rate_after);
 
         if (limit <= 0) {

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

  Renamed: vendor/nginx-1.4.2/src/mail/ngx_mail.h (+2 -2) 99%
===================================================================
--- vendor/nginx-1.2.6/src/mail/ngx_mail.h    2013-07-22 11:05:55 +0900 (1fceb42)
+++ vendor/nginx-1.4.2/src/mail/ngx_mail.h    2013-07-22 13:32:39 +0900 (ccdfb8c)
@@ -39,7 +39,7 @@ typedef struct {
     unsigned                ssl:1;
 #endif
 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
-    unsigned                ipv6only:2;
+    unsigned                ipv6only:1;
 #endif
     unsigned                so_keepalive:2;
 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
@@ -100,7 +100,7 @@ typedef struct {
     unsigned                ssl:1;
 #endif
 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
-    unsigned                ipv6only:2;
+    unsigned                ipv6only:1;
 #endif
     unsigned                so_keepalive:2;
 #if (NGX_HAVE_KEEPALIVE_TUNABLE)

  Renamed: vendor/nginx-1.4.2/src/mail/ngx_mail_auth_http_module.c (+35 -25) 97%
===================================================================
--- vendor/nginx-1.2.6/src/mail/ngx_mail_auth_http_module.c    2013-07-22 11:05:55 +0900 (d2bd4ad)
+++ vendor/nginx-1.4.2/src/mail/ngx_mail_auth_http_module.c    2013-07-22 13:32:39 +0900 (2e9b9f2)
@@ -454,12 +454,15 @@ static void
 ngx_mail_auth_http_process_headers(ngx_mail_session_t *s,
     ngx_mail_auth_http_ctx_t *ctx)
 {
-    u_char              *p;
-    time_t               timer;
-    size_t               len, size;
-    ngx_int_t            rc, port, n;
-    ngx_addr_t          *peer;
-    struct sockaddr_in  *sin;
+    u_char               *p;
+    time_t                timer;
+    size_t                len, size;
+    ngx_int_t             rc, port, n;
+    ngx_addr_t           *peer;
+    struct sockaddr_in   *sin;
+#if (NGX_HAVE_INET6)
+    struct sockaddr_in6  *sin6;
+#endif
 
     ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
                    "mail auth http process headers");
@@ -772,17 +775,26 @@ ngx_mail_auth_http_process_headers(ngx_mail_session_t *s,
                 return;
             }
 
-            /* AF_INET only */
+            rc = ngx_parse_addr(s->connection->pool, peer,
+                                ctx->addr.data, ctx->addr.len);
+
+            switch (rc) {
+            case NGX_OK:
+                break;
 
-            sin = ngx_pcalloc(s->connection->pool, sizeof(struct sockaddr_in));
-            if (sin == NULL) {
+            case NGX_DECLINED:
+                ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+                              "auth http server %V sent invalid server "
+                              "address:\"%V\"",
+                              ctx->peer.name, &ctx->addr);
+                /* fall through */
+
+            default:
                 ngx_destroy_pool(ctx->pool);
                 ngx_mail_session_internal_server_error(s);
                 return;
             }
 
-            sin->sin_family = AF_INET;
-
             port = ngx_atoi(ctx->port.data, ctx->port.len);
             if (port == NGX_ERROR || port < 1 || port > 65535) {
                 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
@@ -794,21 +806,20 @@ ngx_mail_auth_http_process_headers(ngx_mail_session_t *s,
                 return;
             }
 
-            sin->sin_port = htons((in_port_t) port);
+            switch (peer->sockaddr->sa_family) {
 
-            sin->sin_addr.s_addr = ngx_inet_addr(ctx->addr.data, ctx->addr.len);
-            if (sin->sin_addr.s_addr == INADDR_NONE) {
-                ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
-                              "auth http server %V sent invalid server "
-                              "address:\"%V\"",
-                              ctx->peer.name, &ctx->addr);
-                ngx_destroy_pool(ctx->pool);
-                ngx_mail_session_internal_server_error(s);
-                return;
-            }
+#if (NGX_HAVE_INET6)
+            case AF_INET6:
+                sin6 = (struct sockaddr_in6 *) peer->sockaddr;
+                sin6->sin6_port = htons((in_port_t) port);
+                break;
+#endif
 
-            peer->sockaddr = (struct sockaddr *) sin;
-            peer->socklen = sizeof(struct sockaddr_in);
+            default: /* AF_INET */
+                sin = (struct sockaddr_in *) peer->sockaddr;
+                sin->sin_port = htons((in_port_t) port);
+                break;
+            }
 
             len = ctx->addr.len + 1 + ctx->port.len;
 
@@ -1388,7 +1399,6 @@ ngx_mail_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     u.url = value[1];
     u.default_port = 80;
     u.uri_part = 1;
-    u.one_addr = 1;
 
     if (ngx_strncmp(u.url.data, "http://", 7) == 0) {
         u.url.len -= 7;

  Renamed: vendor/nginx-1.4.2/src/mail/ngx_mail_core_module.c (+5 -1) 99%
===================================================================
--- vendor/nginx-1.2.6/src/mail/ngx_mail_core_module.c    2013-07-22 11:05:55 +0900 (6509b98)
+++ vendor/nginx-1.4.2/src/mail/ngx_mail_core_module.c    2013-07-22 13:32:39 +0900 (be8673c)
@@ -382,6 +382,10 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     ls->wildcard = u.wildcard;
     ls->ctx = cf->ctx;
 
+#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
+    ls->ipv6only = 1;
+#endif
+
     if (cscf->protocol == NULL) {
         for (m = 0; ngx_modules[m]; m++) {
             if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
@@ -423,7 +427,7 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                     ls->ipv6only = 1;
 
                 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
-                    ls->ipv6only = 2;
+                    ls->ipv6only = 0;
 
                 } else {
                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  Renamed: vendor/nginx-1.4.2/src/os/unix/ngx_files.c (+1 -1) 99%
===================================================================
--- vendor/nginx-1.2.6/src/os/unix/ngx_files.c    2013-07-22 11:05:55 +0900 (4fdf884)
+++ vendor/nginx-1.4.2/src/os/unix/ngx_files.c    2013-07-22 13:32:39 +0900 (c3ae47f)
@@ -363,7 +363,7 @@ ngx_open_glob(ngx_glob_t *gl)
 {
     int  n;
 
-    n = glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob);
+    n = glob((char *) gl->pattern, 0, NULL, &gl->pglob);
 
     if (n == 0) {
         return NGX_OK;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  Renamed: vendor/nginx-1.4.2/src/os/unix/ngx_process_cycle.c (+1 -1) 99%
===================================================================
--- vendor/nginx-1.2.6/src/os/unix/ngx_process_cycle.c    2013-07-22 11:05:55 +0900 (c9b0266)
+++ vendor/nginx-1.4.2/src/os/unix/ngx_process_cycle.c    2013-07-22 13:32:39 +0900 (dfdfae0)
@@ -647,7 +647,7 @@ ngx_reap_children(ngx_cycle_t *cycle)
 
                 if (ngx_rename_file((char *) ccf->oldpid.data,
                                     (char *) ccf->pid.data)
-                    != NGX_OK)
+                    == NGX_FILE_ERROR)
                 {
                     ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                                   ngx_rename_file_n " %s back to %s failed "

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  Renamed: vendor/nginx-1.4.2/src/os/unix/ngx_user.c (+13 -14) 80%
===================================================================
--- vendor/nginx-1.2.6/src/os/unix/ngx_user.c    2013-07-22 11:05:55 +0900 (27f990e)
+++ vendor/nginx-1.4.2/src/os/unix/ngx_user.c    2013-07-22 13:32:39 +0900 (7a71203)
@@ -28,30 +28,27 @@ ngx_libc_crypt(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
 {
     char               *value;
     size_t              len;
-    ngx_err_t           err;
     struct crypt_data   cd;
 
-    ngx_set_errno(0);
-
     cd.initialized = 0;
     /* work around the glibc bug */
     cd.current_salt[0] = ~salt[0];
 
     value = crypt_r((char *) key, (char *) salt, &cd);
 
-    err = ngx_errno;
-
-    if (err == 0) {
+    if (value) {
         len = ngx_strlen(value) + 1;
 
         *encrypted = ngx_pnalloc(pool, len);
-        if (*encrypted) {
-            ngx_memcpy(*encrypted, value, len);
-            return NGX_OK;
+        if (*encrypted == NULL) {
+            return NGX_ERROR;
         }
+
+        ngx_memcpy(*encrypted, value, len);
+        return NGX_OK;
     }
 
-    ngx_log_error(NGX_LOG_CRIT, pool->log, err, "crypt_r() failed");
+    ngx_log_error(NGX_LOG_CRIT, pool->log, ngx_errno, "crypt_r() failed");
 
     return NGX_ERROR;
 }
@@ -75,18 +72,20 @@ ngx_libc_crypt(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
 
 #endif
 
-    ngx_set_errno(0);
-
     value = crypt((char *) key, (char *) salt);
 
     if (value) {
         len = ngx_strlen(value) + 1;
 
         *encrypted = ngx_pnalloc(pool, len);
-        if (*encrypted) {
-            ngx_memcpy(*encrypted, value, len);
+        if (*encrypted == NULL) {
+#if (NGX_THREADS && NGX_NONREENTRANT_CRYPT)
+            ngx_mutex_unlock(ngx_crypt_mutex);
+#endif
+            return NGX_ERROR;
         }
 
+        ngx_memcpy(*encrypted, value, len);
 #if (NGX_THREADS && NGX_NONREENTRANT_CRYPT)
         ngx_mutex_unlock(ngx_crypt_mutex);
 #endif

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

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

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




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