nginx: import from packages, add myself as the maintainer 48/head
authorThomas Heil <heil@terminal-consulting.de>
Mon, 23 Jun 2014 14:37:24 +0000 (16:37 +0200)
committerThomas Heil <heil@terminal-consulting.de>
Mon, 23 Jun 2014 14:37:24 +0000 (16:37 +0200)
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>
14 files changed:
net/nginx/Config.in [new file with mode: 0644]
net/nginx/Makefile [new file with mode: 0644]
net/nginx/files/nginx.init [new file with mode: 0644]
net/nginx/files/nginx.proxyprotocol.example [new file with mode: 0644]
net/nginx/files/nginx.syslog.example [new file with mode: 0644]
net/nginx/patches-lua-nginx/300-ldl.patch [new file with mode: 0644]
net/nginx/patches-nginx-upstream-check/check_1.2.6+.patch [new file with mode: 0644]
net/nginx/patches/101-feature_test_fix.patch [new file with mode: 0644]
net/nginx/patches/102-sizeof_test_fix.patch [new file with mode: 0644]
net/nginx/patches/103-sys_nerr.patch [new file with mode: 0644]
net/nginx/patches/200-config.patch [new file with mode: 0644]
net/nginx/patches/300-crosscompile_ccflags.patch [new file with mode: 0644]
net/nginx/patches/400-nginx-1.4.x_proxy_protocol_patch_v2.patch [new file with mode: 0644]
net/nginx/patches/401-nginx-1.4.0-syslog.patch [new file with mode: 0644]

diff --git a/net/nginx/Config.in b/net/nginx/Config.in
new file mode 100644 (file)
index 0000000..1b60626
--- /dev/null
@@ -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 (file)
index 0000000..06d9275
--- /dev/null
@@ -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 (file)
index 0000000..adf36b4
--- /dev/null
@@ -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 (file)
index 0000000..ab4bad6
--- /dev/null
@@ -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 (file)
index 0000000..0594344
--- /dev/null
@@ -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 (file)
index 0000000..d826bcf
--- /dev/null
@@ -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 (file)
index 0000000..3ab9134
--- /dev/null
@@ -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 (file)
index 0000000..8e15fe9
--- /dev/null
@@ -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 (file)
index 0000000..0cd93cc
--- /dev/null
@@ -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 (file)
index 0000000..5f5d106
--- /dev/null
@@ -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 (file)
index 0000000..f350095
--- /dev/null
@@ -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 (file)
index 0000000..4a06a76
--- /dev/null
@@ -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 (file)
index 0000000..52c1ce7
--- /dev/null
@@ -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 (file)
index 0000000..941c79a
--- /dev/null
@@ -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;
+ }