aboutsummaryrefslogtreecommitdiff
path: root/net/nginx
diff options
context:
space:
mode:
authorThomas Heil <heil@terminal-consulting.de>2014-06-23 16:37:24 +0200
committerThomas Heil <heil@terminal-consulting.de>2014-06-23 16:37:24 +0200
commite9da522f68ab4553ad16c077a59a38171664fdd3 (patch)
tree1878f42fa3bc9c26cc2ac473a8e5e5f8f07f4092 /net/nginx
parente273fef7a7ab30943d9fd7d3edbd41e764282e1e (diff)
nginx: import from packages, add myself as the maintainer
This adds the nginx package from the old svn package fee. I adopt the licensing information and will maintain the package in the future. This request also updates nginx to the last stable version 1.4.7. It further adds support for - naxsi (the ngix web application firewall) - syslog module - http upstream check module - support for the haproxy Proxy Protocol (this way nginx can see the real ip address behind haproxy) Building was tested with target x86_64, ar71xx and avr32. Signed-off-by: Thomas Heil <heil@terminal-consulting.de>
Diffstat (limited to 'net/nginx')
-rw-r--r--net/nginx/Config.in187
-rw-r--r--net/nginx/Makefile334
-rw-r--r--net/nginx/files/nginx.init24
-rw-r--r--net/nginx/files/nginx.proxyprotocol.example40
-rw-r--r--net/nginx/files/nginx.syslog.example59
-rw-r--r--net/nginx/patches-lua-nginx/300-ldl.patch21
-rw-r--r--net/nginx/patches-nginx-upstream-check/check_1.2.6+.patch209
-rw-r--r--net/nginx/patches/101-feature_test_fix.patch107
-rw-r--r--net/nginx/patches/102-sizeof_test_fix.patch26
-rw-r--r--net/nginx/patches/103-sys_nerr.patch12
-rw-r--r--net/nginx/patches/200-config.patch18
-rw-r--r--net/nginx/patches/300-crosscompile_ccflags.patch33
-rw-r--r--net/nginx/patches/400-nginx-1.4.x_proxy_protocol_patch_v2.patch1194
-rw-r--r--net/nginx/patches/401-nginx-1.4.0-syslog.patch698
14 files changed, 2962 insertions, 0 deletions
diff --git a/net/nginx/Config.in b/net/nginx/Config.in
new file mode 100644
index 000000000..1b6062615
--- /dev/null
+++ b/net/nginx/Config.in
@@ -0,0 +1,187 @@
+#
+# Copyright (C) 2010-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+menu "Configuration"
+ depends on PACKAGE_nginx
+
+config NGINX_STUB_STATUS
+ bool
+ prompt "Enable stub status module"
+ help
+ Enable the stub status module which gives some status from the server.
+
+config NGINX_FLV
+ bool
+ prompt "Enable FLV module"
+ help
+ Provides the ability to seek within FLV (Flash) files using time-based offsets.
+
+config NGINX_SSL
+ bool
+ prompt "Enable SSL module"
+ help
+ Enable HTTPS/SSL support.
+
+config NGINX_DAV
+ bool
+ prompt "Enable WebDAV module"
+ help
+ Enable the HTTP and WebDAV methods PUT, DELETE, MKCOL, COPY and MOVE.
+
+config NGINX_LUA
+ bool
+ prompt "Enable LUA module"
+ help
+ Enable support for LUA scripts.
+
+config NGINX_PCRE
+ bool
+ prompt "Enable PCRE library usage"
+ default y
+
+config NGINX_HTTP_CACHE
+ bool
+ prompt "Enable HTTP cache"
+
+config NGINX_HTTP_CHARSET
+ bool
+ prompt "Enable HTTP charset module"
+ default y
+
+config NGINX_HTTP_GZIP
+ bool
+ prompt "Enable HTTP gzip module"
+ default y
+
+config NGINX_HTTP_SSI
+ bool
+ prompt "Enable HTTP ssi module"
+ default y
+
+config NGINX_HTTP_USERID
+ bool
+ prompt "Enable HTTP userid module"
+ default y
+
+config NGINX_HTTP_ACCESS
+ bool
+ prompt "Enable HTTP access module"
+ default y
+
+config NGINX_HTTP_AUTH_BASIC
+ bool
+ prompt "Enable HTTP auth basic"
+ default y
+
+config NGINX_HTTP_AUTOINDEX
+ bool
+ prompt "Enable HTTP autoindex module"
+ default y
+
+config NGINX_HTTP_GEO
+ bool
+ prompt "Enable HTTP geo module"
+ default y
+
+config NGINX_HTTP_MAP
+ bool
+ prompt "Enable HTTP map module"
+ default y
+
+config NGINX_HTTP_SPLIT_CLIENTS
+ bool
+ prompt "Enable HTTP split clients"
+ default y
+
+config NGINX_HTTP_REFERER
+ bool
+ prompt "Enable HTTP referer module"
+ default y
+
+config NGINX_HTTP_REWRITE
+ bool
+ prompt "Enable HTTP rewrite module"
+ select NGINX_PCRE
+ default y
+
+config NGINX_HTTP_PROXY
+ bool
+ prompt "Enable HTTP proxy module"
+ default y
+
+config NGINX_HTTP_FASTCGI
+ bool
+ prompt "Enable HTTP fastcgi module"
+ default y
+
+config NGINX_HTTP_UWSGI
+ bool
+ prompt "Enable HTTP uwsgi module"
+ default y
+
+config NGINX_HTTP_SCGI
+ bool
+ prompt "Enable HTTP scgi module"
+ default y
+
+config NGINX_HTTP_MEMCACHED
+ bool
+ prompt "Enable HTTP memcached module"
+ default y
+
+config NGINX_HTTP_LIMIT_CONN
+ bool
+ prompt "Enable HTTP limit conn"
+ default y
+
+config NGINX_HTTP_LIMIT_REQ
+ bool
+ prompt "Enable HTTP limit req"
+ default y
+
+config NGINX_HTTP_EMPTY_GIF
+ bool
+ prompt "Enable HTTP empty gif"
+ default y
+
+config NGINX_HTTP_BROWSER
+ bool
+ prompt "Enable HTTP browser module"
+ default y
+
+config NGINX_HTTP_UPSTREAM_IP_HASH
+ bool
+ prompt "Enable HTTP IP hash module"
+ default y
+
+config NGINX_NAXSI
+ bool
+ prompt "Enable NAXSI module"
+ select PACKAGE_nginx-naxsi
+ help
+ Enable support for NAXSI WAF.
+
+config NGINX_PROXYPROTOCOL
+ bool
+ prompt "Enable NAXSI proxyprotocol"
+ select PACKAGE_nginx-proxyprotocol
+ help
+ Enable support for NAXSI WAF.
+
+config NGINX_SYSLOG
+ bool
+ prompt "Enable Syslog module"
+ select PACKAGE_nginx-syslog
+ help
+ Provides the ability log to a remote destination
+
+config NGINX_HTTP_UPSTREAM_CHECK
+ bool
+ prompt "Enable HTTP upstream check module"
+ default y
+
+endmenu
diff --git a/net/nginx/Makefile b/net/nginx/Makefile
new file mode 100644
index 000000000..06d92758b
--- /dev/null
+++ b/net/nginx/Makefile
@@ -0,0 +1,334 @@
+#
+# Copyright (C) 2009-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nginx
+PKG_VERSION:=1.4.7
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://nginx.org/download/
+PKG_MD5SUM:=aee151d298dcbfeb88b3f7dd3e7a4d17
+PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
+PKG_LICENSE:=2-clause BSD-like license
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+PKG_CONFIG_DEPENDS := \
+ CONFIG_NGINX_STUB_STATUS \
+ CONFIG_NGINX_FLV \
+ CONFIG_NGINX_SSL \
+ CONFIG_NGINX_DAV \
+ CONFIG_NGINX_LUA \
+ CONFIG_NGINX_PCRE \
+ CONFIG_NGINX_HTTP_CACHE \
+ CONFIG_NGINX_HTTP_CHARSET \
+ CONFIG_NGINX_HTTP_GZIP \
+ CONFIG_NGINX_HTTP_SSI \
+ CONFIG_NGINX_HTTP_USERID \
+ CONFIG_NGINX_HTTP_ACCESS \
+ CONFIG_NGINX_HTTP_AUTH_BASIC \
+ CONFIG_NGINX_HTTP_AUTOINDEX \
+ CONFIG_NGINX_HTTP_GEO \
+ CONFIG_NGINX_HTTP_MAP \
+ CONFIG_NGINX_HTTP_SPLIT_CLIENTS \
+ CONFIG_NGINX_HTTP_REFERER \
+ CONFIG_NGINX_HTTP_REWRITE \
+ CONFIG_NGINX_HTTP_PROXY \
+ CONFIG_NGINX_HTTP_FASTCGI \
+ CONFIG_NGINX_HTTP_UWSGI \
+ CONFIG_NGINX_HTTP_SCGI \
+ CONFIG_NGINX_HTTP_MEMCACHED \
+ CONFIG_NGINX_HTTP_LIMIT_CONN \
+ CONFIG_NGINX_HTTP_LIMIT_REQ \
+ CONFIG_NGINX_HTTP_EMPTY_GIF \
+ CONFIG_NGINX_HTTP_BROWSER \
+ CONFIG_NGINX_HTTP_UPSTREAM_IP_HASH
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/nginx
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Web Servers/Proxies
+ TITLE:=Nginx web server
+ URL:=http://nginx.org/
+ DEPENDS:=+NGINX_PCRE:libpcre +(NGINX_SSL||NGINX_HTTP_CACHE||NGINX_HTTP_AUTH_BASIC):libopenssl +NGINX_HTTP_GZIP:zlib +libpthread +NGINX_LUA:liblua
+ MENU:=1
+endef
+
+define Package/nginx/description
+ nginx is an HTTP and reverse proxy server, as well as a mail proxy server,
+ written by Igor Sysoev.
+endef
+
+define Package/nginx/config
+ source "$(SOURCE)/Config.in"
+endef
+
+config_files=nginx.conf mime.types fastcgi_params koi-utf koi-win win-utf
+
+define Package/nginx/conffiles
+/etc/nginx/
+endef
+
+ADDITIONAL_MODULES:=
+ifeq ($(CONFIG_NGINX_NAXSI),y)
+ ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-naxsi/naxsi_src
+endif
+ifeq ($(CONFIG_IPV6),y)
+ ADDITIONAL_MODULES += --with-ipv6
+endif
+ifeq ($(CONFIG_NGINX_STUB_STATUS),y)
+ ADDITIONAL_MODULES += --with-http_stub_status_module
+endif
+ifeq ($(CONFIG_NGINX_FLV),y)
+ ADDITIONAL_MODULES += --with-http_flv_module
+endif
+ifeq ($(CONFIG_NGINX_SSL),y)
+ ADDITIONAL_MODULES += --with-http_ssl_module
+endif
+ifeq ($(CONFIG_NGINX_DAV),y)
+ ADDITIONAL_MODULES += --with-http_dav_module
+endif
+ifeq ($(CONFIG_NGINX_LUA),y)
+ ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/lua-nginx
+endif
+ifneq ($(CONFIG_NGINX_HTTP_CACHE),y)
+ ADDITIONAL_MODULES += --without-http-cache
+endif
+ifneq ($(CONFIG_NGINX_PCRE),y)
+ ADDITIONAL_MODULES += --without-pcre
+endif
+ifneq ($(CONFIG_NGINX_HTTP_CHARSET),y)
+ ADDITIONAL_MODULES += --without-http_charset_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_GZIP),y)
+ ADDITIONAL_MODULES += --without-http_gzip_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_SSI),y)
+ ADDITIONAL_MODULES += --without-http_ssi_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_USERID),y)
+ ADDITIONAL_MODULES += --without-http_userid_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_ACCESS),y)
+ ADDITIONAL_MODULES += --without-http_access_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_AUTH_BASIC),y)
+ ADDITIONAL_MODULES += --without-http_auth_basic_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_AUTOINDEX),y)
+ ADDITIONAL_MODULES += --without-http_autoindex_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_GEO),y)
+ ADDITIONAL_MODULES += --without-http_geo_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_MAP),y)
+ ADDITIONAL_MODULES += --without-http_map_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_SPLIT_CLIENTS),y)
+ ADDITIONAL_MODULES += --without-http_split_clients_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_REFERER),y)
+ ADDITIONAL_MODULES += --without-http_referer_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_REWRITE),y)
+ ADDITIONAL_MODULES += --without-http_rewrite_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_PROXY),y)
+ ADDITIONAL_MODULES += --without-http_proxy_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_FASTCGI),y)
+ ADDITIONAL_MODULES += --without-http_fastcgi_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_UWSGI),y)
+ ADDITIONAL_MODULES += --without-http_uwsgi_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_SCGI),y)
+ ADDITIONAL_MODULES += --without-http_scgi_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_MEMCACHED),y)
+ ADDITIONAL_MODULES += --without-http_memcached_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_LIMIT_CONN),y)
+ ADDITIONAL_MODULES += --without-http_limit_conn_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_LIMIT_REQ),y)
+ ADDITIONAL_MODULES += --without-http_limit_req_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_EMPTY_GIF),y)
+ ADDITIONAL_MODULES += --without-http_empty_gif_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_BROWSER),y)
+ ADDITIONAL_MODULES += --without-http_browser_module
+endif
+ifneq ($(CONFIG_NGINX_HTTP_UPSTREAM_IP_HASH),y)
+ ADDITIONAL_MODULES += --without-http_upstream_ip_hash_module
+endif
+ifeq ($(CONFIG_NGINX_PROXYPROTOCOL),y)
+ ADDITIONAL_MODULES += --with-proxy-protocol
+endif
+ifeq ($(CONFIG_NGINX_SYSLOG),y)
+ ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-syslog
+endif
+ifeq ($(CONFIG_NGINX_HTTP_UPSTREAM_CHECK),y)
+ ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-upstream-check
+endif
+
+define Build/Configure
+ # TODO: fix --crossbuild
+ (cd $(PKG_BUILD_DIR) ;\
+ $(if $(CONFIG_NGINX_LUA),LUA_INC=$(STAGING_DIR)/usr/include LUA_LIB=$(STAGING_DIR)/usr/lib) \
+ ./configure \
+ --crossbuild=Linux::$(ARCH) \
+ --prefix=/usr \
+ --conf-path=/etc/nginx/nginx.conf \
+ $(ADDITIONAL_MODULES) \
+ --error-log-path=/var/log/nginx/error.log \
+ --pid-path=/var/run/nginx.pid \
+ --lock-path=/var/lock/nginx.lock \
+ --http-log-path=/var/log/nginx/access.log \
+ --http-client-body-temp-path=/var/lib/nginx/body \
+ --http-proxy-temp-path=/var/lib/nginx/proxy \
+ --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
+ --with-cc="$(TARGET_CC)" \
+ --with-cc-opt="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
+ --with-ld-opt="$(TARGET_LDFLAGS)" )
+endef
+
+define Package/nginx/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/nginx $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/etc/nginx
+ $(INSTALL_DATA) $(addprefix $(PKG_INSTALL_DIR)/etc/nginx/,$(config_files)) $(1)/etc/nginx/
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/nginx.init $(1)/etc/init.d/nginx
+endef
+
+define Build/Prepare
+ $(call Build/Prepare/Default)
+ $(if $(CONFIG_NGINX_LUA),$(call Prepare/lua-nginx))
+ $(if $(CONFIG_NGINX_NAXSI),$(call Prepare/nginx-naxsi))
+ $(if $(CONFIG_NGINX_SYSLOG),$(call Prepare/nginx-syslog))
+ $(if $(CONFIG_NGINX_HTTP_UPSTREAM_CHECK),$(call Prepare/nginx-upstream-check))
+endef
+
+define Download/lua-nginx
+ VERSION:=d3ab0edd45bffe1b9a36abdf5bff544de436ccee
+ SUBDIR:=lua-nginx
+ FILE:=lua-nginx-module-$(PKG_VERSION)-$$(VERSION).tar.gz
+ URL:=https://github.com/chaoslawful/lua-nginx-module.git
+ PROTO:=git
+endef
+
+define Prepare/lua-nginx
+ $(eval $(call Download,lua-nginx))
+ gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
+ $(call PatchDir,$(PKG_BUILD_DIR),./patches-lua-nginx)
+endef
+
+define Download/nginx-upstream-check
+ VERSION:=d40b9f956d9d978005bb15616d2f283d4e3d2031
+ SUBDIR:=nginx-upstream-check
+ FILE:=nginx-upstream-check-$(PKG_VERSION)-$$(VERSION).tar.gz
+ URL:=https://github.com/yaoweibin/nginx_upstream_check_module.git
+ PROTO:=git
+endef
+
+define Prepare/nginx-upstream-check
+ $(eval $(call Download,nginx-upstream-check))
+ gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
+ $(call PatchDir,$(PKG_BUILD_DIR),./patches-nginx-upstream-check)
+endef
+
+
+define Package/nginx-naxsi
+ MENU:=1
+ $(call Package/nginx)
+ TITLE+= nginx-naxsi
+ DEPENDS:=nginx
+endef
+
+define Package/nginx-naxsi/description
+ NGINX WAF NAXSI
+endef
+
+define Package/nginx-proxyprotocol
+ MENU:=1
+ $(call Package/nginx)
+ TITLE+= nginx-proxyprotocol
+ DEPENDS:=nginx
+endef
+
+define Package/nginx-proxyprotocol/description
+ IMPLEMENT Proxy Protocol
+endef
+
+define Package/nginx-syslog
+ MENU:=1
+ $(call Package/nginx)
+ TITLE+= nginx-syslog
+ DEPENDS:=nginx
+endef
+
+define Package/nginx-syslog/description
+ IMPLEMENT Syslog Protocol
+endef
+
+define Download/nginx-naxsi
+ VERSION:=34dcb45fe4fdcb144c5258d83672f8e1e1c8db2e
+ SUBDIR:=nginx-naxsi
+ FILE:=nginx-naxsi-module-$(PKG_VERSION)-$$(VERSION).tar.gz
+ URL:=https://github.com/nbs-system/naxsi.git
+ PROTO:=git
+endef
+
+define Prepare/nginx-naxsi
+ $(eval $(call Download,nginx-naxsi))
+ gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
+endef
+
+define Package/nginx-naxsi/install
+ $(INSTALL_DIR) $(1)/etc/nginx
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/nginx-naxsi/naxsi_config/naxsi_core.rules $(1)/etc/nginx
+ chmod 0640 $(1)/etc/nginx/naxsi_core.rules
+endef
+
+define Download/nginx-syslog
+ VERSION:=7abf48e52552c40a21463e1a8c608e0e575261cd
+ SUBDIR:=nginx-syslog
+ FILE:=nginx-syslog-module-$(PKG_VERSION)-$$(VERSION).tar.gz
+ URL:=https://github.com/splitice/nginx_syslog_patch.git
+ PROTO:=git
+endef
+
+define Prepare/nginx-syslog
+ $(eval $(call Download,nginx-syslog))
+ gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
+endef
+
+define Package/nginx-proxyprotocol/install
+ $(INSTALL_DIR) $(1)/etc/nginx
+ $(INSTALL_BIN) ./files/nginx.proxyprotocol.example $(1)/etc/nginx/nginx.conf.proxyprotocol
+ chmod 0640 $(1)/etc/nginx/nginx.conf.proxyprotocol
+endef
+
+define Package/nginx-syslog/install
+ $(INSTALL_DIR) $(1)/etc/nginx
+ $(INSTALL_BIN) ./files/nginx.syslog.example $(1)/etc/nginx/nginx.conf.syslog
+ chmod 0640 $(1)/etc/nginx/nginx.conf.syslog
+endef
+
+
+$(eval $(call BuildPackage,nginx))
+$(eval $(call BuildPackage,nginx-naxsi))
+$(eval $(call BuildPackage,nginx-proxyprotocol))
+$(eval $(call BuildPackage,nginx-syslog))
+
diff --git a/net/nginx/files/nginx.init b/net/nginx/files/nginx.init
new file mode 100644
index 000000000..adf36b442
--- /dev/null
+++ b/net/nginx/files/nginx.init
@@ -0,0 +1,24 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2009-2012 OpenWrt.org
+
+START=50
+NGINX_BIN=/usr/sbin/nginx
+
+start() {
+ mkdir -p /var/log/nginx
+ mkdir -p /var/lib/nginx
+ $NGINX_BIN
+}
+
+stop() {
+ $NGINX_BIN -s stop
+}
+
+reload() {
+ $NGINX_BIN -s reload
+}
+
+shutdown() {
+ $NGINX_BIN -s quit
+}
+
diff --git a/net/nginx/files/nginx.proxyprotocol.example b/net/nginx/files/nginx.proxyprotocol.example
new file mode 100644
index 000000000..ab4bad625
--- /dev/null
+++ b/net/nginx/files/nginx.proxyprotocol.example
@@ -0,0 +1,40 @@
+worker_processes 1;
+pid /tmp/nginx.pid;
+daemon off;
+master_process off;
+error_log stderr debug_core;
+
+events {
+ debug_connection <YOUR IPv4>;
+ debug_connection <YOUR IPV6>;
+ worker_connections 1024;
+}
+
+http {
+ default_type application/octet-stream;
+ client_body_temp_path /tmp/body 1;
+
+ access_log /tmp/nginx_access.log;
+
+ server {
+# listen 8082 ssl;
+# proxy protocol configuration for nginx 1.4.x:
+ listen 8082 accept_proxy_protocol=on;
+# same with spdy enabled:
+# listen 8082 spdy ssl accept_proxy_protocol=on;
+ listen [::]:8082 ipv6only=on;
+ ssl_certificate /your/certificate;
+ ssl_certificate_key /your/key;
+ server_name localhost;
+# proxy protocol configuration for nginx 1.2.x:
+# accept_proxy_protocol on;
+
+ location / {
+ proxy_pass http://127.0.0.1:8084;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_connect_timeout 10s;
+ proxy_read_timeout 10s;
+ send_proxy_protocol on;
+ }
+ }
+}
diff --git a/net/nginx/files/nginx.syslog.example b/net/nginx/files/nginx.syslog.example
new file mode 100644
index 000000000..05943448d
--- /dev/null
+++ b/net/nginx/files/nginx.syslog.example
@@ -0,0 +1,59 @@
+worker_processes 1;
+
+syslog local6 nginx;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ include mime.types;
+ default_type application/octet-stream;
+
+ log_format main '$remote_addr - $remote_user [$time_local] $request '
+ '"$status" $body_bytes_sent "$http_referer" '
+ '"$http_user_agent" "$http_x_forwarded_for"';
+
+ server {
+ listen 80;
+ server_name localhost;
+
+ #send the log to syslog and file.
+ access_log syslog:notice|logs/host1.access.log main;
+
+ # pre 1.5.x
+ error_log syslog:notice|logs/host1.error.log;
+
+ location / {
+ root html;
+ index index.html index.htm;
+ }
+ }
+
+ server {
+ listen 80;
+ server_name www.example.com;
+
+ access_log syslog:warn|logs/host2.access.log main;
+ error_log syslog:warn|logs/host2.error.log;
+
+ location / {
+ root html;
+ index index.html index.htm;
+ }
+ }
+
+ server {
+ listen 80;
+ server_name www.test.com;
+
+ #send the log just to syslog.
+ access_log syslog:error main;
+ error_log syslog:error;
+
+ location / {
+ root html;
+ index index.html index.htm;
+ }
+ }
+}
diff --git a/net/nginx/patches-lua-nginx/300-ldl.patch b/net/nginx/patches-lua-nginx/300-ldl.patch
new file mode 100644
index 000000000..d826bcf26
--- /dev/null
+++ b/net/nginx/patches-lua-nginx/300-ldl.patch
@@ -0,0 +1,21 @@
+--- a/lua-nginx/config
++++ b/lua-nginx/config
+@@ -1,5 +1,5 @@
+ ngx_feature="Lua library"
+-ngx_feature_libs="-llua -lm"
++ngx_feature_libs="-llua -lm -ldl"
+ ngx_feature_name=
+ ngx_feature_run=no
+ ngx_feature_incs="#include <lauxlib.h>"
+@@ -47,9 +47,9 @@ else
+ ngx_feature="Lua library in $LUA_LIB and $LUA_INC (specified by the LUA_LIB and LUA_INC env)"
+ ngx_feature_path="$LUA_INC"
+ if [ $NGX_RPATH = YES ]; then
+- ngx_feature_libs="-R$LUA_LIB -L$LUA_LIB -llua -lm"
++ ngx_feature_libs="-R$LUA_LIB -L$LUA_LIB -llua -lm -ldl"
+ else
+- ngx_feature_libs="-L$LUA_LIB -llua -lm"
++ ngx_feature_libs="-L$LUA_LIB -llua -lm -ldl"
+ fi
+
+ . auto/feature
diff --git a/net/nginx/patches-nginx-upstream-check/check_1.2.6+.patch b/net/nginx/patches-nginx-upstream-check/check_1.2.6+.patch
new file mode 100644
index 000000000..3ab913472
--- /dev/null
+++ b/net/nginx/patches-nginx-upstream-check/check_1.2.6+.patch
@@ -0,0 +1,209 @@
+diff --git a/src/http/modules/ngx_http_upstream_ip_hash_module.c b/src/http/modules/ngx_http_upstream_ip_hash_module.c
+index 89ccc2b..a552044 100644
+--- a/src/http/modules/ngx_http_upstream_ip_hash_module.c
++++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c
+@@ -9,6 +9,10 @@
+ #include <ngx_core.h>
+ #include <ngx_http.h>
+
++#if (NGX_UPSTREAM_CHECK_MODULE)
++#include "ngx_http_upstream_check_handler.h"
++#endif
++
+
+ typedef struct {
+ /* the round robin data must be first */
+@@ -208,6 +212,12 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
+
+ if (!peer->down) {
+
++#if (NGX_UPSTREAM_CHECK_MODULE)
++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
++ "get ip_hash peer, check_index: %ui",
++ peer->check_index);
++ if (!ngx_http_check_peer_down(peer->check_index)) {
++#endif
+ if (peer->max_fails == 0 || peer->fails < peer->max_fails) {
+ break;
+ }
+@@ -216,6 +226,9 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
+ peer->checked = now;
+ break;
+ }
++#if (NGX_UPSTREAM_CHECK_MODULE)
++ }
++#endif
+ }
+
+ iphp->rrp.tried[n] |= m;
+diff --git a/src/http/modules/ngx_http_upstream_least_conn_module.c b/src/http/modules/ngx_http_upstream_least_conn_module.c
+index 21156ae..c57393d 100644
+--- a/src/http/modules/ngx_http_upstream_least_conn_module.c
++++ b/src/http/modules/ngx_http_upstream_least_conn_module.c
+@@ -9,6 +9,10 @@
+ #include <ngx_core.h>
+ #include <ngx_http.h>
+
++#if (NGX_UPSTREAM_CHECK_MODULE)
++#include "ngx_http_upstream_check_handler.h"
++#endif
++
+
+ typedef struct {
+ ngx_uint_t *conns;
+@@ -203,6 +207,16 @@ ngx_http_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data)
+ continue;
+ }
+
++#if (NGX_UPSTREAM_CHECK_MODULE)
++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
++ "get least_conn peer, check_index: %ui",
++ peer->check_index);
++
++ if (ngx_http_check_peer_down(peer->check_index)) {
++ continue;
++ }
++#endif
++
+ if (peer->max_fails
+ && peer->fails >= peer->max_fails
+ && now - peer->checked <= peer->fail_timeout)
+@@ -256,6 +270,16 @@ ngx_http_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data)
+ continue;
+ }
+
++#if (NGX_UPSTREAM_CHECK_MODULE)
++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
++ "get least_conn peer, check_index: %ui",
++ peer->check_index);
++
++ if (ngx_http_check_peer_down(peer->check_index)) {
++ continue;
++ }
++#endif
++
+ if (lcp->conns[i] * best->weight != lcp->conns[p] * peer->weight) {
+ continue;
+ }
+diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c
+index 4b78cff..f077b46 100644
+--- a/src/http/ngx_http_upstream_round_robin.c
++++ b/src/http/ngx_http_upstream_round_robin.c
+@@ -9,6 +9,9 @@
+ #include <ngx_core.h>
+ #include <ngx_http.h>
+
++#if (NGX_UPSTREAM_CHECK_MODULE)
++#include "ngx_http_upstream_check_handler.h"
++#endif
+
+ static ngx_int_t ngx_http_upstream_cmp_servers(const void *one,
+ const void *two);
+@@ -87,7 +90,17 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
+ peers->peer[n].weight = server[i].weight;
+ peers->peer[n].effective_weight = server[i].weight;
+ peers->peer[n].current_weight = 0;
+- n++;
++
++#if (NGX_UPSTREAM_CHECK_MODULE)
++ if (!server[i].down) {
++ peers->peer[n].check_index =
++ ngx_http_check_add_peer(cf, us, &server[i].addrs[j]);
++ }
++ else {
++ peers->peer[n].check_index = (ngx_uint_t) NGX_ERROR;
++ }
++#endif
++ n++;
+ }
+ }
+
+@@ -145,6 +158,17 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
+ backup->peer[n].max_fails = server[i].max_fails;
+ backup->peer[n].fail_timeout = server[i].fail_timeout;
+ backup->peer[n].down = server[i].down;
++
++#if (NGX_UPSTREAM_CHECK_MODULE)
++ if (!server[i].down) {
++ backup->peer[n].check_index =
++ ngx_http_check_add_peer(cf, us, &server[i].addrs[j]);
++ }
++ else {
++ backup->peer[n].check_index = (ngx_uint_t) NGX_ERROR;
++ }
++#endif
++
+ n++;
+ }
+ }
+@@ -206,6 +230,9 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
+ peers->peer[i].current_weight = 0;
+ peers->peer[i].max_fails = 1;
+ peers->peer[i].fail_timeout = 10;
++#if (NGX_UPSTREAM_CHECK_MODULE)
++ peers->peer[i].check_index = (ngx_uint_t) NGX_ERROR;
++#endif
+ }
+
+ us->peer.data = peers;
+@@ -323,6 +350,9 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
+ peers->peer[0].current_weight = 0;
+ peers->peer[0].max_fails = 1;
+ peers->peer[0].fail_timeout = 10;
++#if (NGX_UPSTREAM_CHECK_MODULE)
++ peers->peer[0].check_index = (ngx_uint_t) NGX_ERROR;
++#endif
+
+ } else {
+
+@@ -356,6 +386,9 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
+ peers->peer[i].current_weight = 0;
+ peers->peer[i].max_fails = 1;
+ peers->peer[i].fail_timeout = 10;
++#if (NGX_UPSTREAM_CHECK_MODULE)
++ peers->peer[i].check_index = (ngx_uint_t) NGX_ERROR;
++#endif
+ }
+ }
+
+@@ -434,6 +467,12 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
+ goto failed;
+ }
+
++#if (NGX_UPSTREAM_CHECK_MODULE)
++ if (ngx_http_check_peer_down(peer->check_index)) {
++ goto failed;
++ }
++#endif
++
+ } else {
+
+ /* there are several peers */
+@@ -531,6 +570,12 @@ ngx_http_upstream_get_peer(ngx_http_upstream_rr_peer_data_t *rrp)
+ continue;
+ }
+
++#if (NGX_UPSTREAM_CHECK_MODULE)
++ if (ngx_http_check_peer_down(peer->check_index)) {
++ continue;
++ }
++#endif
++
+ if (peer->max_fails
+ && peer->fails >= peer->max_fails
+ && now - peer->checked <= peer->fail_timeout)
+diff --git a/src/http/ngx_http_upstream_round_robin.h b/src/http/ngx_http_upstream_round_robin.h
+index 3f8cbf8..1613168 100644
+--- a/src/http/ngx_http_upstream_round_robin.h
++++ b/src/http/ngx_http_upstream_round_robin.h
+@@ -30,6 +30,10 @@ typedef struct {
+ ngx_uint_t max_fails;
+ time_t fail_timeout;
+
++#if (NGX_UPSTREAM_CHECK_MODULE)
++ ngx_uint_t check_index;
++#endif
++
+ ngx_uint_t down; /* unsigned down:1; */
+
+ #if (NGX_HTTP_SSL)
diff --git a/net/nginx/patches/101-feature_test_fix.patch b/net/nginx/patches/101-feature_test_fix.patch
new file mode 100644
index 000000000..8e15fe96e
--- /dev/null
+++ b/net/nginx/patches/101-feature_test_fix.patch
@@ -0,0 +1,107 @@
+--- a/auto/cc/name
++++ b/auto/cc/name
+@@ -7,7 +7,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then
+
+ ngx_feature="C compiler"
+ ngx_feature_name=
+- ngx_feature_run=yes
++ ngx_feature_run=
+ ngx_feature_incs=
+ ngx_feature_path=
+ ngx_feature_libs=
+--- a/auto/cc/conf
++++ b/auto/cc/conf
+@@ -155,7 +155,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then
+ else
+ ngx_feature="C99 variadic macros"
+ ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS"
+- ngx_feature_run=yes
++ ngx_feature_run=no
+ ngx_feature_incs="#include <stdio.h>
+ #define var(dummy, ...) sprintf(__VA_ARGS__)"
+ ngx_feature_path=
+@@ -169,7 +169,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then
+
+ ngx_feature="gcc variadic macros"
+ ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS"
+- ngx_feature_run=yes
++ ngx_feature_run=no
+ ngx_feature_incs="#include <stdio.h>
+ #define var(dummy, args...) sprintf(args)"
+ ngx_feature_path=
+--- a/auto/os/linux
++++ b/auto/os/linux
+@@ -48,7 +48,7 @@ fi
+
+ ngx_feature="epoll"
+ ngx_feature_name="NGX_HAVE_EPOLL"
+-ngx_feature_run=yes
++ngx_feature_run=no
+ ngx_feature_incs="#include <sys/epoll.h>"
+ ngx_feature_path=
+ ngx_feature_libs=
+@@ -73,7 +73,7 @@ fi
+ CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE"
+ ngx_feature="sendfile()"
+ ngx_feature_name="NGX_HAVE_SENDFILE"
+-ngx_feature_run=yes
++ngx_feature_run=no
+ ngx_feature_incs="#include <sys/sendfile.h>
+ #include <errno.h>"
+ ngx_feature_path=
+@@ -94,7 +94,7 @@ fi
+ CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
+ ngx_feature="sendfile64()"
+ ngx_feature_name="NGX_HAVE_SENDFILE64"
+-ngx_feature_run=yes
++ngx_feature_run=no
+ ngx_feature_incs="#include <sys/sendfile.h>
+ #include <errno.h>"
+ ngx_feature_path=
+@@ -112,7 +112,7 @@ ngx_include="sys/prctl.h"; . auto/includ
+
+ ngx_feature="prctl(PR_SET_DUMPABLE)"
+ ngx_feature_name="NGX_HAVE_PR_SET_DUMPABLE"
+-ngx_feature_run=yes
++ngx_feature_run=no
+ ngx_feature_incs="#include <sys/prctl.h>"
+ ngx_feature_path=
+ ngx_feature_libs=
+--- a/auto/unix
++++ b/auto/unix
+@@ -618,7 +618,7 @@ ngx_feature_test="void *p; p = memalign(
+
+ ngx_feature="mmap(MAP_ANON|MAP_SHARED)"
+ ngx_feature_name="NGX_HAVE_MAP_ANON"
+-ngx_feature_run=yes
++ngx_feature_run=no
+ ngx_feature_incs="#include <sys/mman.h>"
+ ngx_feature_path=
+ ngx_feature_libs=
+@@ -631,7 +631,7 @@ ngx_feature_test="void *p;
+
+ ngx_feature='mmap("/dev/zero", MAP_SHARED)'
+ ngx_feature_name="NGX_HAVE_MAP_DEVZERO"
+-ngx_feature_run=yes
++ngx_feature_run=no
+ ngx_feature_incs="#include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>"
+@@ -646,7 +646,7 @@ ngx_feature_test='void *p; int fd;
+
+ ngx_feature="System V shared memory"
+ ngx_feature_name="NGX_HAVE_SYSVSHM"
+-ngx_feature_run=yes
++ngx_feature_run=no
+ ngx_feature_incs="#include <sys/ipc.h>
+ #include <sys/shm.h>"
+ ngx_feature_path=
+@@ -660,7 +660,7 @@ ngx_feature_test="int id;
+
+ ngx_feature="POSIX semaphores"
+ ngx_feature_name="NGX_HAVE_POSIX_SEM"
+-ngx_feature_run=yes
++ngx_feature_run=no
+ ngx_feature_incs="#include <semaphore.h>"
+ ngx_feature_path=
+ ngx_feature_libs=
diff --git a/net/nginx/patches/102-sizeof_test_fix.patch b/net/nginx/patches/102-sizeof_test_fix.patch
new file mode 100644
index 000000000..0cd93cc4e
--- /dev/null
+++ b/net/nginx/patches/102-sizeof_test_fix.patch
@@ -0,0 +1,26 @@
+--- a/auto/types/sizeof
++++ b/auto/types/sizeof
+@@ -25,8 +25,13 @@ $NGX_INCLUDE_UNISTD_H
+ $NGX_INCLUDE_INTTYPES_H
+ $NGX_INCLUDE_AUTO_CONFIG_H
+
++char object_code_block[] = {
++ '\n', 'e', '4', 'V', 'A',
++ '0', 'x', ('0' + sizeof($ngx_type)),
++ 'Y', '3', 'p', 'M', '\n'
++};
++
+ int main() {
+- printf("%d", (int) sizeof($ngx_type));
+ return 0;
+ }
+
+@@ -40,7 +45,7 @@ eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&
+
+
+ if [ -x $NGX_AUTOTEST ]; then
+- ngx_size=`$NGX_AUTOTEST`
++ ngx_size=`sed -ne 's/^e4VA0x\(.\)Y3pM$/\1/p' < $NGX_AUTOTEST`
+ echo " $ngx_size bytes"
+ fi
+
diff --git a/net/nginx/patches/103-sys_nerr.patch b/net/nginx/patches/103-sys_nerr.patch
new file mode 100644
index 000000000..5f5d106fe
--- /dev/null
+++ b/net/nginx/patches/103-sys_nerr.patch
@@ -0,0 +1,12 @@
+--- a/src/os/unix/ngx_errno.c
++++ b/src/os/unix/ngx_errno.c
+@@ -8,6 +8,9 @@
+ #include <ngx_config.h>
+ #include <ngx_core.h>
+
++#ifndef NGX_SYS_NERR
++#define NGX_SYS_NERR 128
++#endif
+
+ /*
+ * The strerror() messages are copied because:
diff --git a/net/nginx/patches/200-config.patch b/net/nginx/patches/200-config.patch
new file mode 100644
index 000000000..f35009576
--- /dev/null
+++ b/net/nginx/patches/200-config.patch
@@ -0,0 +1,18 @@
+--- a/conf/nginx.conf
++++ b/conf/nginx.conf
+@@ -1,5 +1,5 @@
+
+-#user nobody;
++user nobody nogroup;
+ worker_processes 1;
+
+ #error_log logs/error.log;
+@@ -16,7 +16,7 @@ events {
+
+ http {
+ include mime.types;
+- default_type application/octet-stream;
++ #default_type application/octet-stream;
+
+ #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+ # '$status $body_bytes_sent "$http_referer" '
diff --git a/net/nginx/patches/300-crosscompile_ccflags.patch b/net/nginx/patches/300-crosscompile_ccflags.patch
new file mode 100644
index 000000000..4a06a7696
--- /dev/null
+++ b/net/nginx/patches/300-crosscompile_ccflags.patch
@@ -0,0 +1,33 @@
+--- a/auto/endianness
++++ b/auto/endianness
+@@ -21,7 +21,7 @@ int main() {
+
+ END
+
+-ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
++ngx_test="$CC $NGX_CC_OPT $CC_TEST_FLAGS $CC_AUX_FLAGS \
+ -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
+
+ eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
+--- a/auto/feature
++++ b/auto/feature
+@@ -39,7 +39,7 @@ int main() {
+ END
+
+
+-ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS $ngx_feature_inc_path \
++ngx_test="$CC $NGX_CC_OPT $CC_TEST_FLAGS $CC_AUX_FLAGS $ngx_feature_inc_path \
+ -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_TEST_LD_OPT $ngx_feature_libs"
+
+ ngx_feature_inc_path=
+--- a/auto/include
++++ b/auto/include
+@@ -27,7 +27,7 @@ int main() {
+ END
+
+
+-ngx_test="$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c"
++ngx_test="$CC $NGX_CC_OPT -o $NGX_AUTOTEST $NGX_AUTOTEST.c"
+
+ eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
+
diff --git a/net/nginx/patches/400-nginx-1.4.x_proxy_protocol_patch_v2.patch b/net/nginx/patches/400-nginx-1.4.x_proxy_protocol_patch_v2.patch
new file mode 100644
index 000000000..52c1ce7ff
--- /dev/null
+++ b/net/nginx/patches/400-nginx-1.4.x_proxy_protocol_patch_v2.patch
@@ -0,0 +1,1194 @@
+Index: nginx-1.4.7/auto/modules
+===================================================================
+--- nginx-1.4.7.orig/auto/modules
++++ nginx-1.4.7/auto/modules
+@@ -297,6 +297,10 @@ if [ $HTTP_SSL = YES ]; then
+ HTTP_SRCS="$HTTP_SRCS $HTTP_SSL_SRCS"
+ fi
+
++if [ $PROXY_PROTOCOL = YES ]; then
++ have=NGX_PROXY_PROTOCOL . auto/have
++fi
++
+ if [ $HTTP_PROXY = YES ]; then
+ have=NGX_HTTP_X_FORWARDED_FOR . auto/have
+ #USE_MD5=YES
+Index: nginx-1.4.7/auto/options
+===================================================================
+--- nginx-1.4.7.orig/auto/options
++++ nginx-1.4.7/auto/options
+@@ -47,6 +47,8 @@ USE_THREADS=NO
+ NGX_FILE_AIO=NO
+ NGX_IPV6=NO
+
++PROXY_PROTOCOL=NO
++
+ HTTP=YES
+
+ NGX_HTTP_LOG_PATH=
+@@ -192,6 +194,8 @@ do
+ --with-file-aio) NGX_FILE_AIO=YES ;;
+ --with-ipv6) NGX_IPV6=YES ;;
+
++ --with-proxy-protocol) PROXY_PROTOCOL=YES ;;
++
+ --without-http) HTTP=NO ;;
+ --without-http-cache) HTTP_CACHE=NO ;;
+
+@@ -350,6 +354,8 @@ cat << END
+ --with-file-aio enable file AIO support
+ --with-ipv6 enable IPv6 support
+
++ --with-proxy-protocol enable proxy protocol 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
+Index: nginx-1.4.7/auto/sources
+===================================================================
+--- nginx-1.4.7.orig/auto/sources
++++ nginx-1.4.7/auto/sources
+@@ -36,7 +36,8 @@ CORE_DEPS="src/core/nginx.h \
+ src/core/ngx_conf_file.h \
+ src/core/ngx_resolver.h \
+ src/core/ngx_open_file_cache.h \
+- src/core/ngx_crypt.h"
++ src/core/ngx_crypt.h \
++ src/core/ngx_proxy_protocol.h"
+
+
+ CORE_SRCS="src/core/nginx.c \
+@@ -67,7 +68,8 @@ CORE_SRCS="src/core/nginx.c \
+ src/core/ngx_conf_file.c \
+ src/core/ngx_resolver.c \
+ src/core/ngx_open_file_cache.c \
+- src/core/ngx_crypt.c"
++ src/core/ngx_crypt.c \
++ src/core/ngx_proxy_protocol.c"
+
+
+ REGEX_MODULE=ngx_regex_module
+Index: nginx-1.4.7/src/core/ngx_connection.h
+===================================================================
+--- nginx-1.4.7.orig/src/core/ngx_connection.h
++++ nginx-1.4.7/src/core/ngx_connection.h
+@@ -63,6 +63,10 @@ struct ngx_listening_s {
+ unsigned shared:1; /* shared between threads or processes */
+ unsigned addr_ntop:1;
+
++#if (NGX_PROXY_PROTOCOL)
++ unsigned accept_proxy_protocol:2; /* proxy_protocol flag */
++#endif
++
+ #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
+ unsigned ipv6only:1;
+ #endif
+@@ -148,6 +152,10 @@ struct ngx_connection_s {
+
+ ngx_uint_t requests;
+
++#if (NGX_PROXY_PROTOCOL)
++ ngx_uint_t proxy_protocol;
++#endif
++
+ unsigned buffered:8;
+
+ unsigned log_error:3; /* ngx_connection_log_error_e */
+Index: nginx-1.4.7/src/core/ngx_core.h
+===================================================================
+--- nginx-1.4.7.orig/src/core/ngx_core.h
++++ nginx-1.4.7/src/core/ngx_core.h
+@@ -77,6 +77,9 @@ typedef void (*ngx_connection_handler_pt
+ #include <ngx_open_file_cache.h>
+ #include <ngx_os.h>
+ #include <ngx_connection.h>
++#if (NGX_PROXY_PROTOCOL)
++#include <ngx_proxy_protocol.h>
++#endif
+
+
+ #define LF (u_char) 10
+Index: nginx-1.4.7/src/core/ngx_proxy_protocol.c
+===================================================================
+--- /dev/null
++++ nginx-1.4.7/src/core/ngx_proxy_protocol.c
+@@ -0,0 +1,430 @@
++
++/*
++ * Copyright (C) Baptiste Assmann
++ * Copyright (C) Exceliance
++ */
++
++
++#include <ngx_config.h>
++#include <ngx_core.h>
++#include <ngx_event.h>
++
++#if (NGX_PROXY_PROTOCOL)
++
++int
++ngx_recv_proxy_protocol(ngx_connection_t *c, u_char *buf, ssize_t n)
++{
++ u_char *end, *p, *t;
++ size_t len;
++ ssize_t s;
++ int step = 0;
++ ngx_proxy_protocol_t pp;
++
++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "processing proxy protocol");
++
++ /* 16 is the minimal length of the proxy protocol string */
++ if (n < 18) {
++ step = 1;
++ goto fail;
++ }
++
++ s = n;
++ end = memchr(buf, '\n', n);
++ if (end == NULL) {
++ step = 2;
++ goto fail;
++ }
++
++ p = buf;
++ if (memcmp(p, "PROXY ", 6) != 0) {
++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
++ "incorrect proxy protocol header string");
++ step = 3;
++ goto fail;
++ }
++ p += 6;
++ s -= 6;
++ if (s <= 0) {
++ step = 4;
++ goto fail;
++ }
++
++ ngx_memzero(&pp, sizeof(ngx_proxy_protocol_t));
++
++ if (memcmp(p, "TCP4 ", 5) == 0) {
++ struct sockaddr_in *sin_src;
++ struct sockaddr_in *sin_dst;
++
++ pp.pp_proto = NGX_PP_PROTO_TCP4;
++ pp.pp_src3.ss_family = AF_INET;
++ pp.pp_dst3.ss_family = AF_INET;
++ sin_src = (struct sockaddr_in *) &pp.pp_src3;
++ sin_dst = (struct sockaddr_in *) &pp.pp_dst3;
++
++ p += 5;
++ s -= 5;
++ if (s <= 0) {
++ step = 5;
++ goto fail;
++ }
++
++ /* l3 source address */
++ if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
++ step = 6;
++ goto fail;
++ }
++ len = t - p;
++ if ((sin_src->sin_addr.s_addr = ngx_inet_addr(p, len)) == INADDR_NONE) {
++ step = 7;
++ goto fail;
++ }
++ pp.pp_src3_text.data = ngx_pcalloc(c->pool, len + 1);
++ ngx_memcpy(pp.pp_src3_text.data, p, len);
++ pp.pp_src3_text.len = len;
++
++ p += (len + 1);
++ s -= (len + 1);
++ if (s <= 0) {
++ step = 8;
++ goto fail;
++ }
++
++ /* l3 destination address */
++ if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
++ step = 9;
++ goto fail;
++ }
++ len = t - p;
++ if ((sin_dst->sin_addr.s_addr = ngx_inet_addr(p, len)) == INADDR_NONE) {
++ step = 10;
++ goto fail;
++ }
++// FIXME pointer shift ???
++ pp.pp_dst3_text.data = ngx_pcalloc(c->pool, len + 1);
++ ngx_memcpy(pp.pp_dst3_text.data, p, len);
++ pp.pp_dst3_text.len = len;
++
++ p += (len + 1);
++ s -= (len + 1);
++ if (s <= 0) {
++ step = 11;
++ goto fail;
++ }
++
++ /* l4 source port */
++ if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
++ step = 12;
++ goto fail;
++ }
++ len = t - p;
++ pp.pp_src4 = ngx_atoi(p, len);
++ if ((pp.pp_src4 < 1024)
++ || (pp.pp_src4 > 65535)) {
++ step = 13;
++ goto fail;
++ }
++ sin_src->sin_port = htons(pp.pp_src4);
++
++ p += (len + 1);
++ s -= (len + 1);
++ if (s <= 0) {
++ step = 14;
++ goto fail;
++ }
++
++ /* l4 destination port */
++ if ( (t = (u_char *)memchr(p, '\r', s)) == NULL ) {
++ step = 15;
++ goto fail;
++ }
++ len = t - p;
++ pp.pp_dst4 = ngx_atoi(p, len);
++ if (pp.pp_dst4 > 65535) {
++ step = 16;
++ goto fail;
++ }
++ sin_dst->sin_port = htons(pp.pp_dst4);
++
++ if (p[len + 1] != '\n') {
++ step = 17;
++ goto fail;
++ }
++
++ p += (len + 2);
++ s -= (len + 2);
++
++
++ /* if we managed to get there, then we can safely replace the
++ * information in the connection structure
++ */
++
++ /* updating connection with source information provided by proxy protocol */
++ if (pp.pp_src3_text.len > c->addr_text.len) {
++ ngx_pfree(c->pool, c->addr_text.data);
++ c->addr_text.data = ngx_pcalloc(c->pool, pp.pp_src3_text.len);
++ } else {
++ ngx_memzero(c->addr_text.data, c->addr_text.len);
++ }
++ ngx_memcpy(c->addr_text.data, pp.pp_src3_text.data, pp.pp_src3_text.len);
++ c->addr_text.len = pp.pp_src3_text.len;
++
++ ngx_pfree(c->pool, c->sockaddr);
++ c->socklen = NGX_SOCKADDRLEN;
++ c->sockaddr = ngx_pcalloc(c->pool, c->socklen);
++ ngx_memcpy(c->sockaddr, sin_src, c->socklen);
++
++ if (c->sockaddr->sa_family != AF_INET) {
++ ngx_pfree(c->pool, c->sockaddr);
++ c->socklen = NGX_SOCKADDRLEN;
++ c->sockaddr = ngx_pcalloc(c->pool, c->socklen);
++ } else {
++ ngx_memzero(c->sockaddr, sizeof(struct sockaddr_in));
++ c->socklen = NGX_SOCKADDRLEN;
++ }
++ ngx_memcpy(c->sockaddr, sin_src, c->socklen);
++
++ /* updating connection with destination information provided by proxy protocol */
++ ngx_pfree(c->pool, c->local_sockaddr);
++ c->local_sockaddr = ngx_pcalloc(c->pool, NGX_SOCKADDRLEN);
++ ngx_memcpy(c->local_sockaddr, sin_dst, NGX_SOCKADDRLEN);
++
++ }
++
++#if (NGX_HAVE_INET6)
++
++ else if (memcmp(p, "TCP6 ", 5) == 0) {
++
++ struct sockaddr_in6 *sin6_src;
++ struct sockaddr_in6 *sin6_dst;
++
++ pp.pp_proto = NGX_PP_PROTO_TCP6;
++ pp.pp_src3.ss_family = AF_INET6;
++ pp.pp_dst3.ss_family = AF_INET6;
++ sin6_src = (struct sockaddr_in6 *) &pp.pp_src3;
++ sin6_dst = (struct sockaddr_in6 *) &pp.pp_dst3;
++
++ p += 5;
++ s -= 5;
++ if (s <= 0) {
++ step = 18;
++ goto fail;
++ }
++
++ /* l3 source address */
++ if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
++ step = 19;
++ goto fail;
++ }
++ len = t - p;
++ if (ngx_inet6_addr(p, len, sin6_src->sin6_addr.s6_addr) != NGX_OK) {
++ step = 20;
++ goto fail;
++ }
++ pp.pp_src3_text.data = ngx_pcalloc(c->pool, len + 1);
++ ngx_memcpy(pp.pp_src3_text.data, p, len);
++ pp.pp_src3_text.len = len;
++
++ p += (len + 1);
++ s -= (len + 1);
++ if (s <= 0) {
++ step = 21;
++ goto fail;
++ }
++
++ /* l3 destination address */
++ if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
++ step = 22;
++ goto fail;
++ }
++ len = t - p;
++ if (ngx_inet6_addr(p, len, sin6_dst->sin6_addr.s6_addr) != NGX_OK) {
++ step = 23;
++ goto fail;
++ }
++ pp.pp_dst3_text.data = ngx_pcalloc(c->pool, len + 1);
++ ngx_memcpy(pp.pp_dst3_text.data, p, len);
++ pp.pp_dst3_text.len = len;
++
++ p += (len + 1);
++ s -= (len + 1);
++ if (s <= 0) {
++ step = 24;
++ goto fail;
++ }
++
++ /* l4 source port */
++ if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
++ step = 25;
++ goto fail;
++ }
++ len = t - p;
++ pp.pp_src4 = ngx_atoi(p, len);
++ if ((pp.pp_src4 < 1024)
++ || (pp.pp_src4 > 65535)) {
++ step = 26;
++ goto fail;
++ }
++ sin6_src->sin6_port = htons(pp.pp_src4);
++
++ p += (len + 1);
++ s -= (len + 1);
++ if (s <= 0) {
++ step = 27;
++ goto fail;
++ }
++
++ /* l4 destination port */
++ if ( (t = (u_char *)memchr(p, '\r', s)) == NULL ) {
++ step = 28;
++ goto fail;
++ }
++ len = t - p;
++ pp.pp_dst4 = ngx_atoi(p, len);
++ if (pp.pp_dst4 > 65535) {
++ step = 29;
++ goto fail;
++ }
++ sin6_dst->sin6_port = htons(pp.pp_dst4);
++
++ if (p[len + 1] != '\n') {
++ step = 30;
++ goto fail;
++ }
++
++ p += (len + 2);
++ s -= (len + 2);
++
++ /* if we managed to get there, then we can safely replace the
++ * information in the connection structure
++ */
++
++ /* updating connection with source provided by proxy protocol */
++ if (pp.pp_src3_text.len > c->addr_text.len) {
++ ngx_pfree(c->pool, c->addr_text.data);
++ c->addr_text.data = ngx_pcalloc(c->pool, pp.pp_src3_text.len);
++ } else {
++ ngx_memzero(c->addr_text.data, c->addr_text.len);
++ }
++ ngx_memcpy(c->addr_text.data, pp.pp_src3_text.data, pp.pp_src3_text.len);
++ c->addr_text.len = pp.pp_src3_text.len;
++
++ ngx_pfree(c->pool, c->sockaddr);
++ c->socklen = NGX_SOCKADDRLEN;
++ c->sockaddr = ngx_pcalloc(c->pool, c->socklen);
++ ngx_memcpy(c->sockaddr, sin6_src, c->socklen);
++
++ /* updating connection with destination provided by proxy protocol */
++ if (c->sockaddr->sa_family != AF_INET6) {
++ ngx_pfree(c->pool, c->local_sockaddr);
++ c->local_sockaddr = ngx_pcalloc(c->pool, NGX_SOCKADDRLEN);
++ } else {
++ ngx_memzero(c->sockaddr, sizeof(struct sockaddr_in6));
++ c->socklen = NGX_SOCKADDRLEN;
++ }
++// ngx_memcpy(c->local_sockaddr, sin6_dst, NGX_SOCKADDRLEN);
++//FIXME must be finished here
++
++ }
++
++#endif
++
++ else {
++ step = 31;
++ goto fail;
++ }
++
++ ngx_print_proxy_protocol(&pp, c->log);
++
++ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
++ "proxy_protocol, asking to remove %z chars",
++ end + 1 - buf);
++
++ return (end + 1 - buf);
++
++fail:
++ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
++ "proxy_protocol error at step: %d", step);
++
++ return 0;
++
++}
++
++
++void
++ngx_print_proxy_protocol(ngx_proxy_protocol_t *p, ngx_log_t *log)
++{
++ switch (p->pp_proto) {
++ case NGX_PP_PROTO_TCP4:
++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0,
++ "proxy_protocol, proto: TCP4");
++ break;
++ case NGX_PP_PROTO_TCP6:
++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0,
++ "proxy_protocol, proto: TCP6");
++ break;
++ }
++
++ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
++ "proxy_protocol, string length: %d", ngx_proxy_protocol_string_length(p));
++ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
++ "proxy_protocol, src3: %s, %d", p->pp_src3_text.data, p->pp_src3_text.len);
++ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
++ "proxy_protocol, dst3: %s, %d", p->pp_dst3_text.data, p->pp_dst3_text.len);
++ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
++ "proxy_protocol, src4: %d", p->pp_src4);
++ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
++ "proxy_protocol, dst4: %d", p->pp_dst4);
++}
++
++
++int
++ngx_proxy_protocol_string_length(ngx_proxy_protocol_t *p)
++{
++ int len = 0;
++
++ /* 'PROXY ' */
++ len += (sizeof("PROXY ") - 1);
++
++ /* protocol version (TCP4 or TCP6) + space */
++ len += (sizeof("TCP0 ") - 1);
++
++ /* src3 + space */
++ len += p->pp_src3_text.len;
++ len += 1;
++
++ /* dst3 + space */
++ len += p->pp_dst3_text.len;
++ len += 1;
++
++ /* src4 */
++ if (p->pp_src4 < 10000)
++ /* 4 digits + 1 space */
++ len += (sizeof("0000 ") - 1);
++ else
++ /* 5 digits + 1 space */
++ len += (sizeof("00000 ") - 1);
++
++ /* dst4 */
++ if (p->pp_dst4 >= 10000)
++ /* 5 digits */
++ len += (sizeof("00000 ") - 1);
++ else if (p->pp_dst4 >= 1000)
++ /* 4 digits */
++ len += (sizeof("0000 ") - 1);
++ else if (p->pp_dst4 >= 100)
++ /* 3 digits */
++ len += (sizeof("000 ") - 1);
++ else if (p->pp_dst4 >= 10)
++ /* 2 digits */
++ len += (sizeof("00 ") - 1);
++ else
++ /* 1 digit */
++ len += (sizeof("0 ") - 1);
++
++ /* CRLF */
++ len += (sizeof(CRLF) - 1);
++
++ return len - 1;
++}
++
++#endif
+Index: nginx-1.4.7/src/core/ngx_proxy_protocol.h
+===================================================================
+--- /dev/null
++++ nginx-1.4.7/src/core/ngx_proxy_protocol.h
+@@ -0,0 +1,45 @@
++
++/*
++ * Copyright (C) Baptiste Assmann
++ * Copyright (C) Exceliance
++ */
++
++
++#ifndef _NGX_PROXY_PROTOCOL_H_INCLUDED_
++#define _NGX_PROXY_PROTOCOL_H_INCLUDED_
++
++
++#include <ngx_config.h>
++#include <ngx_core.h>
++
++
++#if (NGX_PROXY_PROTOCOL)
++
++typedef struct ngx_proxy_protocol_s ngx_proxy_protocol_t;
++
++typedef enum {
++ NGX_PP_PROTO_TCP4 = 1,
++ NGX_PP_PROTO_TCP6
++} ngx_pp_proto;
++
++
++struct ngx_proxy_protocol_s {
++ unsigned int pp_proto; /* proxy protocol related information */
++ struct sockaddr_storage pp_src3;
++ ngx_str_t pp_src3_text;
++ struct sockaddr_storage pp_dst3;
++ ngx_str_t pp_dst3_text;
++ unsigned int pp_src4;
++ unsigned int pp_dst4;
++};
++
++
++int ngx_recv_proxy_protocol(ngx_connection_t *, u_char *, ssize_t);
++void ngx_print_proxy_protocol(ngx_proxy_protocol_t *, ngx_log_t *);
++int ngx_proxy_protocol_string_length(ngx_proxy_protocol_t *);
++
++
++#endif
++
++#endif /* _NGX_CONNECTION_H_INCLUDED_ */
++
+Index: nginx-1.4.7/src/http/modules/ngx_http_proxy_module.c
+===================================================================
+--- nginx-1.4.7.orig/src/http/modules/ngx_http_proxy_module.c
++++ nginx-1.4.7/src/http/modules/ngx_http_proxy_module.c
+@@ -8,7 +8,9 @@
+ #include <ngx_config.h>
+ #include <ngx_core.h>
+ #include <ngx_http.h>
+-
++#if (NGX_PROXY_PROTOCOL)
++#include <ngx_proxy_protocol.h>
++#endif
+
+ typedef struct ngx_http_proxy_rewrite_s ngx_http_proxy_rewrite_t;
+
+@@ -365,6 +367,17 @@ static ngx_command_t ngx_http_proxy_com
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.busy_buffers_size_conf),
+ NULL },
+
++#if (NGX_PROXY_PROTOCOL)
++
++ { ngx_string("send_proxy_protocol"),
++ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
++ ngx_conf_set_flag_slot,
++ NGX_HTTP_LOC_CONF_OFFSET,
++ offsetof(ngx_http_proxy_loc_conf_t, upstream.send_proxy_protocol),
++ NULL },
++
++#endif
++
+ #if (NGX_HTTP_CACHE)
+
+ { ngx_string("proxy_cache"),
+@@ -2420,6 +2433,11 @@ ngx_http_proxy_create_loc_conf(ngx_conf_
+ conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
+
+ conf->upstream.intercept_errors = NGX_CONF_UNSET;
++
++#if (NGX_PROXY_PROTOCOL)
++ conf->upstream.send_proxy_protocol = NGX_CONF_UNSET;
++#endif
++
+ #if (NGX_HTTP_SSL)
+ conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
+ #endif
+@@ -2695,6 +2713,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
+ ngx_conf_merge_value(conf->upstream.intercept_errors,
+ prev->upstream.intercept_errors, 0);
+
++#if (NGX_PROXY_PROTOCOL)
++ ngx_conf_merge_value(conf->upstream.send_proxy_protocol,
++ prev->upstream.send_proxy_protocol, 0);
++#endif
++
+ #if (NGX_HTTP_SSL)
+ ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
+ prev->upstream.ssl_session_reuse, 1);
+Index: nginx-1.4.7/src/http/ngx_http.c
+===================================================================
+--- nginx-1.4.7.orig/src/http/ngx_http.c
++++ nginx-1.4.7/src/http/ngx_http.c
+@@ -1228,6 +1228,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
+ #if (NGX_HTTP_SPDY)
+ ngx_uint_t spdy;
+ #endif
++#if (NGX_PROXY_PROTOCOL)
++ ngx_uint_t accept_proxy_protocol;
++#endif
+
+ /*
+ * we cannot compare whole sockaddr struct's as kernel
+@@ -1283,6 +1286,10 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
+ #if (NGX_HTTP_SPDY)
+ spdy = lsopt->spdy || addr[i].opt.spdy;
+ #endif
++#if (NGX_PROXY_PROTOCOL)
++ accept_proxy_protocol = lsopt->accept_proxy_protocol
++ || addr[i].opt.accept_proxy_protocol;
++#endif
+
+ if (lsopt->set) {
+
+@@ -1316,6 +1323,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
+ #if (NGX_HTTP_SPDY)
+ addr[i].opt.spdy = spdy;
+ #endif
++#if (NGX_PROXY_PROTOCOL)
++ addr[i].opt.accept_proxy_protocol = accept_proxy_protocol;
++#endif
+
+ return NGX_OK;
+ }
+@@ -1762,6 +1772,11 @@ ngx_http_add_listening(ngx_conf_t *cf, n
+ ls->pool_size = cscf->connection_pool_size;
+ ls->post_accept_timeout = cscf->client_header_timeout;
+
++#if (NGX_PROXY_PROTOCOL)
++// CLEANUP: ls->accept_proxy_protocol = cscf->accept_proxy_protocol;
++ ls->accept_proxy_protocol = addr->opt.accept_proxy_protocol;
++#endif
++
+ clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
+
+ ls->logp = clcf->error_log;
+@@ -1840,6 +1855,9 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_h
+ #if (NGX_HTTP_SPDY)
+ addrs[i].conf.spdy = addr[i].opt.spdy;
+ #endif
++#if (NGX_PROXY_PROTOCOL)
++ addrs[i].conf.accept_proxy_protocol = addr[i].opt.accept_proxy_protocol;
++#endif
+
+ if (addr[i].hash.buckets == NULL
+ && (addr[i].wc_head == NULL
+@@ -1904,6 +1922,9 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_
+ #if (NGX_HTTP_SPDY)
+ addrs6[i].conf.spdy = addr[i].opt.spdy;
+ #endif
++#if (NGX_PROXY_PROTOCOL)
++ addrs6[i].conf.accept_proxy_protocol = addr[i].opt.accept_proxy_protocol;
++#endif
+
+ if (addr[i].hash.buckets == NULL
+ && (addr[i].wc_head == NULL
+Index: nginx-1.4.7/src/http/ngx_http_core_module.c
+===================================================================
+--- nginx-1.4.7.orig/src/http/ngx_http_core_module.c
++++ nginx-1.4.7/src/http/ngx_http_core_module.c
+@@ -4090,6 +4090,15 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
+ continue;
+ }
+
++#if (NGX_PROXY_PROTOCOL)
++ if (ngx_strncmp(value[n].data, "accept_proxy_protocol=on", 24) == 0) {
++ lsopt.accept_proxy_protocol = 1;
++ lsopt.set = 1;
++ lsopt.bind = 1;
++ continue;
++ }
++#endif
++
+ if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
+ #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
+ struct sockaddr *sa;
+Index: nginx-1.4.7/src/http/ngx_http_core_module.h
+===================================================================
+--- nginx-1.4.7.orig/src/http/ngx_http_core_module.h
++++ nginx-1.4.7/src/http/ngx_http_core_module.h
+@@ -78,6 +78,11 @@ typedef struct {
+ #if (NGX_HTTP_SPDY)
+ unsigned spdy:1;
+ #endif
++
++#if (NGX_PROXY_PROTOCOL)
++ unsigned accept_proxy_protocol:2;
++#endif
++
+ #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
+ unsigned ipv6only:1;
+ #endif
+@@ -234,6 +239,10 @@ struct ngx_http_addr_conf_s {
+
+ ngx_http_virtual_names_t *virtual_names;
+
++#if (NGX_PROXY_PROTOCOL)
++ ngx_flag_t accept_proxy_protocol;
++#endif
++
+ #if (NGX_HTTP_SSL)
+ unsigned ssl:1;
+ #endif
+Index: nginx-1.4.7/src/http/ngx_http_request.c
+===================================================================
+--- nginx-1.4.7.orig/src/http/ngx_http_request.c
++++ nginx-1.4.7/src/http/ngx_http_request.c
+@@ -63,6 +63,9 @@ static void ngx_http_ssl_handshake(ngx_e
+ static void ngx_http_ssl_handshake_handler(ngx_connection_t *c);
+ #endif
+
++#if (NGX_PROXY_PROTOCOL)
++static void ngx_http_proxy_protocol(ngx_event_t *rev);
++#endif
+
+ static char *ngx_http_client_errors[] = {
+
+@@ -343,6 +346,14 @@ ngx_http_init_connection(ngx_connection_
+ }
+ #endif
+
++#if (NGX_PROXY_PROTOCOL)
++ {
++ if (hc->addr_conf->accept_proxy_protocol) {
++ rev->handler = ngx_http_proxy_protocol;
++ }
++ }
++#endif
++
+ if (rev->ready) {
+ /* the deferred accept(), rtsig, aio, iocp */
+
+@@ -364,7 +375,6 @@ ngx_http_init_connection(ngx_connection_
+ }
+ }
+
+-
+ static void
+ ngx_http_wait_request_handler(ngx_event_t *rev)
+ {
+@@ -469,6 +479,12 @@ ngx_http_wait_request_handler(ngx_event_
+ }
+
+ rev->handler = ngx_http_process_request_line;
++
++#if (NGX_PROXY_PROTOCOL)
++ if (hc->addr_conf->accept_proxy_protocol)
++ rev->handler = ngx_http_proxy_protocol;
++#endif
++
+ ngx_http_process_request_line(rev);
+ }
+
+@@ -582,6 +598,67 @@ ngx_http_create_request(ngx_connection_t
+ return r;
+ }
+
++#if (NGX_PROXY_PROTOCOL)
++
++static void
++ngx_http_proxy_protocol(ngx_event_t *rev)
++{
++ ssize_t n;
++ size_t size = 1024;
++ u_char tmpbuf[size];
++ ngx_connection_t *c;
++ ngx_http_connection_t *hc;
++
++ c = rev->data;
++ hc = c->data;
++ rev->handler = ngx_http_wait_request_handler;
++
++#if (NGX_HTTP_SPDY)
++ {
++ if (hc->addr_conf->spdy) {
++ rev->handler = ngx_http_spdy_init;
++ }
++ }
++#endif
++
++#if (NGX_HTTP_SSL)
++ {
++ if (hc->addr_conf->ssl) {
++ rev->handler = ngx_http_ssl_handshake;
++ }
++ }
++#endif
++
++ n = recv(c->fd, tmpbuf, size, MSG_PEEK);
++
++ if ((n <= 0) && (c->listening)
++ && (hc->addr_conf->accept_proxy_protocol)
++ && (!c->proxy_protocol)) {
++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required but not found");
++ return;
++ }
++ if ((n > 0) && (c->listening)
++ && (hc->addr_conf->accept_proxy_protocol)
++ && (!c->proxy_protocol)) {
++ ssize_t m;
++ if (!(m = ngx_recv_proxy_protocol(c, tmpbuf, n))) {
++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required but not found");
++ ngx_http_close_connection(c);
++ return;
++ }
++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required and found");
++
++ c->proxy_protocol = 1;
++
++ /* strip the proxy protocol string from the buffer */
++ recv(c->fd, tmpbuf, m, 0);
++ }
++
++ rev->handler(rev);
++}
++
++#endif
++
+
+ #if (NGX_HTTP_SSL)
+
+@@ -1291,6 +1368,10 @@ ngx_http_read_request_header(ngx_http_re
+ c = r->connection;
+ rev = c->read;
+
++fprintf(stderr, "DEBUG: pos: %p, last: %p, start: %p, end: %p\n",
++ r->header_in->pos, r->header_in->last, r->header_in->start,
++ r->header_in->end);
++
+ n = r->header_in->last - r->header_in->pos;
+
+ if (n > 0) {
+Index: nginx-1.4.7/src/http/ngx_http_upstream.c
+===================================================================
+--- nginx-1.4.7.orig/src/http/ngx_http_upstream.c
++++ nginx-1.4.7/src/http/ngx_http_upstream.c
+@@ -31,6 +31,10 @@ static ngx_int_t ngx_http_upstream_reini
+ ngx_http_upstream_t *u);
+ static void ngx_http_upstream_send_request(ngx_http_request_t *r,
+ ngx_http_upstream_t *u);
++#if (NGX_PROXY_PROTOCOL)
++static void ngx_http_upstream_send_proxy_protocol(ngx_http_request_t *r,
++ ngx_http_upstream_t *u);
++#endif
+ static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
+ ngx_http_upstream_t *u);
+ static void ngx_http_upstream_process_header(ngx_http_request_t *r,
+@@ -1255,6 +1259,13 @@ ngx_http_upstream_connect(ngx_http_reque
+
+ u->request_sent = 0;
+
++#if (NGX_PROXY_PROTOCOL)
++ if (u->conf->send_proxy_protocol && !(u->ssl && c->ssl == NULL)) {
++ ngx_http_upstream_send_proxy_protocol(r, u);
++ return;
++ }
++#endif
++
+ if (rc == NGX_AGAIN) {
+ ngx_add_timer(c->write, u->conf->connect_timeout);
+ return;
+@@ -1498,6 +1509,228 @@ ngx_http_upstream_send_request(ngx_http_
+ }
+
+
++#if (NGX_PROXY_PROTOCOL)
++
++static void
++ngx_http_upstream_send_proxy_protocol(ngx_http_request_t *r, ngx_http_upstream_t *u)
++{
++ size_t len;
++ ngx_int_t rc;
++ ngx_connection_t *uc;
++ ngx_connection_t *cc;
++ ngx_chain_t *pp_string;
++ ngx_proxy_protocol_t pp;
++ ngx_buf_t *b;
++ char port[6];
++ u_char *addr;
++ struct sockaddr_storage sa_src;
++ struct sockaddr_storage sa_dst;
++ socklen_t addrlen = NGX_SOCKADDRLEN;
++ struct sockaddr_in *sin_src;
++ struct sockaddr_in *sin_dst;
++
++#if (NGX_HAVE_INET6)
++
++ struct sockaddr_in6 *sin6_src;
++ struct sockaddr_in6 *sin6_dst;
++
++#endif
++
++
++ uc = u->peer.connection;
++ cc = r->connection;
++
++ if ( !(u->conf->send_proxy_protocol) ) {
++ return;
++ }
++
++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0,
++ "http upstream send proxy protocol");
++
++ if (!u->request_sent && ngx_http_upstream_test_connect(uc) != NGX_OK) {
++ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
++ return;
++ }
++
++ uc->log->action = "sending proxy protocol to upstream";
++
++ len = 0;
++
++ if (r->connection->proxy_protocol) {
++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0,
++ "PP: got proxy-protocol from client connection");
++
++ switch (cc->sockaddr->sa_family) {
++
++#if (NGX_HAVE_INET6)
++
++ case AF_INET6:
++
++ pp.pp_proto = NGX_PP_PROTO_TCP6;
++ sin6_dst = (struct sockaddr_in6 *) cc->local_sockaddr;
++ sin6_src = (struct sockaddr_in6 *) cc->sockaddr;
++
++ break;
++
++#endif
++
++ default:
++ pp.pp_proto = NGX_PP_PROTO_TCP4;
++ sin_dst = (struct sockaddr_in *) cc->local_sockaddr;
++ sin_src = (struct sockaddr_in *) cc->sockaddr;
++
++ }
++
++ } else {
++
++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0,
++ "PP: collecting information from socket fd");
++
++ getsockname(cc->fd, (struct sockaddr *) &sa_dst, &addrlen);
++
++ switch (sa_dst.ss_family) {
++
++#if (NGX_HAVE_INET6)
++
++ case AF_INET6:
++
++ pp.pp_proto = NGX_PP_PROTO_TCP6;
++ sin6_dst = (struct sockaddr_in6 *) &sa_dst;
++
++ getpeername(cc->fd, (struct sockaddr *) &sa_src, &addrlen);
++ sin6_src = (struct sockaddr_in6 *) &sa_src;
++
++ break;
++
++#endif
++
++ default:
++
++ pp.pp_proto = NGX_PP_PROTO_TCP4;
++ sin_dst = (struct sockaddr_in *) &sa_dst;
++ getpeername(cc->fd, (struct sockaddr *) &sa_src, &addrlen);
++ sin_src = (struct sockaddr_in *) &sa_src;
++ }
++
++
++ }
++
++ switch (pp.pp_proto) {
++
++#if (NGX_HAVE_INET6)
++
++ case NGX_PP_PROTO_TCP6:
++
++ /* dst3 and dst4 */
++ addr = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN);
++ ngx_inet_ntop(AF_INET6, &sin6_dst->sin6_addr, addr, NGX_INET6_ADDRSTRLEN);
++ pp.pp_dst3_text.data = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN);
++ pp.pp_dst3_text.len = ngx_strlen(addr);
++ ngx_memcpy(pp.pp_dst3_text.data, addr, pp.pp_dst3_text.len);
++ pp.pp_dst4 = htons(sin6_dst->sin6_port);
++
++ ngx_memzero(addr, NGX_INET6_ADDRSTRLEN);
++
++ /* src3 and src4 */
++ ngx_inet_ntop(AF_INET6, &sin6_src->sin6_addr, addr, NGX_INET6_ADDRSTRLEN);
++ pp.pp_src3_text.data = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN);
++ pp.pp_src3_text.len = ngx_strlen(addr);
++ ngx_memcpy(pp.pp_src3_text.data, addr, pp.pp_src3_text.len);
++ pp.pp_src4 = htons(sin6_src->sin6_port);
++
++ break;
++
++#endif
++
++ default:
++
++ /* dst3 and dst4 */
++ addr = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN);
++ ngx_inet_ntop(AF_INET, &sin_dst->sin_addr, addr, NGX_INET_ADDRSTRLEN);
++ pp.pp_dst3_text.data = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN);
++ pp.pp_dst3_text.len = ngx_strlen(addr);
++ ngx_memcpy(pp.pp_dst3_text.data, addr, pp.pp_dst3_text.len);
++ pp.pp_dst4 = htons(sin_dst->sin_port);
++
++ ngx_memzero(addr, NGX_INET_ADDRSTRLEN);
++
++ /* src3 and src4 */
++ ngx_inet_ntop(AF_INET, &sin_src->sin_addr, addr, NGX_INET_ADDRSTRLEN);
++ pp.pp_src3_text.data = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN);
++ pp.pp_src3_text.len = ngx_strlen(addr);
++ ngx_memcpy(pp.pp_src3_text.data, addr, pp.pp_src3_text.len);
++ pp.pp_src4 = htons(sin_src->sin_port);
++
++ }
++
++ len += ngx_proxy_protocol_string_length(&pp);
++
++ ngx_print_proxy_protocol(&pp, uc->log);
++
++ b = ngx_create_temp_buf(uc->pool, len);
++ if (b == NULL) {
++ return;
++ }
++
++ pp_string = ngx_alloc_chain_link(uc->pool);
++ if (pp_string == NULL) {
++ return;
++ }
++
++ pp_string->buf = b;
++ pp_string->next = NULL;
++
++ b->last = ngx_cpymem(b->last, "PROXY ", sizeof("PROXY ") - 1);
++
++ switch (pp.pp_proto) {
++ case NGX_PP_PROTO_TCP4:
++ b->last = ngx_cpymem(b->last, "TCP4 ", sizeof("TCP4 ") - 1);
++ break;
++ case NGX_PP_PROTO_TCP6:
++ b->last = ngx_cpymem(b->last, "TCP6 ", sizeof("TCP6 ") - 1);
++ break;
++ }
++
++ /* src3 */
++ b->last = ngx_cpymem(b->last, pp.pp_src3_text.data, pp.pp_src3_text.len);
++ b->last = ngx_cpymem(b->last, " ", 1);
++
++ /* dst3 */
++ b->last = ngx_cpymem(b->last, pp.pp_dst3_text.data, pp.pp_dst3_text.len);
++ b->last = ngx_cpymem(b->last, " ", 1);
++
++ /* src4 */
++ ngx_memzero(port, 6);
++ sprintf(port,"%d", pp.pp_src4);
++ b->last = ngx_cpymem(b->last, port, strlen(port));
++ b->last = ngx_cpymem(b->last, " ", 1);
++
++ /* dst4 */
++ ngx_memzero(port, 6);
++ sprintf(port,"%d", pp.pp_dst4);
++ b->last = ngx_cpymem(b->last, port, strlen(port));
++
++ /* CRLF */
++ b->last = ngx_cpymem(b->last, CRLF, sizeof(CRLF) - 1);
++
++ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, uc->log, 0,
++ "http upstream send proxy protocol: %d -%*s-",
++ ngx_proxy_protocol_string_length(&pp),
++ ngx_proxy_protocol_string_length(&pp) - 2,
++ b->start);
++
++ rc = ngx_output_chain(&u->output, pp_string);
++
++ if (rc == NGX_ERROR) {
++ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
++ return;
++ }
++
++}
++
++#endif
++
++
+ static void
+ ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
+ ngx_http_upstream_t *u)
+Index: nginx-1.4.7/src/http/ngx_http_upstream.h
+===================================================================
+--- nginx-1.4.7.orig/src/http/ngx_http_upstream.h
++++ nginx-1.4.7/src/http/ngx_http_upstream.h
+@@ -188,6 +188,10 @@ typedef struct {
+ unsigned intercept_404:1;
+ unsigned change_buffering:1;
+
++#if (NGX_PROXY_PROTOCOL)
++ ngx_flag_t send_proxy_protocol;
++#endif
++
+ #if (NGX_HTTP_SSL)
+ ngx_ssl_t *ssl;
+ ngx_flag_t ssl_session_reuse;
+Index: nginx-1.4.7/auto/cc/gcc
+===================================================================
+--- nginx-1.4.7.orig/auto/cc/gcc
++++ nginx-1.4.7/auto/cc/gcc
+@@ -168,7 +168,7 @@ esac
+
+
+ # stop on warning
+-CFLAGS="$CFLAGS -Werror"
++CFLAGS="$CFLAGS"
+
+ # debug
+ CFLAGS="$CFLAGS -g"
+Index: nginx-1.4.7/auto/cc/icc
+===================================================================
+--- nginx-1.4.7.orig/auto/cc/icc
++++ nginx-1.4.7/auto/cc/icc
+@@ -115,7 +115,7 @@ case "$NGX_ICC_VER" in
+ esac
+
+ # stop on warning
+-CFLAGS="$CFLAGS -Werror"
++CFLAGS="$CFLAGS "
+
+ # debug
+ CFLAGS="$CFLAGS -g"
diff --git a/net/nginx/patches/401-nginx-1.4.0-syslog.patch b/net/nginx/patches/401-nginx-1.4.0-syslog.patch
new file mode 100644
index 000000000..941c79aee
--- /dev/null
+++ b/net/nginx/patches/401-nginx-1.4.0-syslog.patch
@@ -0,0 +1,698 @@
+Index: nginx-1.4.7/src/core/ngx_cycle.c
+===================================================================
+--- nginx-1.4.7.orig/src/core/ngx_cycle.c
++++ nginx-1.4.7/src/core/ngx_cycle.c
+@@ -85,6 +85,12 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
+ cycle->pool = pool;
+ cycle->log = log;
+ cycle->new_log.log_level = NGX_LOG_ERR;
++#if (NGX_ENABLE_SYSLOG)
++ cycle->new_log.facility = SYSLOG_FACILITY;
++ cycle->new_log.facility = ERR_SYSLOG_PRIORITY;
++ cycle->new_log.syslog_on = 0;
++ cycle->new_log.syslog_set = 0;
++#endif
+ cycle->old_cycle = old_cycle;
+
+ cycle->conf_prefix.len = old_cycle->conf_prefix.len;
+Index: nginx-1.4.7/src/core/ngx_log.c
+===================================================================
+--- nginx-1.4.7.orig/src/core/ngx_log.c
++++ nginx-1.4.7/src/core/ngx_log.c
+@@ -10,6 +10,15 @@
+
+
+ static char *ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
++#if (NGX_ENABLE_SYSLOG)
++static char *ngx_set_syslog(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
++void log_exit(ngx_cycle_t *cycle);
++
++typedef struct{
++ ngx_str_t name;
++ ngx_int_t macro;
++} ngx_string_to_macro_t;
++#endif
+
+
+ static ngx_command_t ngx_errlog_commands[] = {
+@@ -21,6 +30,15 @@ static ngx_command_t ngx_errlog_command
+ 0,
+ NULL},
+
++#if (NGX_ENABLE_SYSLOG)
++ {ngx_string("syslog"),
++ NGX_MAIN_CONF|NGX_CONF_TAKE12,
++ ngx_set_syslog,
++ 0,
++ 0,
++ NULL},
++#endif
++
+ ngx_null_command
+ };
+
+@@ -43,7 +61,11 @@ ngx_module_t ngx_errlog_module = {
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+- NULL, /* exit master */
++#if (NGX_ENABLE_SYSLOG)
++ log_exit, /* exit master */
++#else
++ NULL,
++#endif
+ NGX_MODULE_V1_PADDING
+ };
+
+@@ -52,6 +74,48 @@ static ngx_log_t ngx_log;
+ static ngx_open_file_t ngx_log_file;
+ ngx_uint_t ngx_use_stderr = 1;
+
++#if (NGX_ENABLE_SYSLOG)
++static ngx_string_to_macro_t ngx_syslog_facilities[] = {
++ {ngx_string("auth"), LOG_AUTH},
++#if !(NGX_SOLARIS)
++ {ngx_string("authpriv"), LOG_AUTHPRIV},
++#endif
++ {ngx_string("cron"), LOG_CRON},
++ {ngx_string("daemon"), LOG_DAEMON},
++#if !(NGX_SOLARIS)
++ {ngx_string("ftp"), LOG_FTP},
++#endif
++ {ngx_string("kern"), LOG_KERN},
++ {ngx_string("local0"), LOG_LOCAL0},
++ {ngx_string("local1"), LOG_LOCAL1},
++ {ngx_string("local2"), LOG_LOCAL2},
++ {ngx_string("local3"), LOG_LOCAL3},
++ {ngx_string("local4"), LOG_LOCAL4},
++ {ngx_string("local5"), LOG_LOCAL5},
++ {ngx_string("local6"), LOG_LOCAL6},
++ {ngx_string("local7"), LOG_LOCAL7},
++ {ngx_string("lpr"), LOG_LPR},
++ {ngx_string("mail"), LOG_MAIL},
++ {ngx_string("news"), LOG_NEWS},
++ {ngx_string("syslog"), LOG_SYSLOG},
++ {ngx_string("user"), LOG_USER},
++ {ngx_string("uucp"), LOG_UUCP},
++ { ngx_null_string, 0}
++};
++
++static ngx_string_to_macro_t ngx_syslog_priorities[] = {
++ {ngx_string("emerg"), LOG_EMERG},
++ {ngx_string("alert"), LOG_ALERT},
++ {ngx_string("crit"), LOG_CRIT},
++ {ngx_string("error"), LOG_ERR},
++ {ngx_string("err"), LOG_ERR},
++ {ngx_string("warn"), LOG_WARNING},
++ {ngx_string("notice"),LOG_NOTICE},
++ {ngx_string("info"), LOG_INFO},
++ {ngx_string("debug"), LOG_DEBUG},
++ { ngx_null_string, 0}
++};
++#endif
+
+ static ngx_str_t err_levels[] = {
+ ngx_null_string,
+@@ -89,11 +153,16 @@ ngx_log_error_core(ngx_uint_t level, ngx
+ va_list args;
+ #endif
+ u_char *p, *last, *msg;
++#if (NGX_ENABLE_SYSLOG)
++ u_char *errstr_syslog;
++#endif
+ u_char errstr[NGX_MAX_ERROR_STR];
+
++#if !(NGX_ENABLE_SYSLOG)
+ if (log->file->fd == NGX_INVALID_FILE) {
+ return;
+ }
++#endif
+
+ last = errstr + NGX_MAX_ERROR_STR;
+
+@@ -102,6 +171,10 @@ ngx_log_error_core(ngx_uint_t level, ngx
+
+ p = errstr + ngx_cached_err_log_time.len;
+
++#if (NGX_ENABLE_SYSLOG)
++ errstr_syslog = p;
++#endif
++
+ p = ngx_slprintf(p, last, " [%V] ", &err_levels[level]);
+
+ /* pid#tid */
+@@ -140,11 +213,27 @@ ngx_log_error_core(ngx_uint_t level, ngx
+
+ ngx_linefeed(p);
+
++#if (NGX_ENABLE_SYSLOG)
++ if (log->file != NULL && log->file->name.len != 0) {
+ (void) ngx_write_fd(log->file->fd, errstr, p - errstr);
++ }
++
++ /* Don't send the debug level info to syslog */
++ if (log->syslog_on && level < NGX_LOG_DEBUG) {
++ /* write to syslog */
++ syslog(log->priority, "%.*s", (int)(p - errstr_syslog), errstr_syslog);
++ }
++#else
++ (void) ngx_write_fd(log->file->fd, errstr, p - errstr);
++#endif
+
+ if (!ngx_use_stderr
+ || level > NGX_LOG_WARN
++#if (NGX_ENABLE_SYSLOG)
++ || (log->file != NULL && log->file->fd == ngx_stderr))
++#else
+ || log->file->fd == ngx_stderr)
++#endif
+ {
+ return;
+ }
+@@ -367,6 +456,50 @@ ngx_log_create(ngx_cycle_t *cycle, ngx_s
+ }
+
+
++#if (NGX_ENABLE_SYSLOG)
++ngx_int_t
++ngx_log_get_priority(ngx_conf_t *cf, ngx_str_t *priority)
++{
++ ngx_int_t p = 0;
++ ngx_uint_t n, match = 0;
++
++ for (n = 0; ngx_syslog_priorities[n].name.len != 0; n++) {
++ if (ngx_strncmp(priority->data, ngx_syslog_priorities[n].name.data,
++ ngx_syslog_priorities[n].name.len) == 0) {
++ p = ngx_syslog_priorities[n].macro;
++ match = 1;
++ }
++ }
++
++ if (!match) {
++ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
++ "invalid syslog priority \"%V\"", priority);
++ return -1;
++ }
++
++ return p;
++}
++
++
++char *
++ngx_log_set_priority(ngx_conf_t *cf, ngx_str_t *priority, ngx_log_t *log)
++{
++ log->priority = ERR_SYSLOG_PRIORITY;
++
++ if (priority->len == 0) {
++ return NGX_CONF_OK;
++ }
++
++ log->priority = ngx_log_get_priority(cf, priority);
++ if (log->priority == (-1)) {
++ return NGX_CONF_ERROR;
++ }
++
++ return NGX_CONF_OK;
++}
++#endif
++
++
+ char *
+ ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log)
+ {
+@@ -429,6 +562,13 @@ static char *
+ ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+ {
+ ngx_str_t *value, name;
++#if (NGX_ENABLE_SYSLOG)
++ u_char *off = NULL;
++ ngx_str_t priority;
++
++ ngx_str_null(&name);
++ ngx_str_null(&priority);
++#endif
+
+ if (cf->cycle->new_log.file) {
+ return "is duplicate";
+@@ -436,7 +576,44 @@ ngx_error_log(ngx_conf_t *cf, ngx_comman
+
+ value = cf->args->elts;
+
++#if (NGX_ENABLE_SYSLOG)
++ if (ngx_strncmp(value[1].data, "syslog", sizeof("syslog") - 1) == 0) {
++ if (!cf->cycle->new_log.syslog_set) {
++ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
++ "You must set the syslog directive and enable it first.");
++ return NGX_CONF_ERROR;
++ }
++
++ cf->cycle->new_log.syslog_on = 1;
++
++ if (value[1].data[sizeof("syslog") - 1] == ':') {
++ priority.len = value[1].len - sizeof("syslog");
++ priority.data = value[1].data + sizeof("syslog");
++
++ off = (u_char *)ngx_strchr(priority.data, (int) '|');
++ if (off != NULL) {
++ priority.len = off - priority.data;
++
++ off++;
++ name.len = value[1].data + value[1].len - off;
++ name.data = off;
++ }
++ }
++ else {
++ if (value[1].len > sizeof("syslog")) {
++ name.len = value[1].len - sizeof("syslog");
++ name.data = value[1].data + sizeof("syslog");
++ }
++ }
++
++ if (ngx_log_set_priority(cf, &priority, &cf->cycle->new_log) == NGX_CONF_ERROR) {
++ return NGX_CONF_ERROR;
++ }
++ }
++ else if (ngx_strcmp(value[1].data, "stderr") == 0) {
++#else
+ if (ngx_strcmp(value[1].data, "stderr") == 0) {
++#endif
+ ngx_str_null(&name);
+
+ } else {
+@@ -457,3 +634,63 @@ ngx_error_log(ngx_conf_t *cf, ngx_comman
+
+ return ngx_log_set_levels(cf, &cf->cycle->new_log);
+ }
++
++
++#if (NGX_ENABLE_SYSLOG)
++
++#define SYSLOG_IDENT_NAME "nginx"
++
++static char *
++ngx_set_syslog(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
++{
++ char *program;
++ ngx_str_t *value;
++ ngx_int_t facility, match = 0;
++ ngx_uint_t n;
++
++ value = cf->args->elts;
++
++ if (cf->cycle->new_log.syslog_set) {
++ return "is duplicate";
++ }
++
++ cf->cycle->new_log.syslog_set = 1;
++
++ for (n = 0; ngx_syslog_facilities[n].name.len != 0; n++) {
++ if (ngx_strncmp(value[1].data, ngx_syslog_facilities[n].name.data,
++ ngx_syslog_facilities[n].name.len) == 0) {
++ facility = ngx_syslog_facilities[n].macro;
++ match = 1;
++ break;
++ }
++ }
++
++ if (match) {
++ cf->cycle->new_log.facility = facility;
++ cf->cycle->new_log.priority = ERR_SYSLOG_PRIORITY;
++ }
++ else {
++ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
++ "invalid syslog facility \"%V\"", &value[1]);
++ return NGX_CONF_ERROR;
++ }
++
++ program = SYSLOG_IDENT_NAME;
++ if (cf->args->nelts > 2) {
++ program = (char *) value[2].data;
++ }
++
++ openlog(program, LOG_ODELAY, facility);
++
++ return NGX_CONF_OK;
++}
++
++
++void log_exit(ngx_cycle_t *cycle)
++{
++ if (cycle->new_log.syslog_set) {
++ closelog();
++ }
++}
++#endif
++
+Index: nginx-1.4.7/src/core/ngx_log.h
+===================================================================
+--- nginx-1.4.7.orig/src/core/ngx_log.h
++++ nginx-1.4.7/src/core/ngx_log.h
+@@ -12,6 +12,13 @@
+ #include <ngx_config.h>
+ #include <ngx_core.h>
+
++#if (NGX_ENABLE_SYSLOG)
++#include <syslog.h>
++
++#define SYSLOG_FACILITY LOG_LOCAL5
++#define ERR_SYSLOG_PRIORITY LOG_ERR
++#endif
++
+
+ #define NGX_LOG_STDERR 0
+ #define NGX_LOG_EMERG 1
+@@ -61,6 +68,13 @@ struct ngx_log_s {
+ */
+
+ char *action;
++
++#if (NGX_ENABLE_SYSLOG)
++ ngx_int_t priority;
++ ngx_int_t facility;
++ unsigned syslog_on:1; /* unsigned :1 syslog_on */
++ unsigned syslog_set:1; /*unsigned :1 syslog_set */
++#endif
+ };
+
+
+@@ -221,6 +235,10 @@ void ngx_cdecl ngx_log_debug_core(ngx_lo
+
+ ngx_log_t *ngx_log_init(u_char *prefix);
+ ngx_log_t *ngx_log_create(ngx_cycle_t *cycle, ngx_str_t *name);
++#if (NGX_ENABLE_SYSLOG)
++ngx_int_t ngx_log_get_priority(ngx_conf_t *cf, ngx_str_t *priority);
++char * ngx_log_set_priority(ngx_conf_t *cf, ngx_str_t *priority, ngx_log_t *log);
++#endif
+ char *ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log);
+ void ngx_cdecl ngx_log_abort(ngx_err_t err, const char *fmt, ...);
+ void ngx_cdecl ngx_log_stderr(ngx_err_t err, const char *fmt, ...);
+Index: nginx-1.4.7/src/http/modules/ngx_http_log_module.c
+===================================================================
+--- nginx-1.4.7.orig/src/http/modules/ngx_http_log_module.c
++++ nginx-1.4.7/src/http/modules/ngx_http_log_module.c
+@@ -13,6 +13,11 @@
+ #include <zlib.h>
+ #endif
+
++#if (NGX_ENABLE_SYSLOG)
++#include <syslog.h>
++
++#define HTTP_SYSLOG_PRIORITY LOG_NOTICE
++#endif
+
+ typedef struct ngx_http_log_op_s ngx_http_log_op_t;
+
+@@ -67,6 +72,11 @@ typedef struct {
+ time_t disk_full_time;
+ time_t error_log_time;
+ ngx_http_log_fmt_t *format;
++
++#if (NGX_ENABLE_SYSLOG)
++ ngx_int_t priority;
++ unsigned syslog_on:1; /* unsigned :1 syslog_on */
++#endif
+ } ngx_http_log_t;
+
+
+@@ -348,6 +358,14 @@ ngx_http_log_write(ngx_http_request_t *r
+ time_t now;
+ ssize_t n;
+ ngx_err_t err;
++
++#if (NGX_ENABLE_SYSLOG)
++ n = 0;
++ if (log->syslog_on) {
++ syslog(log->priority, "%.*s", (int)len, buf);
++ }
++#endif
++
+ #if (NGX_ZLIB)
+ ngx_http_log_buf_t *buffer;
+ #endif
+@@ -355,6 +373,9 @@ ngx_http_log_write(ngx_http_request_t *r
+ if (log->script == NULL) {
+ name = log->file->name.data;
+
++#if (NGX_ENABLE_SYSLOG)
++ if (name != NULL) {
++#endif
+ #if (NGX_ZLIB)
+ buffer = log->file->data;
+
+@@ -367,7 +388,11 @@ ngx_http_log_write(ngx_http_request_t *r
+ #else
+ n = ngx_write_fd(log->file->fd, buf, len);
+ #endif
+-
++#if (NGX_ENABLE_SYSLOG)
++ } else {
++ n = len;
++ }
++#endif
+ } else {
+ name = NULL;
+ n = ngx_http_log_script_write(r, log->script, &name, buf, len);
+@@ -1068,6 +1093,10 @@ ngx_http_log_merge_loc_conf(ngx_conf_t *
+ log->script = NULL;
+ log->disk_full_time = 0;
+ log->error_log_time = 0;
++#if (NGX_ENABLE_SYSLOG)
++ log->priority = HTTP_SYSLOG_PRIORITY;
++ log->syslog_on = 0;
++#endif
+
+ lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
+ fmt = lmcf->formats.elts;
+@@ -1096,6 +1125,13 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx
+ ngx_http_log_main_conf_t *lmcf;
+ ngx_http_script_compile_t sc;
+
++#if (NGX_ENABLE_SYSLOG)
++ u_char *off;
++ ngx_str_t priority;
++ ngx_uint_t syslog_on = 0;
++ name = priority = (ngx_str_t)ngx_null_string;
++#endif
++
+ value = cf->args->elts;
+
+ if (ngx_strcmp(value[1].data, "off") == 0) {
+@@ -1108,6 +1144,38 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx
+ "invalid parameter \"%V\"", &value[2]);
+ return NGX_CONF_ERROR;
+ }
++#if (NGX_ENABLE_SYSLOG)
++ else if (ngx_strncmp(value[1].data, "syslog", sizeof("syslog") - 1) == 0) {
++ if (!cf->cycle->new_log.syslog_set) {
++ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
++ "You must set the syslog directive and enable it first.");
++ return NGX_CONF_ERROR;
++ }
++
++ syslog_on = 1;
++ if (value[1].data[sizeof("syslog") - 1] == ':') {
++ priority.len = value[1].len - sizeof("syslog");
++ priority.data = value[1].data + sizeof("syslog");
++
++ off = (u_char*) ngx_strchr(priority.data, '|');
++ if (off != NULL) {
++ priority.len = off - priority.data;
++
++ off++;
++ name.len = value[1].data + value[1].len - off;
++ name.data = off;
++ }
++ }
++ else {
++ if (value[1].len > sizeof("syslog")) {
++ name.len = value[1].len - sizeof("syslog");
++ name.data = value[1].data + sizeof("syslog");
++ }
++ }
++ } else {
++ name = value[1];
++ }
++#endif
+
+ if (llcf->logs == NULL) {
+ llcf->logs = ngx_array_create(cf->pool, 2, sizeof(ngx_http_log_t));
+@@ -1125,6 +1193,52 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx
+
+ ngx_memzero(log, sizeof(ngx_http_log_t));
+
++#if (NGX_ENABLE_SYSLOG)
++ log->syslog_on = syslog_on;
++
++ if (priority.len == 0) {
++ log->priority = HTTP_SYSLOG_PRIORITY;
++ }
++ else {
++ log->priority = ngx_log_get_priority(cf, &priority);
++ }
++
++ if (name.len != 0) {
++ n = ngx_http_script_variables_count(&name);
++
++ if (n == 0) {
++ log->file = ngx_conf_open_file(cf->cycle, &name);
++ if (log->file == NULL) {
++ return NGX_CONF_ERROR;
++ }
++ } else {
++ if (ngx_conf_full_name(cf->cycle, &name, 0) != NGX_OK) {
++ return NGX_CONF_ERROR;
++ }
++ log->script = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_script_t));
++ if (log->script == NULL) {
++ return NGX_CONF_ERROR;
++ }
++ ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
++ sc.cf = cf;
++ sc.source = &name;
++ sc.lengths = &log->script->lengths;
++ sc.values = &log->script->values;
++ sc.variables = n;
++ sc.complete_lengths = 1;
++ sc.complete_values = 1;
++ if (ngx_http_script_compile(&sc) != NGX_OK) {
++ return NGX_CONF_ERROR;
++ }
++ }
++ }
++ else {
++ log->file = ngx_conf_open_file(cf->cycle, &name);
++ if (log->file == NULL) {
++ return NGX_CONF_ERROR;
++ }
++ }
++#else
+ n = ngx_http_script_variables_count(&value[1]);
+
+ if (n == 0) {
+@@ -1157,6 +1271,7 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx
+ return NGX_CONF_ERROR;
+ }
+ }
++#endif
+
+ if (cf->args->nelts >= 3) {
+ name = value[2];
+Index: nginx-1.4.7/src/http/ngx_http_core_module.c
+===================================================================
+--- nginx-1.4.7.orig/src/http/ngx_http_core_module.c
++++ nginx-1.4.7/src/http/ngx_http_core_module.c
+@@ -1462,6 +1462,9 @@ ngx_http_update_location_config(ngx_http
+
+ if (r == r->main) {
+ ngx_http_set_connection_log(r->connection, clcf->error_log);
++#if (NGX_ENABLE_SYSLOG)
++ r->connection->log->priority = clcf->error_log->priority;
++#endif
+ }
+
+ if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) {
+@@ -4901,6 +4904,15 @@ ngx_http_core_error_log(ngx_conf_t *cf,
+
+ ngx_str_t *value, name;
+
++#if (NGX_ENABLE_SYSLOG)
++ u_char *off = NULL;
++ ngx_int_t syslog_on = 0;
++ ngx_str_t priority;
++
++ name = priority = (ngx_str_t) ngx_null_string;
++#endif
++
++
+ if (clcf->error_log) {
+ return "is duplicate";
+ }
+@@ -4910,6 +4922,36 @@ ngx_http_core_error_log(ngx_conf_t *cf,
+ if (ngx_strcmp(value[1].data, "stderr") == 0) {
+ ngx_str_null(&name);
+
++#if (NGX_ENABLE_SYSLOG)
++ } else if (ngx_strncmp(value[1].data, "syslog", sizeof("syslog") - 1) == 0) {
++ if (!cf->cycle->new_log.syslog_set) {
++ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
++ "You must set the syslog directive and enable it first.");
++ return NGX_CONF_ERROR;
++ }
++
++ syslog_on = 1;
++
++ if (value[1].data[sizeof("syslog") - 1] == ':') {
++ priority.len = value[1].len - sizeof("syslog");
++ priority.data = value[1].data + sizeof("syslog");
++
++ off = (u_char*) ngx_strchr(priority.data, '|');
++ if (off != NULL) {
++ priority.len = off - priority.data;
++
++ off++;
++ name.len = value[1].data + value[1].len - off;
++ name.data = off;
++ }
++ }
++ else {
++ if (value[1].len > sizeof("syslog")) {
++ name.len = value[1].len - sizeof("syslog");
++ name.data = value[1].data + sizeof("syslog");
++ }
++ }
++#endif
+ } else {
+ name = value[1];
+ }
+@@ -4919,6 +4961,17 @@ ngx_http_core_error_log(ngx_conf_t *cf,
+ return NGX_CONF_ERROR;
+ }
+
++#if (NGX_ENABLE_SYSLOG)
++ if (syslog_on) {
++ clcf->error_log->syslog_on = 1;
++ if (ngx_log_set_priority(cf, &priority, clcf->error_log) == NGX_CONF_ERROR) {
++ return NGX_CONF_ERROR;
++ }
++ }
++
++ clcf->error_log->log_level = 0;
++#endif
++
+ if (cf->args->nelts == 2) {
+ clcf->error_log->log_level = NGX_LOG_ERR;
+ return NGX_CONF_OK;
+Index: nginx-1.4.7/src/http/ngx_http_request.c
+===================================================================
+--- nginx-1.4.7.orig/src/http/ngx_http_request.c
++++ nginx-1.4.7/src/http/ngx_http_request.c
+@@ -533,6 +533,9 @@ ngx_http_create_request(ngx_connection_t
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ ngx_http_set_connection_log(r->connection, clcf->error_log);
++#if (NGX_ENABLE_SYSLOG)
++ c->log->priority = clcf->error_log->priority;
++#endif
+
+ r->header_in = hc->nbusy ? hc->busy[0] : c->buffer;
+
+@@ -872,6 +875,9 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *
+ clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module);
+
+ ngx_http_set_connection_log(c, clcf->error_log);
++#if (NGX_ENABLE_SYSLOG)
++ c->log->priority = clcf->error_log->priority;
++#endif
+
+ sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
+
+@@ -2077,6 +2083,9 @@ ngx_http_set_virtual_server(ngx_http_req
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ ngx_http_set_connection_log(r->connection, clcf->error_log);
++#if (NGX_ENABLE_SYSLOG)
++ r->connection->log->priority = clcf->error_log->priority;
++#endif
+
+ return NGX_OK;
+ }