diff --git a/net/nginx/Config.in b/net/nginx/Config.in new file mode 100644 index 0000000000..1b60626152 --- /dev/null +++ b/net/nginx/Config.in @@ -0,0 +1,187 @@ +# +# Copyright (C) 2010-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +menu "Configuration" + depends on PACKAGE_nginx + +config NGINX_STUB_STATUS + bool + prompt "Enable stub status module" + help + Enable the stub status module which gives some status from the server. + +config NGINX_FLV + bool + prompt "Enable FLV module" + help + Provides the ability to seek within FLV (Flash) files using time-based offsets. + +config NGINX_SSL + bool + prompt "Enable SSL module" + help + Enable HTTPS/SSL support. + +config NGINX_DAV + bool + prompt "Enable WebDAV module" + help + Enable the HTTP and WebDAV methods PUT, DELETE, MKCOL, COPY and MOVE. + +config NGINX_LUA + bool + prompt "Enable LUA module" + help + Enable support for LUA scripts. + +config NGINX_PCRE + bool + prompt "Enable PCRE library usage" + default y + +config NGINX_HTTP_CACHE + bool + prompt "Enable HTTP cache" + +config NGINX_HTTP_CHARSET + bool + prompt "Enable HTTP charset module" + default y + +config NGINX_HTTP_GZIP + bool + prompt "Enable HTTP gzip module" + default y + +config NGINX_HTTP_SSI + bool + prompt "Enable HTTP ssi module" + default y + +config NGINX_HTTP_USERID + bool + prompt "Enable HTTP userid module" + default y + +config NGINX_HTTP_ACCESS + bool + prompt "Enable HTTP access module" + default y + +config NGINX_HTTP_AUTH_BASIC + bool + prompt "Enable HTTP auth basic" + default y + +config NGINX_HTTP_AUTOINDEX + bool + prompt "Enable HTTP autoindex module" + default y + +config NGINX_HTTP_GEO + bool + prompt "Enable HTTP geo module" + default y + +config NGINX_HTTP_MAP + bool + prompt "Enable HTTP map module" + default y + +config NGINX_HTTP_SPLIT_CLIENTS + bool + prompt "Enable HTTP split clients" + default y + +config NGINX_HTTP_REFERER + bool + prompt "Enable HTTP referer module" + default y + +config NGINX_HTTP_REWRITE + bool + prompt "Enable HTTP rewrite module" + select NGINX_PCRE + default y + +config NGINX_HTTP_PROXY + bool + prompt "Enable HTTP proxy module" + default y + +config NGINX_HTTP_FASTCGI + bool + prompt "Enable HTTP fastcgi module" + default y + +config NGINX_HTTP_UWSGI + bool + prompt "Enable HTTP uwsgi module" + default y + +config NGINX_HTTP_SCGI + bool + prompt "Enable HTTP scgi module" + default y + +config NGINX_HTTP_MEMCACHED + bool + prompt "Enable HTTP memcached module" + default y + +config NGINX_HTTP_LIMIT_CONN + bool + prompt "Enable HTTP limit conn" + default y + +config NGINX_HTTP_LIMIT_REQ + bool + prompt "Enable HTTP limit req" + default y + +config NGINX_HTTP_EMPTY_GIF + bool + prompt "Enable HTTP empty gif" + default y + +config NGINX_HTTP_BROWSER + bool + prompt "Enable HTTP browser module" + default y + +config NGINX_HTTP_UPSTREAM_IP_HASH + bool + prompt "Enable HTTP IP hash module" + default y + +config NGINX_NAXSI + bool + prompt "Enable NAXSI module" + select PACKAGE_nginx-naxsi + help + Enable support for NAXSI WAF. + +config NGINX_PROXYPROTOCOL + bool + prompt "Enable NAXSI proxyprotocol" + select PACKAGE_nginx-proxyprotocol + help + Enable support for NAXSI WAF. + +config NGINX_SYSLOG + bool + prompt "Enable Syslog module" + select PACKAGE_nginx-syslog + help + Provides the ability log to a remote destination + +config NGINX_HTTP_UPSTREAM_CHECK + bool + prompt "Enable HTTP upstream check module" + default y + +endmenu diff --git a/net/nginx/Makefile b/net/nginx/Makefile new file mode 100644 index 0000000000..06d92758bf --- /dev/null +++ b/net/nginx/Makefile @@ -0,0 +1,334 @@ +# +# Copyright (C) 2009-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=nginx +PKG_VERSION:=1.4.7 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://nginx.org/download/ +PKG_MD5SUM:=aee151d298dcbfeb88b3f7dd3e7a4d17 +PKG_MAINTAINER:=Thomas Heil +PKG_LICENSE:=2-clause BSD-like license + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +PKG_CONFIG_DEPENDS := \ + CONFIG_NGINX_STUB_STATUS \ + CONFIG_NGINX_FLV \ + CONFIG_NGINX_SSL \ + CONFIG_NGINX_DAV \ + CONFIG_NGINX_LUA \ + CONFIG_NGINX_PCRE \ + CONFIG_NGINX_HTTP_CACHE \ + CONFIG_NGINX_HTTP_CHARSET \ + CONFIG_NGINX_HTTP_GZIP \ + CONFIG_NGINX_HTTP_SSI \ + CONFIG_NGINX_HTTP_USERID \ + CONFIG_NGINX_HTTP_ACCESS \ + CONFIG_NGINX_HTTP_AUTH_BASIC \ + CONFIG_NGINX_HTTP_AUTOINDEX \ + CONFIG_NGINX_HTTP_GEO \ + CONFIG_NGINX_HTTP_MAP \ + CONFIG_NGINX_HTTP_SPLIT_CLIENTS \ + CONFIG_NGINX_HTTP_REFERER \ + CONFIG_NGINX_HTTP_REWRITE \ + CONFIG_NGINX_HTTP_PROXY \ + CONFIG_NGINX_HTTP_FASTCGI \ + CONFIG_NGINX_HTTP_UWSGI \ + CONFIG_NGINX_HTTP_SCGI \ + CONFIG_NGINX_HTTP_MEMCACHED \ + CONFIG_NGINX_HTTP_LIMIT_CONN \ + CONFIG_NGINX_HTTP_LIMIT_REQ \ + CONFIG_NGINX_HTTP_EMPTY_GIF \ + CONFIG_NGINX_HTTP_BROWSER \ + CONFIG_NGINX_HTTP_UPSTREAM_IP_HASH + +include $(INCLUDE_DIR)/package.mk + +define Package/nginx + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=Nginx web server + URL:=http://nginx.org/ + DEPENDS:=+NGINX_PCRE:libpcre +(NGINX_SSL||NGINX_HTTP_CACHE||NGINX_HTTP_AUTH_BASIC):libopenssl +NGINX_HTTP_GZIP:zlib +libpthread +NGINX_LUA:liblua + MENU:=1 +endef + +define Package/nginx/description + nginx is an HTTP and reverse proxy server, as well as a mail proxy server, + written by Igor Sysoev. +endef + +define Package/nginx/config + source "$(SOURCE)/Config.in" +endef + +config_files=nginx.conf mime.types fastcgi_params koi-utf koi-win win-utf + +define Package/nginx/conffiles +/etc/nginx/ +endef + +ADDITIONAL_MODULES:= +ifeq ($(CONFIG_NGINX_NAXSI),y) + ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-naxsi/naxsi_src +endif +ifeq ($(CONFIG_IPV6),y) + ADDITIONAL_MODULES += --with-ipv6 +endif +ifeq ($(CONFIG_NGINX_STUB_STATUS),y) + ADDITIONAL_MODULES += --with-http_stub_status_module +endif +ifeq ($(CONFIG_NGINX_FLV),y) + ADDITIONAL_MODULES += --with-http_flv_module +endif +ifeq ($(CONFIG_NGINX_SSL),y) + ADDITIONAL_MODULES += --with-http_ssl_module +endif +ifeq ($(CONFIG_NGINX_DAV),y) + ADDITIONAL_MODULES += --with-http_dav_module +endif +ifeq ($(CONFIG_NGINX_LUA),y) + ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/lua-nginx +endif +ifneq ($(CONFIG_NGINX_HTTP_CACHE),y) + ADDITIONAL_MODULES += --without-http-cache +endif +ifneq ($(CONFIG_NGINX_PCRE),y) + ADDITIONAL_MODULES += --without-pcre +endif +ifneq ($(CONFIG_NGINX_HTTP_CHARSET),y) + ADDITIONAL_MODULES += --without-http_charset_module +endif +ifneq ($(CONFIG_NGINX_HTTP_GZIP),y) + ADDITIONAL_MODULES += --without-http_gzip_module +endif +ifneq ($(CONFIG_NGINX_HTTP_SSI),y) + ADDITIONAL_MODULES += --without-http_ssi_module +endif +ifneq ($(CONFIG_NGINX_HTTP_USERID),y) + ADDITIONAL_MODULES += --without-http_userid_module +endif +ifneq ($(CONFIG_NGINX_HTTP_ACCESS),y) + ADDITIONAL_MODULES += --without-http_access_module +endif +ifneq ($(CONFIG_NGINX_HTTP_AUTH_BASIC),y) + ADDITIONAL_MODULES += --without-http_auth_basic_module +endif +ifneq ($(CONFIG_NGINX_HTTP_AUTOINDEX),y) + ADDITIONAL_MODULES += --without-http_autoindex_module +endif +ifneq ($(CONFIG_NGINX_HTTP_GEO),y) + ADDITIONAL_MODULES += --without-http_geo_module +endif +ifneq ($(CONFIG_NGINX_HTTP_MAP),y) + ADDITIONAL_MODULES += --without-http_map_module +endif +ifneq ($(CONFIG_NGINX_HTTP_SPLIT_CLIENTS),y) + ADDITIONAL_MODULES += --without-http_split_clients_module +endif +ifneq ($(CONFIG_NGINX_HTTP_REFERER),y) + ADDITIONAL_MODULES += --without-http_referer_module +endif +ifneq ($(CONFIG_NGINX_HTTP_REWRITE),y) + ADDITIONAL_MODULES += --without-http_rewrite_module +endif +ifneq ($(CONFIG_NGINX_HTTP_PROXY),y) + ADDITIONAL_MODULES += --without-http_proxy_module +endif +ifneq ($(CONFIG_NGINX_HTTP_FASTCGI),y) + ADDITIONAL_MODULES += --without-http_fastcgi_module +endif +ifneq ($(CONFIG_NGINX_HTTP_UWSGI),y) + ADDITIONAL_MODULES += --without-http_uwsgi_module +endif +ifneq ($(CONFIG_NGINX_HTTP_SCGI),y) + ADDITIONAL_MODULES += --without-http_scgi_module +endif +ifneq ($(CONFIG_NGINX_HTTP_MEMCACHED),y) + ADDITIONAL_MODULES += --without-http_memcached_module +endif +ifneq ($(CONFIG_NGINX_HTTP_LIMIT_CONN),y) + ADDITIONAL_MODULES += --without-http_limit_conn_module +endif +ifneq ($(CONFIG_NGINX_HTTP_LIMIT_REQ),y) + ADDITIONAL_MODULES += --without-http_limit_req_module +endif +ifneq ($(CONFIG_NGINX_HTTP_EMPTY_GIF),y) + ADDITIONAL_MODULES += --without-http_empty_gif_module +endif +ifneq ($(CONFIG_NGINX_HTTP_BROWSER),y) + ADDITIONAL_MODULES += --without-http_browser_module +endif +ifneq ($(CONFIG_NGINX_HTTP_UPSTREAM_IP_HASH),y) + ADDITIONAL_MODULES += --without-http_upstream_ip_hash_module +endif +ifeq ($(CONFIG_NGINX_PROXYPROTOCOL),y) + ADDITIONAL_MODULES += --with-proxy-protocol +endif +ifeq ($(CONFIG_NGINX_SYSLOG),y) + ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-syslog +endif +ifeq ($(CONFIG_NGINX_HTTP_UPSTREAM_CHECK),y) + ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-upstream-check +endif + +define Build/Configure + # TODO: fix --crossbuild + (cd $(PKG_BUILD_DIR) ;\ + $(if $(CONFIG_NGINX_LUA),LUA_INC=$(STAGING_DIR)/usr/include LUA_LIB=$(STAGING_DIR)/usr/lib) \ + ./configure \ + --crossbuild=Linux::$(ARCH) \ + --prefix=/usr \ + --conf-path=/etc/nginx/nginx.conf \ + $(ADDITIONAL_MODULES) \ + --error-log-path=/var/log/nginx/error.log \ + --pid-path=/var/run/nginx.pid \ + --lock-path=/var/lock/nginx.lock \ + --http-log-path=/var/log/nginx/access.log \ + --http-client-body-temp-path=/var/lib/nginx/body \ + --http-proxy-temp-path=/var/lib/nginx/proxy \ + --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \ + --with-cc="$(TARGET_CC)" \ + --with-cc-opt="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \ + --with-ld-opt="$(TARGET_LDFLAGS)" ) +endef + +define Package/nginx/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/nginx $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/etc/nginx + $(INSTALL_DATA) $(addprefix $(PKG_INSTALL_DIR)/etc/nginx/,$(config_files)) $(1)/etc/nginx/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/nginx.init $(1)/etc/init.d/nginx +endef + +define Build/Prepare + $(call Build/Prepare/Default) + $(if $(CONFIG_NGINX_LUA),$(call Prepare/lua-nginx)) + $(if $(CONFIG_NGINX_NAXSI),$(call Prepare/nginx-naxsi)) + $(if $(CONFIG_NGINX_SYSLOG),$(call Prepare/nginx-syslog)) + $(if $(CONFIG_NGINX_HTTP_UPSTREAM_CHECK),$(call Prepare/nginx-upstream-check)) +endef + +define Download/lua-nginx + VERSION:=d3ab0edd45bffe1b9a36abdf5bff544de436ccee + SUBDIR:=lua-nginx + FILE:=lua-nginx-module-$(PKG_VERSION)-$$(VERSION).tar.gz + URL:=https://github.com/chaoslawful/lua-nginx-module.git + PROTO:=git +endef + +define Prepare/lua-nginx + $(eval $(call Download,lua-nginx)) + gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) + $(call PatchDir,$(PKG_BUILD_DIR),./patches-lua-nginx) +endef + +define Download/nginx-upstream-check + VERSION:=d40b9f956d9d978005bb15616d2f283d4e3d2031 + SUBDIR:=nginx-upstream-check + FILE:=nginx-upstream-check-$(PKG_VERSION)-$$(VERSION).tar.gz + URL:=https://github.com/yaoweibin/nginx_upstream_check_module.git + PROTO:=git +endef + +define Prepare/nginx-upstream-check + $(eval $(call Download,nginx-upstream-check)) + gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) + $(call PatchDir,$(PKG_BUILD_DIR),./patches-nginx-upstream-check) +endef + + +define Package/nginx-naxsi + MENU:=1 + $(call Package/nginx) + TITLE+= nginx-naxsi + DEPENDS:=nginx +endef + +define Package/nginx-naxsi/description + NGINX WAF NAXSI +endef + +define Package/nginx-proxyprotocol + MENU:=1 + $(call Package/nginx) + TITLE+= nginx-proxyprotocol + DEPENDS:=nginx +endef + +define Package/nginx-proxyprotocol/description + IMPLEMENT Proxy Protocol +endef + +define Package/nginx-syslog + MENU:=1 + $(call Package/nginx) + TITLE+= nginx-syslog + DEPENDS:=nginx +endef + +define Package/nginx-syslog/description + IMPLEMENT Syslog Protocol +endef + +define Download/nginx-naxsi + VERSION:=34dcb45fe4fdcb144c5258d83672f8e1e1c8db2e + SUBDIR:=nginx-naxsi + FILE:=nginx-naxsi-module-$(PKG_VERSION)-$$(VERSION).tar.gz + URL:=https://github.com/nbs-system/naxsi.git + PROTO:=git +endef + +define Prepare/nginx-naxsi + $(eval $(call Download,nginx-naxsi)) + gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) +endef + +define Package/nginx-naxsi/install + $(INSTALL_DIR) $(1)/etc/nginx + $(INSTALL_BIN) $(PKG_BUILD_DIR)/nginx-naxsi/naxsi_config/naxsi_core.rules $(1)/etc/nginx + chmod 0640 $(1)/etc/nginx/naxsi_core.rules +endef + +define Download/nginx-syslog + VERSION:=7abf48e52552c40a21463e1a8c608e0e575261cd + SUBDIR:=nginx-syslog + FILE:=nginx-syslog-module-$(PKG_VERSION)-$$(VERSION).tar.gz + URL:=https://github.com/splitice/nginx_syslog_patch.git + PROTO:=git +endef + +define Prepare/nginx-syslog + $(eval $(call Download,nginx-syslog)) + gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) +endef + +define Package/nginx-proxyprotocol/install + $(INSTALL_DIR) $(1)/etc/nginx + $(INSTALL_BIN) ./files/nginx.proxyprotocol.example $(1)/etc/nginx/nginx.conf.proxyprotocol + chmod 0640 $(1)/etc/nginx/nginx.conf.proxyprotocol +endef + +define Package/nginx-syslog/install + $(INSTALL_DIR) $(1)/etc/nginx + $(INSTALL_BIN) ./files/nginx.syslog.example $(1)/etc/nginx/nginx.conf.syslog + chmod 0640 $(1)/etc/nginx/nginx.conf.syslog +endef + + +$(eval $(call BuildPackage,nginx)) +$(eval $(call BuildPackage,nginx-naxsi)) +$(eval $(call BuildPackage,nginx-proxyprotocol)) +$(eval $(call BuildPackage,nginx-syslog)) + diff --git a/net/nginx/files/nginx.init b/net/nginx/files/nginx.init new file mode 100644 index 0000000000..adf36b4427 --- /dev/null +++ b/net/nginx/files/nginx.init @@ -0,0 +1,24 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2009-2012 OpenWrt.org + +START=50 +NGINX_BIN=/usr/sbin/nginx + +start() { + mkdir -p /var/log/nginx + mkdir -p /var/lib/nginx + $NGINX_BIN +} + +stop() { + $NGINX_BIN -s stop +} + +reload() { + $NGINX_BIN -s reload +} + +shutdown() { + $NGINX_BIN -s quit +} + diff --git a/net/nginx/files/nginx.proxyprotocol.example b/net/nginx/files/nginx.proxyprotocol.example new file mode 100644 index 0000000000..ab4bad6256 --- /dev/null +++ b/net/nginx/files/nginx.proxyprotocol.example @@ -0,0 +1,40 @@ +worker_processes 1; +pid /tmp/nginx.pid; +daemon off; +master_process off; +error_log stderr debug_core; + +events { + debug_connection ; + debug_connection ; + worker_connections 1024; +} + +http { + default_type application/octet-stream; + client_body_temp_path /tmp/body 1; + + access_log /tmp/nginx_access.log; + + server { +# listen 8082 ssl; +# proxy protocol configuration for nginx 1.4.x: + listen 8082 accept_proxy_protocol=on; +# same with spdy enabled: +# listen 8082 spdy ssl accept_proxy_protocol=on; + listen [::]:8082 ipv6only=on; + ssl_certificate /your/certificate; + ssl_certificate_key /your/key; + server_name localhost; +# proxy protocol configuration for nginx 1.2.x: +# accept_proxy_protocol on; + + location / { + proxy_pass http://127.0.0.1:8084; + proxy_set_header X-Real-IP $remote_addr; + proxy_connect_timeout 10s; + proxy_read_timeout 10s; + send_proxy_protocol on; + } + } +} diff --git a/net/nginx/files/nginx.syslog.example b/net/nginx/files/nginx.syslog.example new file mode 100644 index 0000000000..05943448d8 --- /dev/null +++ b/net/nginx/files/nginx.syslog.example @@ -0,0 +1,59 @@ +worker_processes 1; + +syslog local6 nginx; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] $request ' + '"$status" $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + server { + listen 80; + server_name localhost; + + #send the log to syslog and file. + access_log syslog:notice|logs/host1.access.log main; + + # pre 1.5.x + error_log syslog:notice|logs/host1.error.log; + + location / { + root html; + index index.html index.htm; + } + } + + server { + listen 80; + server_name www.example.com; + + access_log syslog:warn|logs/host2.access.log main; + error_log syslog:warn|logs/host2.error.log; + + location / { + root html; + index index.html index.htm; + } + } + + server { + listen 80; + server_name www.test.com; + + #send the log just to syslog. + access_log syslog:error main; + error_log syslog:error; + + location / { + root html; + index index.html index.htm; + } + } +} diff --git a/net/nginx/patches-lua-nginx/300-ldl.patch b/net/nginx/patches-lua-nginx/300-ldl.patch new file mode 100644 index 0000000000..d826bcf261 --- /dev/null +++ b/net/nginx/patches-lua-nginx/300-ldl.patch @@ -0,0 +1,21 @@ +--- a/lua-nginx/config ++++ b/lua-nginx/config +@@ -1,5 +1,5 @@ + ngx_feature="Lua library" +-ngx_feature_libs="-llua -lm" ++ngx_feature_libs="-llua -lm -ldl" + ngx_feature_name= + ngx_feature_run=no + ngx_feature_incs="#include " +@@ -47,9 +47,9 @@ else + ngx_feature="Lua library in $LUA_LIB and $LUA_INC (specified by the LUA_LIB and LUA_INC env)" + ngx_feature_path="$LUA_INC" + if [ $NGX_RPATH = YES ]; then +- ngx_feature_libs="-R$LUA_LIB -L$LUA_LIB -llua -lm" ++ ngx_feature_libs="-R$LUA_LIB -L$LUA_LIB -llua -lm -ldl" + else +- ngx_feature_libs="-L$LUA_LIB -llua -lm" ++ ngx_feature_libs="-L$LUA_LIB -llua -lm -ldl" + fi + + . auto/feature diff --git a/net/nginx/patches-nginx-upstream-check/check_1.2.6+.patch b/net/nginx/patches-nginx-upstream-check/check_1.2.6+.patch new file mode 100644 index 0000000000..3ab913472c --- /dev/null +++ b/net/nginx/patches-nginx-upstream-check/check_1.2.6+.patch @@ -0,0 +1,209 @@ +diff --git a/src/http/modules/ngx_http_upstream_ip_hash_module.c b/src/http/modules/ngx_http_upstream_ip_hash_module.c +index 89ccc2b..a552044 100644 +--- a/src/http/modules/ngx_http_upstream_ip_hash_module.c ++++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c +@@ -9,6 +9,10 @@ + #include + #include + ++#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 + #include + ++#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 + #include + ++#if (NGX_UPSTREAM_CHECK_MODULE) ++#include "ngx_http_upstream_check_handler.h" ++#endif + + static ngx_int_t ngx_http_upstream_cmp_servers(const void *one, + const void *two); +@@ -87,7 +90,17 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, + peers->peer[n].weight = server[i].weight; + peers->peer[n].effective_weight = server[i].weight; + peers->peer[n].current_weight = 0; +- n++; ++ ++#if (NGX_UPSTREAM_CHECK_MODULE) ++ if (!server[i].down) { ++ peers->peer[n].check_index = ++ ngx_http_check_add_peer(cf, us, &server[i].addrs[j]); ++ } ++ else { ++ peers->peer[n].check_index = (ngx_uint_t) NGX_ERROR; ++ } ++#endif ++ n++; + } + } + +@@ -145,6 +158,17 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, + backup->peer[n].max_fails = server[i].max_fails; + backup->peer[n].fail_timeout = server[i].fail_timeout; + backup->peer[n].down = server[i].down; ++ ++#if (NGX_UPSTREAM_CHECK_MODULE) ++ if (!server[i].down) { ++ backup->peer[n].check_index = ++ ngx_http_check_add_peer(cf, us, &server[i].addrs[j]); ++ } ++ else { ++ backup->peer[n].check_index = (ngx_uint_t) NGX_ERROR; ++ } ++#endif ++ + n++; + } + } +@@ -206,6 +230,9 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, + peers->peer[i].current_weight = 0; + peers->peer[i].max_fails = 1; + peers->peer[i].fail_timeout = 10; ++#if (NGX_UPSTREAM_CHECK_MODULE) ++ peers->peer[i].check_index = (ngx_uint_t) NGX_ERROR; ++#endif + } + + us->peer.data = peers; +@@ -323,6 +350,9 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r, + peers->peer[0].current_weight = 0; + peers->peer[0].max_fails = 1; + peers->peer[0].fail_timeout = 10; ++#if (NGX_UPSTREAM_CHECK_MODULE) ++ peers->peer[0].check_index = (ngx_uint_t) NGX_ERROR; ++#endif + + } else { + +@@ -356,6 +386,9 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r, + peers->peer[i].current_weight = 0; + peers->peer[i].max_fails = 1; + peers->peer[i].fail_timeout = 10; ++#if (NGX_UPSTREAM_CHECK_MODULE) ++ peers->peer[i].check_index = (ngx_uint_t) NGX_ERROR; ++#endif + } + } + +@@ -434,6 +467,12 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data) + goto failed; + } + ++#if (NGX_UPSTREAM_CHECK_MODULE) ++ if (ngx_http_check_peer_down(peer->check_index)) { ++ goto failed; ++ } ++#endif ++ + } else { + + /* there are several peers */ +@@ -531,6 +570,12 @@ ngx_http_upstream_get_peer(ngx_http_upstream_rr_peer_data_t *rrp) + continue; + } + ++#if (NGX_UPSTREAM_CHECK_MODULE) ++ if (ngx_http_check_peer_down(peer->check_index)) { ++ continue; ++ } ++#endif ++ + if (peer->max_fails + && peer->fails >= peer->max_fails + && now - peer->checked <= peer->fail_timeout) +diff --git a/src/http/ngx_http_upstream_round_robin.h b/src/http/ngx_http_upstream_round_robin.h +index 3f8cbf8..1613168 100644 +--- a/src/http/ngx_http_upstream_round_robin.h ++++ b/src/http/ngx_http_upstream_round_robin.h +@@ -30,6 +30,10 @@ typedef struct { + ngx_uint_t max_fails; + time_t fail_timeout; + ++#if (NGX_UPSTREAM_CHECK_MODULE) ++ ngx_uint_t check_index; ++#endif ++ + ngx_uint_t down; /* unsigned down:1; */ + + #if (NGX_HTTP_SSL) diff --git a/net/nginx/patches/101-feature_test_fix.patch b/net/nginx/patches/101-feature_test_fix.patch new file mode 100644 index 0000000000..8e15fe96e8 --- /dev/null +++ b/net/nginx/patches/101-feature_test_fix.patch @@ -0,0 +1,107 @@ +--- a/auto/cc/name ++++ b/auto/cc/name +@@ -7,7 +7,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then + + ngx_feature="C compiler" + ngx_feature_name= +- ngx_feature_run=yes ++ ngx_feature_run= + ngx_feature_incs= + ngx_feature_path= + ngx_feature_libs= +--- a/auto/cc/conf ++++ b/auto/cc/conf +@@ -155,7 +155,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then + else + ngx_feature="C99 variadic macros" + ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS" +- ngx_feature_run=yes ++ ngx_feature_run=no + ngx_feature_incs="#include + #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 + #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 " + 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 + #include " + 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 + #include " + 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 " + 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 " + 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 + #include + #include " +@@ -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 + #include " + 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 " + ngx_feature_path= + ngx_feature_libs= diff --git a/net/nginx/patches/102-sizeof_test_fix.patch b/net/nginx/patches/102-sizeof_test_fix.patch new file mode 100644 index 0000000000..0cd93cc4eb --- /dev/null +++ b/net/nginx/patches/102-sizeof_test_fix.patch @@ -0,0 +1,26 @@ +--- a/auto/types/sizeof ++++ b/auto/types/sizeof +@@ -25,8 +25,13 @@ $NGX_INCLUDE_UNISTD_H + $NGX_INCLUDE_INTTYPES_H + $NGX_INCLUDE_AUTO_CONFIG_H + ++char object_code_block[] = { ++ '\n', 'e', '4', 'V', 'A', ++ '0', 'x', ('0' + sizeof($ngx_type)), ++ 'Y', '3', 'p', 'M', '\n' ++}; ++ + int main() { +- printf("%d", (int) sizeof($ngx_type)); + return 0; + } + +@@ -40,7 +45,7 @@ eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>& + + + if [ -x $NGX_AUTOTEST ]; then +- ngx_size=`$NGX_AUTOTEST` ++ ngx_size=`sed -ne 's/^e4VA0x\(.\)Y3pM$/\1/p' < $NGX_AUTOTEST` + echo " $ngx_size bytes" + fi + diff --git a/net/nginx/patches/103-sys_nerr.patch b/net/nginx/patches/103-sys_nerr.patch new file mode 100644 index 0000000000..5f5d106fed --- /dev/null +++ b/net/nginx/patches/103-sys_nerr.patch @@ -0,0 +1,12 @@ +--- a/src/os/unix/ngx_errno.c ++++ b/src/os/unix/ngx_errno.c +@@ -8,6 +8,9 @@ + #include + #include + ++#ifndef NGX_SYS_NERR ++#define NGX_SYS_NERR 128 ++#endif + + /* + * The strerror() messages are copied because: diff --git a/net/nginx/patches/200-config.patch b/net/nginx/patches/200-config.patch new file mode 100644 index 0000000000..f35009576a --- /dev/null +++ b/net/nginx/patches/200-config.patch @@ -0,0 +1,18 @@ +--- a/conf/nginx.conf ++++ b/conf/nginx.conf +@@ -1,5 +1,5 @@ + +-#user nobody; ++user nobody nogroup; + worker_processes 1; + + #error_log logs/error.log; +@@ -16,7 +16,7 @@ events { + + http { + include mime.types; +- default_type application/octet-stream; ++ #default_type application/octet-stream; + + #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + # '$status $body_bytes_sent "$http_referer" ' diff --git a/net/nginx/patches/300-crosscompile_ccflags.patch b/net/nginx/patches/300-crosscompile_ccflags.patch new file mode 100644 index 0000000000..4a06a76969 --- /dev/null +++ b/net/nginx/patches/300-crosscompile_ccflags.patch @@ -0,0 +1,33 @@ +--- a/auto/endianness ++++ b/auto/endianness +@@ -21,7 +21,7 @@ int main() { + + END + +-ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \ ++ngx_test="$CC $NGX_CC_OPT $CC_TEST_FLAGS $CC_AUX_FLAGS \ + -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs" + + eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1" +--- a/auto/feature ++++ b/auto/feature +@@ -39,7 +39,7 @@ int main() { + END + + +-ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS $ngx_feature_inc_path \ ++ngx_test="$CC $NGX_CC_OPT $CC_TEST_FLAGS $CC_AUX_FLAGS $ngx_feature_inc_path \ + -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_TEST_LD_OPT $ngx_feature_libs" + + ngx_feature_inc_path= +--- a/auto/include ++++ b/auto/include +@@ -27,7 +27,7 @@ int main() { + END + + +-ngx_test="$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c" ++ngx_test="$CC $NGX_CC_OPT -o $NGX_AUTOTEST $NGX_AUTOTEST.c" + + eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1" + diff --git a/net/nginx/patches/400-nginx-1.4.x_proxy_protocol_patch_v2.patch b/net/nginx/patches/400-nginx-1.4.x_proxy_protocol_patch_v2.patch new file mode 100644 index 0000000000..52c1ce7ff9 --- /dev/null +++ b/net/nginx/patches/400-nginx-1.4.x_proxy_protocol_patch_v2.patch @@ -0,0 +1,1194 @@ +Index: nginx-1.4.7/auto/modules +=================================================================== +--- nginx-1.4.7.orig/auto/modules ++++ nginx-1.4.7/auto/modules +@@ -297,6 +297,10 @@ if [ $HTTP_SSL = YES ]; then + HTTP_SRCS="$HTTP_SRCS $HTTP_SSL_SRCS" + fi + ++if [ $PROXY_PROTOCOL = YES ]; then ++ have=NGX_PROXY_PROTOCOL . auto/have ++fi ++ + if [ $HTTP_PROXY = YES ]; then + have=NGX_HTTP_X_FORWARDED_FOR . auto/have + #USE_MD5=YES +Index: nginx-1.4.7/auto/options +=================================================================== +--- nginx-1.4.7.orig/auto/options ++++ nginx-1.4.7/auto/options +@@ -47,6 +47,8 @@ USE_THREADS=NO + NGX_FILE_AIO=NO + NGX_IPV6=NO + ++PROXY_PROTOCOL=NO ++ + HTTP=YES + + NGX_HTTP_LOG_PATH= +@@ -192,6 +194,8 @@ do + --with-file-aio) NGX_FILE_AIO=YES ;; + --with-ipv6) NGX_IPV6=YES ;; + ++ --with-proxy-protocol) PROXY_PROTOCOL=YES ;; ++ + --without-http) HTTP=NO ;; + --without-http-cache) HTTP_CACHE=NO ;; + +@@ -350,6 +354,8 @@ cat << END + --with-file-aio enable file AIO support + --with-ipv6 enable IPv6 support + ++ --with-proxy-protocol enable proxy protocol support ++ + --with-http_ssl_module enable ngx_http_ssl_module + --with-http_spdy_module enable ngx_http_spdy_module + --with-http_realip_module enable ngx_http_realip_module +Index: nginx-1.4.7/auto/sources +=================================================================== +--- nginx-1.4.7.orig/auto/sources ++++ nginx-1.4.7/auto/sources +@@ -36,7 +36,8 @@ CORE_DEPS="src/core/nginx.h \ + src/core/ngx_conf_file.h \ + src/core/ngx_resolver.h \ + src/core/ngx_open_file_cache.h \ +- src/core/ngx_crypt.h" ++ src/core/ngx_crypt.h \ ++ src/core/ngx_proxy_protocol.h" + + + CORE_SRCS="src/core/nginx.c \ +@@ -67,7 +68,8 @@ CORE_SRCS="src/core/nginx.c \ + src/core/ngx_conf_file.c \ + src/core/ngx_resolver.c \ + src/core/ngx_open_file_cache.c \ +- src/core/ngx_crypt.c" ++ src/core/ngx_crypt.c \ ++ src/core/ngx_proxy_protocol.c" + + + REGEX_MODULE=ngx_regex_module +Index: nginx-1.4.7/src/core/ngx_connection.h +=================================================================== +--- nginx-1.4.7.orig/src/core/ngx_connection.h ++++ nginx-1.4.7/src/core/ngx_connection.h +@@ -63,6 +63,10 @@ struct ngx_listening_s { + unsigned shared:1; /* shared between threads or processes */ + unsigned addr_ntop:1; + ++#if (NGX_PROXY_PROTOCOL) ++ unsigned accept_proxy_protocol:2; /* proxy_protocol flag */ ++#endif ++ + #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) + unsigned ipv6only:1; + #endif +@@ -148,6 +152,10 @@ struct ngx_connection_s { + + ngx_uint_t requests; + ++#if (NGX_PROXY_PROTOCOL) ++ ngx_uint_t proxy_protocol; ++#endif ++ + unsigned buffered:8; + + unsigned log_error:3; /* ngx_connection_log_error_e */ +Index: nginx-1.4.7/src/core/ngx_core.h +=================================================================== +--- nginx-1.4.7.orig/src/core/ngx_core.h ++++ nginx-1.4.7/src/core/ngx_core.h +@@ -77,6 +77,9 @@ typedef void (*ngx_connection_handler_pt + #include + #include + #include ++#if (NGX_PROXY_PROTOCOL) ++#include ++#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 ++#include ++#include ++ ++#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 ++#include ++ ++ ++#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 + #include + #include +- ++#if (NGX_PROXY_PROTOCOL) ++#include ++#endif + + typedef struct ngx_http_proxy_rewrite_s ngx_http_proxy_rewrite_t; + +@@ -365,6 +367,17 @@ static ngx_command_t ngx_http_proxy_com + offsetof(ngx_http_proxy_loc_conf_t, upstream.busy_buffers_size_conf), + NULL }, + ++#if (NGX_PROXY_PROTOCOL) ++ ++ { ngx_string("send_proxy_protocol"), ++ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, ++ ngx_conf_set_flag_slot, ++ NGX_HTTP_LOC_CONF_OFFSET, ++ offsetof(ngx_http_proxy_loc_conf_t, upstream.send_proxy_protocol), ++ NULL }, ++ ++#endif ++ + #if (NGX_HTTP_CACHE) + + { ngx_string("proxy_cache"), +@@ -2420,6 +2433,11 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ + conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; + + conf->upstream.intercept_errors = NGX_CONF_UNSET; ++ ++#if (NGX_PROXY_PROTOCOL) ++ conf->upstream.send_proxy_protocol = NGX_CONF_UNSET; ++#endif ++ + #if (NGX_HTTP_SSL) + conf->upstream.ssl_session_reuse = NGX_CONF_UNSET; + #endif +@@ -2695,6 +2713,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t + ngx_conf_merge_value(conf->upstream.intercept_errors, + prev->upstream.intercept_errors, 0); + ++#if (NGX_PROXY_PROTOCOL) ++ ngx_conf_merge_value(conf->upstream.send_proxy_protocol, ++ prev->upstream.send_proxy_protocol, 0); ++#endif ++ + #if (NGX_HTTP_SSL) + ngx_conf_merge_value(conf->upstream.ssl_session_reuse, + prev->upstream.ssl_session_reuse, 1); +Index: nginx-1.4.7/src/http/ngx_http.c +=================================================================== +--- nginx-1.4.7.orig/src/http/ngx_http.c ++++ nginx-1.4.7/src/http/ngx_http.c +@@ -1228,6 +1228,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, n + #if (NGX_HTTP_SPDY) + ngx_uint_t spdy; + #endif ++#if (NGX_PROXY_PROTOCOL) ++ ngx_uint_t accept_proxy_protocol; ++#endif + + /* + * we cannot compare whole sockaddr struct's as kernel +@@ -1283,6 +1286,10 @@ ngx_http_add_addresses(ngx_conf_t *cf, n + #if (NGX_HTTP_SPDY) + spdy = lsopt->spdy || addr[i].opt.spdy; + #endif ++#if (NGX_PROXY_PROTOCOL) ++ accept_proxy_protocol = lsopt->accept_proxy_protocol ++ || addr[i].opt.accept_proxy_protocol; ++#endif + + if (lsopt->set) { + +@@ -1316,6 +1323,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, n + #if (NGX_HTTP_SPDY) + addr[i].opt.spdy = spdy; + #endif ++#if (NGX_PROXY_PROTOCOL) ++ addr[i].opt.accept_proxy_protocol = accept_proxy_protocol; ++#endif + + return NGX_OK; + } +@@ -1762,6 +1772,11 @@ ngx_http_add_listening(ngx_conf_t *cf, n + ls->pool_size = cscf->connection_pool_size; + ls->post_accept_timeout = cscf->client_header_timeout; + ++#if (NGX_PROXY_PROTOCOL) ++// CLEANUP: ls->accept_proxy_protocol = cscf->accept_proxy_protocol; ++ ls->accept_proxy_protocol = addr->opt.accept_proxy_protocol; ++#endif ++ + clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index]; + + ls->logp = clcf->error_log; +@@ -1840,6 +1855,9 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_h + #if (NGX_HTTP_SPDY) + addrs[i].conf.spdy = addr[i].opt.spdy; + #endif ++#if (NGX_PROXY_PROTOCOL) ++ addrs[i].conf.accept_proxy_protocol = addr[i].opt.accept_proxy_protocol; ++#endif + + if (addr[i].hash.buckets == NULL + && (addr[i].wc_head == NULL +@@ -1904,6 +1922,9 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_ + #if (NGX_HTTP_SPDY) + addrs6[i].conf.spdy = addr[i].opt.spdy; + #endif ++#if (NGX_PROXY_PROTOCOL) ++ addrs6[i].conf.accept_proxy_protocol = addr[i].opt.accept_proxy_protocol; ++#endif + + if (addr[i].hash.buckets == NULL + && (addr[i].wc_head == NULL +Index: nginx-1.4.7/src/http/ngx_http_core_module.c +=================================================================== +--- nginx-1.4.7.orig/src/http/ngx_http_core_module.c ++++ nginx-1.4.7/src/http/ngx_http_core_module.c +@@ -4090,6 +4090,15 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx + continue; + } + ++#if (NGX_PROXY_PROTOCOL) ++ if (ngx_strncmp(value[n].data, "accept_proxy_protocol=on", 24) == 0) { ++ lsopt.accept_proxy_protocol = 1; ++ lsopt.set = 1; ++ lsopt.bind = 1; ++ continue; ++ } ++#endif ++ + if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) { + #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) + struct sockaddr *sa; +Index: nginx-1.4.7/src/http/ngx_http_core_module.h +=================================================================== +--- nginx-1.4.7.orig/src/http/ngx_http_core_module.h ++++ nginx-1.4.7/src/http/ngx_http_core_module.h +@@ -78,6 +78,11 @@ typedef struct { + #if (NGX_HTTP_SPDY) + unsigned spdy:1; + #endif ++ ++#if (NGX_PROXY_PROTOCOL) ++ unsigned accept_proxy_protocol:2; ++#endif ++ + #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) + unsigned ipv6only:1; + #endif +@@ -234,6 +239,10 @@ struct ngx_http_addr_conf_s { + + ngx_http_virtual_names_t *virtual_names; + ++#if (NGX_PROXY_PROTOCOL) ++ ngx_flag_t accept_proxy_protocol; ++#endif ++ + #if (NGX_HTTP_SSL) + unsigned ssl:1; + #endif +Index: nginx-1.4.7/src/http/ngx_http_request.c +=================================================================== +--- nginx-1.4.7.orig/src/http/ngx_http_request.c ++++ nginx-1.4.7/src/http/ngx_http_request.c +@@ -63,6 +63,9 @@ static void ngx_http_ssl_handshake(ngx_e + static void ngx_http_ssl_handshake_handler(ngx_connection_t *c); + #endif + ++#if (NGX_PROXY_PROTOCOL) ++static void ngx_http_proxy_protocol(ngx_event_t *rev); ++#endif + + static char *ngx_http_client_errors[] = { + +@@ -343,6 +346,14 @@ ngx_http_init_connection(ngx_connection_ + } + #endif + ++#if (NGX_PROXY_PROTOCOL) ++ { ++ if (hc->addr_conf->accept_proxy_protocol) { ++ rev->handler = ngx_http_proxy_protocol; ++ } ++ } ++#endif ++ + if (rev->ready) { + /* the deferred accept(), rtsig, aio, iocp */ + +@@ -364,7 +375,6 @@ ngx_http_init_connection(ngx_connection_ + } + } + +- + static void + ngx_http_wait_request_handler(ngx_event_t *rev) + { +@@ -469,6 +479,12 @@ ngx_http_wait_request_handler(ngx_event_ + } + + rev->handler = ngx_http_process_request_line; ++ ++#if (NGX_PROXY_PROTOCOL) ++ if (hc->addr_conf->accept_proxy_protocol) ++ rev->handler = ngx_http_proxy_protocol; ++#endif ++ + ngx_http_process_request_line(rev); + } + +@@ -582,6 +598,67 @@ ngx_http_create_request(ngx_connection_t + return r; + } + ++#if (NGX_PROXY_PROTOCOL) ++ ++static void ++ngx_http_proxy_protocol(ngx_event_t *rev) ++{ ++ ssize_t n; ++ size_t size = 1024; ++ u_char tmpbuf[size]; ++ ngx_connection_t *c; ++ ngx_http_connection_t *hc; ++ ++ c = rev->data; ++ hc = c->data; ++ rev->handler = ngx_http_wait_request_handler; ++ ++#if (NGX_HTTP_SPDY) ++ { ++ if (hc->addr_conf->spdy) { ++ rev->handler = ngx_http_spdy_init; ++ } ++ } ++#endif ++ ++#if (NGX_HTTP_SSL) ++ { ++ if (hc->addr_conf->ssl) { ++ rev->handler = ngx_http_ssl_handshake; ++ } ++ } ++#endif ++ ++ n = recv(c->fd, tmpbuf, size, MSG_PEEK); ++ ++ if ((n <= 0) && (c->listening) ++ && (hc->addr_conf->accept_proxy_protocol) ++ && (!c->proxy_protocol)) { ++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required but not found"); ++ return; ++ } ++ if ((n > 0) && (c->listening) ++ && (hc->addr_conf->accept_proxy_protocol) ++ && (!c->proxy_protocol)) { ++ ssize_t m; ++ if (!(m = ngx_recv_proxy_protocol(c, tmpbuf, n))) { ++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required but not found"); ++ ngx_http_close_connection(c); ++ return; ++ } ++ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required and found"); ++ ++ c->proxy_protocol = 1; ++ ++ /* strip the proxy protocol string from the buffer */ ++ recv(c->fd, tmpbuf, m, 0); ++ } ++ ++ rev->handler(rev); ++} ++ ++#endif ++ + + #if (NGX_HTTP_SSL) + +@@ -1291,6 +1368,10 @@ ngx_http_read_request_header(ngx_http_re + c = r->connection; + rev = c->read; + ++fprintf(stderr, "DEBUG: pos: %p, last: %p, start: %p, end: %p\n", ++ r->header_in->pos, r->header_in->last, r->header_in->start, ++ r->header_in->end); ++ + n = r->header_in->last - r->header_in->pos; + + if (n > 0) { +Index: nginx-1.4.7/src/http/ngx_http_upstream.c +=================================================================== +--- nginx-1.4.7.orig/src/http/ngx_http_upstream.c ++++ nginx-1.4.7/src/http/ngx_http_upstream.c +@@ -31,6 +31,10 @@ static ngx_int_t ngx_http_upstream_reini + ngx_http_upstream_t *u); + static void ngx_http_upstream_send_request(ngx_http_request_t *r, + ngx_http_upstream_t *u); ++#if (NGX_PROXY_PROTOCOL) ++static void ngx_http_upstream_send_proxy_protocol(ngx_http_request_t *r, ++ ngx_http_upstream_t *u); ++#endif + static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r, + ngx_http_upstream_t *u); + static void ngx_http_upstream_process_header(ngx_http_request_t *r, +@@ -1255,6 +1259,13 @@ ngx_http_upstream_connect(ngx_http_reque + + u->request_sent = 0; + ++#if (NGX_PROXY_PROTOCOL) ++ if (u->conf->send_proxy_protocol && !(u->ssl && c->ssl == NULL)) { ++ ngx_http_upstream_send_proxy_protocol(r, u); ++ return; ++ } ++#endif ++ + if (rc == NGX_AGAIN) { + ngx_add_timer(c->write, u->conf->connect_timeout); + return; +@@ -1498,6 +1509,228 @@ ngx_http_upstream_send_request(ngx_http_ + } + + ++#if (NGX_PROXY_PROTOCOL) ++ ++static void ++ngx_http_upstream_send_proxy_protocol(ngx_http_request_t *r, ngx_http_upstream_t *u) ++{ ++ size_t len; ++ ngx_int_t rc; ++ ngx_connection_t *uc; ++ ngx_connection_t *cc; ++ ngx_chain_t *pp_string; ++ ngx_proxy_protocol_t pp; ++ ngx_buf_t *b; ++ char port[6]; ++ u_char *addr; ++ struct sockaddr_storage sa_src; ++ struct sockaddr_storage sa_dst; ++ socklen_t addrlen = NGX_SOCKADDRLEN; ++ struct sockaddr_in *sin_src; ++ struct sockaddr_in *sin_dst; ++ ++#if (NGX_HAVE_INET6) ++ ++ struct sockaddr_in6 *sin6_src; ++ struct sockaddr_in6 *sin6_dst; ++ ++#endif ++ ++ ++ uc = u->peer.connection; ++ cc = r->connection; ++ ++ if ( !(u->conf->send_proxy_protocol) ) { ++ return; ++ } ++ ++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0, ++ "http upstream send proxy protocol"); ++ ++ if (!u->request_sent && ngx_http_upstream_test_connect(uc) != NGX_OK) { ++ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); ++ return; ++ } ++ ++ uc->log->action = "sending proxy protocol to upstream"; ++ ++ len = 0; ++ ++ if (r->connection->proxy_protocol) { ++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0, ++ "PP: got proxy-protocol from client connection"); ++ ++ switch (cc->sockaddr->sa_family) { ++ ++#if (NGX_HAVE_INET6) ++ ++ case AF_INET6: ++ ++ pp.pp_proto = NGX_PP_PROTO_TCP6; ++ sin6_dst = (struct sockaddr_in6 *) cc->local_sockaddr; ++ sin6_src = (struct sockaddr_in6 *) cc->sockaddr; ++ ++ break; ++ ++#endif ++ ++ default: ++ pp.pp_proto = NGX_PP_PROTO_TCP4; ++ sin_dst = (struct sockaddr_in *) cc->local_sockaddr; ++ sin_src = (struct sockaddr_in *) cc->sockaddr; ++ ++ } ++ ++ } else { ++ ++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0, ++ "PP: collecting information from socket fd"); ++ ++ getsockname(cc->fd, (struct sockaddr *) &sa_dst, &addrlen); ++ ++ switch (sa_dst.ss_family) { ++ ++#if (NGX_HAVE_INET6) ++ ++ case AF_INET6: ++ ++ pp.pp_proto = NGX_PP_PROTO_TCP6; ++ sin6_dst = (struct sockaddr_in6 *) &sa_dst; ++ ++ getpeername(cc->fd, (struct sockaddr *) &sa_src, &addrlen); ++ sin6_src = (struct sockaddr_in6 *) &sa_src; ++ ++ break; ++ ++#endif ++ ++ default: ++ ++ pp.pp_proto = NGX_PP_PROTO_TCP4; ++ sin_dst = (struct sockaddr_in *) &sa_dst; ++ getpeername(cc->fd, (struct sockaddr *) &sa_src, &addrlen); ++ sin_src = (struct sockaddr_in *) &sa_src; ++ } ++ ++ ++ } ++ ++ switch (pp.pp_proto) { ++ ++#if (NGX_HAVE_INET6) ++ ++ case NGX_PP_PROTO_TCP6: ++ ++ /* dst3 and dst4 */ ++ addr = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN); ++ ngx_inet_ntop(AF_INET6, &sin6_dst->sin6_addr, addr, NGX_INET6_ADDRSTRLEN); ++ pp.pp_dst3_text.data = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN); ++ pp.pp_dst3_text.len = ngx_strlen(addr); ++ ngx_memcpy(pp.pp_dst3_text.data, addr, pp.pp_dst3_text.len); ++ pp.pp_dst4 = htons(sin6_dst->sin6_port); ++ ++ ngx_memzero(addr, NGX_INET6_ADDRSTRLEN); ++ ++ /* src3 and src4 */ ++ ngx_inet_ntop(AF_INET6, &sin6_src->sin6_addr, addr, NGX_INET6_ADDRSTRLEN); ++ pp.pp_src3_text.data = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN); ++ pp.pp_src3_text.len = ngx_strlen(addr); ++ ngx_memcpy(pp.pp_src3_text.data, addr, pp.pp_src3_text.len); ++ pp.pp_src4 = htons(sin6_src->sin6_port); ++ ++ break; ++ ++#endif ++ ++ default: ++ ++ /* dst3 and dst4 */ ++ addr = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN); ++ ngx_inet_ntop(AF_INET, &sin_dst->sin_addr, addr, NGX_INET_ADDRSTRLEN); ++ pp.pp_dst3_text.data = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN); ++ pp.pp_dst3_text.len = ngx_strlen(addr); ++ ngx_memcpy(pp.pp_dst3_text.data, addr, pp.pp_dst3_text.len); ++ pp.pp_dst4 = htons(sin_dst->sin_port); ++ ++ ngx_memzero(addr, NGX_INET_ADDRSTRLEN); ++ ++ /* src3 and src4 */ ++ ngx_inet_ntop(AF_INET, &sin_src->sin_addr, addr, NGX_INET_ADDRSTRLEN); ++ pp.pp_src3_text.data = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN); ++ pp.pp_src3_text.len = ngx_strlen(addr); ++ ngx_memcpy(pp.pp_src3_text.data, addr, pp.pp_src3_text.len); ++ pp.pp_src4 = htons(sin_src->sin_port); ++ ++ } ++ ++ len += ngx_proxy_protocol_string_length(&pp); ++ ++ ngx_print_proxy_protocol(&pp, uc->log); ++ ++ b = ngx_create_temp_buf(uc->pool, len); ++ if (b == NULL) { ++ return; ++ } ++ ++ pp_string = ngx_alloc_chain_link(uc->pool); ++ if (pp_string == NULL) { ++ return; ++ } ++ ++ pp_string->buf = b; ++ pp_string->next = NULL; ++ ++ b->last = ngx_cpymem(b->last, "PROXY ", sizeof("PROXY ") - 1); ++ ++ switch (pp.pp_proto) { ++ case NGX_PP_PROTO_TCP4: ++ b->last = ngx_cpymem(b->last, "TCP4 ", sizeof("TCP4 ") - 1); ++ break; ++ case NGX_PP_PROTO_TCP6: ++ b->last = ngx_cpymem(b->last, "TCP6 ", sizeof("TCP6 ") - 1); ++ break; ++ } ++ ++ /* src3 */ ++ b->last = ngx_cpymem(b->last, pp.pp_src3_text.data, pp.pp_src3_text.len); ++ b->last = ngx_cpymem(b->last, " ", 1); ++ ++ /* dst3 */ ++ b->last = ngx_cpymem(b->last, pp.pp_dst3_text.data, pp.pp_dst3_text.len); ++ b->last = ngx_cpymem(b->last, " ", 1); ++ ++ /* src4 */ ++ ngx_memzero(port, 6); ++ sprintf(port,"%d", pp.pp_src4); ++ b->last = ngx_cpymem(b->last, port, strlen(port)); ++ b->last = ngx_cpymem(b->last, " ", 1); ++ ++ /* dst4 */ ++ ngx_memzero(port, 6); ++ sprintf(port,"%d", pp.pp_dst4); ++ b->last = ngx_cpymem(b->last, port, strlen(port)); ++ ++ /* CRLF */ ++ b->last = ngx_cpymem(b->last, CRLF, sizeof(CRLF) - 1); ++ ++ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, uc->log, 0, ++ "http upstream send proxy protocol: %d -%*s-", ++ ngx_proxy_protocol_string_length(&pp), ++ ngx_proxy_protocol_string_length(&pp) - 2, ++ b->start); ++ ++ rc = ngx_output_chain(&u->output, pp_string); ++ ++ if (rc == NGX_ERROR) { ++ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); ++ return; ++ } ++ ++} ++ ++#endif ++ ++ + static void + ngx_http_upstream_send_request_handler(ngx_http_request_t *r, + ngx_http_upstream_t *u) +Index: nginx-1.4.7/src/http/ngx_http_upstream.h +=================================================================== +--- nginx-1.4.7.orig/src/http/ngx_http_upstream.h ++++ nginx-1.4.7/src/http/ngx_http_upstream.h +@@ -188,6 +188,10 @@ typedef struct { + unsigned intercept_404:1; + unsigned change_buffering:1; + ++#if (NGX_PROXY_PROTOCOL) ++ ngx_flag_t send_proxy_protocol; ++#endif ++ + #if (NGX_HTTP_SSL) + ngx_ssl_t *ssl; + ngx_flag_t ssl_session_reuse; +Index: nginx-1.4.7/auto/cc/gcc +=================================================================== +--- nginx-1.4.7.orig/auto/cc/gcc ++++ nginx-1.4.7/auto/cc/gcc +@@ -168,7 +168,7 @@ esac + + + # stop on warning +-CFLAGS="$CFLAGS -Werror" ++CFLAGS="$CFLAGS" + + # debug + CFLAGS="$CFLAGS -g" +Index: nginx-1.4.7/auto/cc/icc +=================================================================== +--- nginx-1.4.7.orig/auto/cc/icc ++++ nginx-1.4.7/auto/cc/icc +@@ -115,7 +115,7 @@ case "$NGX_ICC_VER" in + esac + + # stop on warning +-CFLAGS="$CFLAGS -Werror" ++CFLAGS="$CFLAGS " + + # debug + CFLAGS="$CFLAGS -g" diff --git a/net/nginx/patches/401-nginx-1.4.0-syslog.patch b/net/nginx/patches/401-nginx-1.4.0-syslog.patch new file mode 100644 index 0000000000..941c79aee8 --- /dev/null +++ b/net/nginx/patches/401-nginx-1.4.0-syslog.patch @@ -0,0 +1,698 @@ +Index: nginx-1.4.7/src/core/ngx_cycle.c +=================================================================== +--- nginx-1.4.7.orig/src/core/ngx_cycle.c ++++ nginx-1.4.7/src/core/ngx_cycle.c +@@ -85,6 +85,12 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) + cycle->pool = pool; + cycle->log = log; + cycle->new_log.log_level = NGX_LOG_ERR; ++#if (NGX_ENABLE_SYSLOG) ++ cycle->new_log.facility = SYSLOG_FACILITY; ++ cycle->new_log.facility = ERR_SYSLOG_PRIORITY; ++ cycle->new_log.syslog_on = 0; ++ cycle->new_log.syslog_set = 0; ++#endif + cycle->old_cycle = old_cycle; + + cycle->conf_prefix.len = old_cycle->conf_prefix.len; +Index: nginx-1.4.7/src/core/ngx_log.c +=================================================================== +--- nginx-1.4.7.orig/src/core/ngx_log.c ++++ nginx-1.4.7/src/core/ngx_log.c +@@ -10,6 +10,15 @@ + + + static char *ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); ++#if (NGX_ENABLE_SYSLOG) ++static char *ngx_set_syslog(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); ++void log_exit(ngx_cycle_t *cycle); ++ ++typedef struct{ ++ ngx_str_t name; ++ ngx_int_t macro; ++} ngx_string_to_macro_t; ++#endif + + + static ngx_command_t ngx_errlog_commands[] = { +@@ -21,6 +30,15 @@ static ngx_command_t ngx_errlog_command + 0, + NULL}, + ++#if (NGX_ENABLE_SYSLOG) ++ {ngx_string("syslog"), ++ NGX_MAIN_CONF|NGX_CONF_TAKE12, ++ ngx_set_syslog, ++ 0, ++ 0, ++ NULL}, ++#endif ++ + ngx_null_command + }; + +@@ -43,7 +61,11 @@ ngx_module_t ngx_errlog_module = { + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ +- NULL, /* exit master */ ++#if (NGX_ENABLE_SYSLOG) ++ log_exit, /* exit master */ ++#else ++ NULL, ++#endif + NGX_MODULE_V1_PADDING + }; + +@@ -52,6 +74,48 @@ static ngx_log_t ngx_log; + static ngx_open_file_t ngx_log_file; + ngx_uint_t ngx_use_stderr = 1; + ++#if (NGX_ENABLE_SYSLOG) ++static ngx_string_to_macro_t ngx_syslog_facilities[] = { ++ {ngx_string("auth"), LOG_AUTH}, ++#if !(NGX_SOLARIS) ++ {ngx_string("authpriv"), LOG_AUTHPRIV}, ++#endif ++ {ngx_string("cron"), LOG_CRON}, ++ {ngx_string("daemon"), LOG_DAEMON}, ++#if !(NGX_SOLARIS) ++ {ngx_string("ftp"), LOG_FTP}, ++#endif ++ {ngx_string("kern"), LOG_KERN}, ++ {ngx_string("local0"), LOG_LOCAL0}, ++ {ngx_string("local1"), LOG_LOCAL1}, ++ {ngx_string("local2"), LOG_LOCAL2}, ++ {ngx_string("local3"), LOG_LOCAL3}, ++ {ngx_string("local4"), LOG_LOCAL4}, ++ {ngx_string("local5"), LOG_LOCAL5}, ++ {ngx_string("local6"), LOG_LOCAL6}, ++ {ngx_string("local7"), LOG_LOCAL7}, ++ {ngx_string("lpr"), LOG_LPR}, ++ {ngx_string("mail"), LOG_MAIL}, ++ {ngx_string("news"), LOG_NEWS}, ++ {ngx_string("syslog"), LOG_SYSLOG}, ++ {ngx_string("user"), LOG_USER}, ++ {ngx_string("uucp"), LOG_UUCP}, ++ { ngx_null_string, 0} ++}; ++ ++static ngx_string_to_macro_t ngx_syslog_priorities[] = { ++ {ngx_string("emerg"), LOG_EMERG}, ++ {ngx_string("alert"), LOG_ALERT}, ++ {ngx_string("crit"), LOG_CRIT}, ++ {ngx_string("error"), LOG_ERR}, ++ {ngx_string("err"), LOG_ERR}, ++ {ngx_string("warn"), LOG_WARNING}, ++ {ngx_string("notice"),LOG_NOTICE}, ++ {ngx_string("info"), LOG_INFO}, ++ {ngx_string("debug"), LOG_DEBUG}, ++ { ngx_null_string, 0} ++}; ++#endif + + static ngx_str_t err_levels[] = { + ngx_null_string, +@@ -89,11 +153,16 @@ ngx_log_error_core(ngx_uint_t level, ngx + va_list args; + #endif + u_char *p, *last, *msg; ++#if (NGX_ENABLE_SYSLOG) ++ u_char *errstr_syslog; ++#endif + u_char errstr[NGX_MAX_ERROR_STR]; + ++#if !(NGX_ENABLE_SYSLOG) + if (log->file->fd == NGX_INVALID_FILE) { + return; + } ++#endif + + last = errstr + NGX_MAX_ERROR_STR; + +@@ -102,6 +171,10 @@ ngx_log_error_core(ngx_uint_t level, ngx + + p = errstr + ngx_cached_err_log_time.len; + ++#if (NGX_ENABLE_SYSLOG) ++ errstr_syslog = p; ++#endif ++ + p = ngx_slprintf(p, last, " [%V] ", &err_levels[level]); + + /* pid#tid */ +@@ -140,11 +213,27 @@ ngx_log_error_core(ngx_uint_t level, ngx + + ngx_linefeed(p); + ++#if (NGX_ENABLE_SYSLOG) ++ if (log->file != NULL && log->file->name.len != 0) { + (void) ngx_write_fd(log->file->fd, errstr, p - errstr); ++ } ++ ++ /* Don't send the debug level info to syslog */ ++ if (log->syslog_on && level < NGX_LOG_DEBUG) { ++ /* write to syslog */ ++ syslog(log->priority, "%.*s", (int)(p - errstr_syslog), errstr_syslog); ++ } ++#else ++ (void) ngx_write_fd(log->file->fd, errstr, p - errstr); ++#endif + + if (!ngx_use_stderr + || level > NGX_LOG_WARN ++#if (NGX_ENABLE_SYSLOG) ++ || (log->file != NULL && log->file->fd == ngx_stderr)) ++#else + || log->file->fd == ngx_stderr) ++#endif + { + return; + } +@@ -367,6 +456,50 @@ ngx_log_create(ngx_cycle_t *cycle, ngx_s + } + + ++#if (NGX_ENABLE_SYSLOG) ++ngx_int_t ++ngx_log_get_priority(ngx_conf_t *cf, ngx_str_t *priority) ++{ ++ ngx_int_t p = 0; ++ ngx_uint_t n, match = 0; ++ ++ for (n = 0; ngx_syslog_priorities[n].name.len != 0; n++) { ++ if (ngx_strncmp(priority->data, ngx_syslog_priorities[n].name.data, ++ ngx_syslog_priorities[n].name.len) == 0) { ++ p = ngx_syslog_priorities[n].macro; ++ match = 1; ++ } ++ } ++ ++ if (!match) { ++ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, ++ "invalid syslog priority \"%V\"", priority); ++ return -1; ++ } ++ ++ return p; ++} ++ ++ ++char * ++ngx_log_set_priority(ngx_conf_t *cf, ngx_str_t *priority, ngx_log_t *log) ++{ ++ log->priority = ERR_SYSLOG_PRIORITY; ++ ++ if (priority->len == 0) { ++ return NGX_CONF_OK; ++ } ++ ++ log->priority = ngx_log_get_priority(cf, priority); ++ if (log->priority == (-1)) { ++ return NGX_CONF_ERROR; ++ } ++ ++ return NGX_CONF_OK; ++} ++#endif ++ ++ + char * + ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log) + { +@@ -429,6 +562,13 @@ static char * + ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) + { + ngx_str_t *value, name; ++#if (NGX_ENABLE_SYSLOG) ++ u_char *off = NULL; ++ ngx_str_t priority; ++ ++ ngx_str_null(&name); ++ ngx_str_null(&priority); ++#endif + + if (cf->cycle->new_log.file) { + return "is duplicate"; +@@ -436,7 +576,44 @@ ngx_error_log(ngx_conf_t *cf, ngx_comman + + value = cf->args->elts; + ++#if (NGX_ENABLE_SYSLOG) ++ if (ngx_strncmp(value[1].data, "syslog", sizeof("syslog") - 1) == 0) { ++ if (!cf->cycle->new_log.syslog_set) { ++ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, ++ "You must set the syslog directive and enable it first."); ++ return NGX_CONF_ERROR; ++ } ++ ++ cf->cycle->new_log.syslog_on = 1; ++ ++ if (value[1].data[sizeof("syslog") - 1] == ':') { ++ priority.len = value[1].len - sizeof("syslog"); ++ priority.data = value[1].data + sizeof("syslog"); ++ ++ off = (u_char *)ngx_strchr(priority.data, (int) '|'); ++ if (off != NULL) { ++ priority.len = off - priority.data; ++ ++ off++; ++ name.len = value[1].data + value[1].len - off; ++ name.data = off; ++ } ++ } ++ else { ++ if (value[1].len > sizeof("syslog")) { ++ name.len = value[1].len - sizeof("syslog"); ++ name.data = value[1].data + sizeof("syslog"); ++ } ++ } ++ ++ if (ngx_log_set_priority(cf, &priority, &cf->cycle->new_log) == NGX_CONF_ERROR) { ++ return NGX_CONF_ERROR; ++ } ++ } ++ else if (ngx_strcmp(value[1].data, "stderr") == 0) { ++#else + if (ngx_strcmp(value[1].data, "stderr") == 0) { ++#endif + ngx_str_null(&name); + + } else { +@@ -457,3 +634,63 @@ ngx_error_log(ngx_conf_t *cf, ngx_comman + + return ngx_log_set_levels(cf, &cf->cycle->new_log); + } ++ ++ ++#if (NGX_ENABLE_SYSLOG) ++ ++#define SYSLOG_IDENT_NAME "nginx" ++ ++static char * ++ngx_set_syslog(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ++{ ++ char *program; ++ ngx_str_t *value; ++ ngx_int_t facility, match = 0; ++ ngx_uint_t n; ++ ++ value = cf->args->elts; ++ ++ if (cf->cycle->new_log.syslog_set) { ++ return "is duplicate"; ++ } ++ ++ cf->cycle->new_log.syslog_set = 1; ++ ++ for (n = 0; ngx_syslog_facilities[n].name.len != 0; n++) { ++ if (ngx_strncmp(value[1].data, ngx_syslog_facilities[n].name.data, ++ ngx_syslog_facilities[n].name.len) == 0) { ++ facility = ngx_syslog_facilities[n].macro; ++ match = 1; ++ break; ++ } ++ } ++ ++ if (match) { ++ cf->cycle->new_log.facility = facility; ++ cf->cycle->new_log.priority = ERR_SYSLOG_PRIORITY; ++ } ++ else { ++ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, ++ "invalid syslog facility \"%V\"", &value[1]); ++ return NGX_CONF_ERROR; ++ } ++ ++ program = SYSLOG_IDENT_NAME; ++ if (cf->args->nelts > 2) { ++ program = (char *) value[2].data; ++ } ++ ++ openlog(program, LOG_ODELAY, facility); ++ ++ return NGX_CONF_OK; ++} ++ ++ ++void log_exit(ngx_cycle_t *cycle) ++{ ++ if (cycle->new_log.syslog_set) { ++ closelog(); ++ } ++} ++#endif ++ +Index: nginx-1.4.7/src/core/ngx_log.h +=================================================================== +--- nginx-1.4.7.orig/src/core/ngx_log.h ++++ nginx-1.4.7/src/core/ngx_log.h +@@ -12,6 +12,13 @@ + #include + #include + ++#if (NGX_ENABLE_SYSLOG) ++#include ++ ++#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 + #endif + ++#if (NGX_ENABLE_SYSLOG) ++#include ++ ++#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; + }