From d6333fc6c58508f6b260385608279feeafb8c8a2 Mon Sep 17 00:00:00 2001 From: suyuan <175338101@qq.com> Date: Wed, 12 Oct 2022 00:23:56 +0800 Subject: [PATCH] Revert "Revert "fix nginx"" This reverts commit 60a01b5ad1f5bf13ee01af1e3fc6fc12f61ccf87. --- nginx/Config.in | 270 -- nginx/Config_ssl.in | 7 +- nginx/Makefile | 166 +- .../files-luci-support/60_nginx-luci-support | 56 +- .../70_nginx-luci-support-ssl | 48 - .../{luci_uwsgi.conf => luci.locations} | 1 + nginx/files-luci-support/luci_nginx.conf | 52 - nginx/files-luci-support/luci_nginx_ssl.conf | 67 - nginx/files/nginx.init | 67 +- .../101-add-lua-ngx-pipe.patch | 579 ---- nginx/patches/104-endianness_fix.patch | 19 + .../patches/201-ignore-invalid-options.patch | 2 +- nginx/patches/300-max-processes.patch | 11 - nginx/patches/400-socket-cloexec.patch | 174 -- nginx/src/lua-nginx/src/ngx_http_lua_pipe.c | 2499 ----------------- nginx/src/lua-nginx/src/ngx_http_lua_pipe.h | 94 - 16 files changed, 192 insertions(+), 3920 deletions(-) delete mode 100755 nginx/Config.in delete mode 100755 nginx/files-luci-support/70_nginx-luci-support-ssl rename nginx/files-luci-support/{luci_uwsgi.conf => luci.locations} (94%) mode change 100755 => 100644 delete mode 100755 nginx/files-luci-support/luci_nginx.conf delete mode 100755 nginx/files-luci-support/luci_nginx_ssl.conf delete mode 100644 nginx/patches-lua-nginx/101-add-lua-ngx-pipe.patch create mode 100644 nginx/patches/104-endianness_fix.patch delete mode 100755 nginx/patches/300-max-processes.patch delete mode 100644 nginx/patches/400-socket-cloexec.patch delete mode 100644 nginx/src/lua-nginx/src/ngx_http_lua_pipe.c delete mode 100644 nginx/src/lua-nginx/src/ngx_http_lua_pipe.h diff --git a/nginx/Config.in b/nginx/Config.in deleted file mode 100755 index ccb5e240f..000000000 --- a/nginx/Config.in +++ /dev/null @@ -1,270 +0,0 @@ -# -# Copyright (C) 2010-2016 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_SSL - bool - prompt "Enable SSL module" - help - Enable HTTPS/SSL support. - default n - -config NGINX_DAV - bool - prompt "Enable WebDAV module" - help - Enable the HTTP and WebDAV methods PUT, DELETE, MKCOL, COPY and MOVE. - default n - -config NGINX_UBUS - bool - prompt "Enable UBUS module" - help - Enable UBUS api support directly from the server. - default y - -config NGINX_FLV - bool - prompt "Enable FLV module" - help - Provides the ability to seek within FLV (Flash) files using time-based offsets. - default n - -config NGINX_STUB_STATUS - bool - prompt "Enable stub status module" - help - Enable the stub status module which gives some status from the server. - default n - -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_AUTH_REQUEST - bool - prompt "Enable HTTP auth request module" - default n - -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_HASH - bool - prompt "Enable HTTP hash module" - default y - -config NGINX_HTTP_UPSTREAM_IP_HASH - bool - prompt "Enable HTTP IP hash module" - default y - -config NGINX_HTTP_UPSTREAM_LEAST_CONN - bool - prompt "Enable HTTP least conn module" - default y - -config NGINX_HTTP_UPSTREAM_KEEPALIVE - bool - prompt "Enable HTTP keepalive module" - default y - -config NGINX_HTTP_CACHE - bool - prompt "Enable HTTP cache" - default y - -config NGINX_HTTP_V2 - bool - prompt "Enable HTTP_V2 module" - default n - -config NGINX_PCRE - bool - prompt "Enable PCRE library usage" - default y - -config NGINX_NAXSI - bool - prompt "Enable NAXSI module" - default y - -config NGINX_LUA - bool - prompt "Enable Lua module" - default n - -config NGINX_HTTP_REAL_IP - bool - prompt "Enable HTTP real ip module" - default n - -config NGINX_HTTP_SECURE_LINK - bool - prompt "Enable HTTP secure link module" - default n - -config NGINX_HTTP_SUB - bool - prompt "Enable HTTP sub module" - default n - -config NGINX_HEADERS_MORE - bool - prompt "Enable Headers_more module" - help - Set and clear input and output headers...more than "add"! - default y - -config NGINX_HTTP_BROTLI - bool - prompt "Enable Brotli compression module" - help - Add support for brotli compression module. - default n - -config NGINX_STREAM_CORE_MODULE - bool - prompt "Enable stream support" - help - Add support for NGINX request streaming. - default n - -config NGINX_STREAM_SSL_MODULE - bool - prompt "Enable stream support with SSL/TLS termination" - depends on NGINX_STREAM_CORE_MODULE - help - Add support for NGINX request streaming with SSL/TLS termination. - default n - -config NGINX_STREAM_SSL_PREREAD_MODULE - bool - prompt "Enable stream support with SSL/TLS pre-read" - depends on NGINX_STREAM_CORE_MODULE - help - Add support for NGINX request streaming using information from the ClientHello message without terminating SSL/TLS. - default n - -config NGINX_RTMP_MODULE - bool - prompt "Enable RTMP module" - depends on NGINX_SSL - help - Add support for NGINX-based Media Streaming Server module. - DASH enhanced - https://github.com/ut0mt8/nginx-rtmp-module - default n - -config NGINX_TS_MODULE - bool - prompt "Enable TS module" - help - Add support for MPEG-TS Live Module module. - default n - -endmenu diff --git a/nginx/Config_ssl.in b/nginx/Config_ssl.in index 098017aa6..1c53dab6a 100755 --- a/nginx/Config_ssl.in +++ b/nginx/Config_ssl.in @@ -46,11 +46,6 @@ config NGINX_HTTP_GZIP prompt "Enable HTTP gzip module" default y -config NGINX_HTTP_GZIP_STATIC - bool - prompt "Enable HTTP gzip static module" - default y - config NGINX_HTTP_SSI bool prompt "Enable HTTP ssi module" @@ -180,7 +175,7 @@ config NGINX_HTTP_CACHE config NGINX_HTTP_V2 bool prompt "Enable HTTP_V2 module" - default n + default y config NGINX_PCRE bool diff --git a/nginx/Makefile b/nginx/Makefile index 56d75ea52..7105e6c15 100755 --- a/nginx/Makefile +++ b/nginx/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=nginx -PKG_VERSION:=1.17.7 +PKG_VERSION:=1.19.6 PKG_RELEASE:=2 PKG_SOURCE:=nginx-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://nginx.org/download/ -PKG_HASH:=b62756842807e5693b794e5d0ae289bd8ae5b098e66538b2a91eb80f25c591ff +PKG_HASH:=b11195a02b1d3285ddf2987e02c6b6d28df41bb1b1dd25f33542848ef4fc33b5 PKG_MAINTAINER:=Thomas Heil \ Ansuel Smith @@ -25,14 +25,12 @@ PKG_BUILD_PARALLEL:=1 PKG_INSTALL:=1 PKG_CONFIG_DEPENDS := \ - CONFIG_NGINX_SSL \ CONFIG_NGINX_DAV \ CONFIG_NGINX_FLV \ CONFIG_NGINX_UBUS \ CONFIG_NGINX_STUB_STATUS \ CONFIG_NGINX_HTTP_CHARSET \ CONFIG_NGINX_HTTP_GZIP \ - CONFIG_NGINX_HTTP_GZIP_STATIC \ CONFIG_NGINX_HTTP_SSI \ CONFIG_NGINX_HTTP_USERID \ CONFIG_NGINX_HTTP_ACCESS \ @@ -76,6 +74,7 @@ PKG_CONFIG_DEPENDS := \ CONFIG_OPENSSL_WITH_NPN include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk define Package/nginx/default SECTION:=net @@ -83,28 +82,26 @@ define Package/nginx/default SUBMENU:=Web Servers/Proxies TITLE:=Nginx web server URL:=http://nginx.org/ - DEPENDS:=+NGINX_PCRE:libpcre +NGINX_SSL:libopenssl \ - +NGINX_HTTP_GZIP:zlib +NGINX_LUA:liblua +libpthread +NGINX_DAV:libxml2 \ - +NGINX_UBUS:libubus +NGINX_UBUS:libblobmsg-json +NGINX_UBUS:libjson-c + DEPENDS:=+libopenssl +libpthread + # TODO: add PROVIDES when removing nginx + # PROVIDES:=nginx endef define Package/nginx/description nginx is an HTTP and reverse proxy server, as well as a mail proxy server, \ - written by Igor Sysoev. (Some module require SSL module enable to show up in \ - config menu) -endef - -define Package/nginx - $(Package/nginx/default) - VARIANT:=no-ssl + written by Igor Sysoev. endef define Package/nginx-ssl $(Package/nginx/default) TITLE += with SSL support - DEPENDS +=+libopenssl VARIANT:=ssl - PROVIDES:=nginx + DEPENDS+= +NGINX_PCRE:libpcre \ + +NGINX_PCRE:nginx-ssl-util +!NGINX_PCRE:nginx-ssl-util-nopcre \ + +NGINX_HTTP_GZIP:zlib +NGINX_LUA:liblua +NGINX_DAV:libxml2 \ + +NGINX_UBUS:libubus +NGINX_UBUS:libblobmsg-json +NGINX_UBUS:libjson-c + EXTRA_DEPENDS:=nginx-ssl-util$(if $(CONFIG_NGINX_PCRE),,-nopcre) (>=1.5-1) (<2) + CONFLICTS:=nginx-all-module endef Package/nginx-ssl/description = $(Package/nginx/description) \ @@ -114,24 +111,21 @@ Package/nginx-ssl/description = $(Package/nginx/description) \ define Package/nginx-all-module $(Package/nginx/default) TITLE += with ALL module selected - DEPENDS:=+libpcre +libopenssl +zlib +liblua +libpthread +libxml2 \ - +libubus +libblobmsg-json +libjson-c + DEPENDS+=+libpcre +nginx-ssl-util +zlib +liblua +libxml2 +libubus \ + +libblobmsg-json +libjson-c + EXTRA_DEPENDS:=nginx-ssl-util (>=1.5-1) (<2) VARIANT:=all-module - PROVIDES:=nginx + PROVIDES += nginx-ssl endef Package/nginx-all-module/description = $(Package/nginx/description) \ This variant is compiled with ALL module selected. -define Package/nginx/config - source "$(SOURCE)/Config.in" -endef - define Package/nginx-ssl/config source "$(SOURCE)/Config_ssl.in" endef -config_files=nginx.conf mime.types +config_files=mime.types define Package/nginx/conffiles /etc/nginx/ @@ -141,7 +135,7 @@ Package/nginx-ssl/conffiles = $(Package/nginx/conffiles) Package/nginx-all-module/conffiles = $(Package/nginx/conffiles) -ADDITIONAL_MODULES:=--with-http_gzip_static_module +ADDITIONAL_MODULES:= --with-http_ssl_module ifneq ($(BUILD_VARIANT),all-module) ifneq ($(CONFIG_NGINX_HTTP_CACHE),y) @@ -149,8 +143,6 @@ ifneq ($(BUILD_VARIANT),all-module) endif ifneq ($(CONFIG_NGINX_PCRE),y) ADDITIONAL_MODULES += --without-pcre - else - ADDITIONAL_MODULES += --with-pcre endif ifneq ($(CONFIG_NGINX_HTTP_CHARSET),y) ADDITIONAL_MODULES += --without-http_charset_module @@ -160,9 +152,6 @@ ifneq ($(BUILD_VARIANT),all-module) ifneq ($(CONFIG_NGINX_HTTP_GZIP),y) ADDITIONAL_MODULES += --without-http_gzip_module endif - ifeq ($(CONFIG_NGINX_HTTP_GZIP_STATIC),y) - ADDITIONAL_MODULES += --with-http_gzip_static_module - endif ifneq ($(CONFIG_NGINX_HTTP_SSI),y) ADDITIONAL_MODULES += --without-http_ssi_module endif @@ -236,16 +225,6 @@ ifneq ($(BUILD_VARIANT),all-module) ifneq ($(CONFIG_NGINX_HTTP_UPSTREAM_KEEPALIVE),y) ADDITIONAL_MODULES += --without-http_upstream_keepalive_module endif - - ifeq ($(BUILD_VARIANT),ssl) - ifneq ($(CONFIG_NGINX_SSL),y) - ADDITIONAL_MODULES += --with-http_ssl_module - endif - endif - - ifeq ($(CONFIG_NGINX_SSL),y) - ADDITIONAL_MODULES += --with-http_ssl_module - endif ifeq ($(CONFIG_NGINX_NAXSI),y) ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-naxsi/naxsi_src endif @@ -312,44 +291,36 @@ else CONFIG_NGINX_LUA:=y CONFIG_NGINX_DAV:=y CONFIG_NGINX_UBUS:=y - ADDITIONAL_MODULES += --with-http_ssl_module --add-module=$(PKG_BUILD_DIR)/nginx-naxsi/naxsi_src \ - --add-module=$(PKG_BUILD_DIR)/lua-nginx --with-ipv6 --with-http_stub_status_module --with-http_flv_module \ - --with-http_dav_module --add-module=$(PKG_BUILD_DIR)/nginx-dav-ext-module \ + ADDITIONAL_MODULES += --with-ipv6 --with-http_stub_status_module --with-http_flv_module \ + --with-http_dav_module \ --with-http_auth_request_module --with-http_v2_module --with-http_realip_module \ - --with-http_secure_link_module --with-http_sub_module --add-module=$(PKG_BUILD_DIR)/nginx-headers-more \ + --with-http_secure_link_module --with-http_sub_module \ --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module \ + --add-module=$(PKG_BUILD_DIR)/nginx-headers-more \ + --add-module=$(PKG_BUILD_DIR)/nginx-naxsi/naxsi_src \ + --add-module=$(PKG_BUILD_DIR)/lua-nginx \ + --add-module=$(PKG_BUILD_DIR)/nginx-dav-ext-module \ --add-module=$(PKG_BUILD_DIR)/nginx-brotli --add-module=$(PKG_BUILD_DIR)/nginx-rtmp \ --add-module=$(PKG_BUILD_DIR)/nginx-ts --add-module=$(PKG_BUILD_DIR)/nginx-ubus-module - config_files += koi-utf koi-win win-utf fastcgi_params + config_files += koi-utf koi-win win-utf fastcgi_params uwsgi_params endif -define Package/nginx-mod-luci/default +define Package/nginx-mod-luci TITLE:=Nginx on LuCI SECTION:=net CATEGORY:=Network SUBMENU:=Web Servers/Proxies TITLE:=Support file for Nginx URL:=http://nginx.org/ - DEPENDS:=+uwsgi +uwsgi-luci-support -endef - -define Package/nginx-mod-luci - $(Package/nginx-mod-luci/default) - DEPENDS += +nginx + DEPENDS:=+uwsgi +uwsgi-luci-support +nginx + # TODO: add PROVIDES when removing nginx-mod-luci-ssl + # PROVIDES:=nginx-mod-luci-ssl endef define Package/nginx-mod-luci/description Support file for LuCI in nginx. Include custom nginx configuration, autostart script for uwsgi. endef -define Package/nginx-mod-luci-ssl - $(Package/nginx-mod-luci/default) - TITLE += with HTTPS support - DEPENDS += +nginx-ssl -endef - -Package/nginx-mod-luci-ssl/description = $(define Package/nginx-mod-luci/description) \ - This also include redirect from http to https and cert autogeneration. TARGET_CFLAGS += -fvisibility=hidden -ffunction-sections -fdata-sections -DNGX_LUA_NO_BY_LUA_BLOCK TARGET_LDFLAGS += -Wl,--gc-sections @@ -359,12 +330,14 @@ ifeq ($(CONFIG_NGINX_LUA),y) LUA_LIB=$(STAGING_DIR)/usr/lib endif +CONFIGURE_VARS += CONFIG_BIG_ENDIAN=$(CONFIG_BIG_ENDIAN) + CONFIGURE_ARGS += \ --crossbuild=Linux::$(ARCH) \ --prefix=/usr \ --conf-path=/etc/nginx/nginx.conf \ $(ADDITIONAL_MODULES) \ - --error-log-path=/var/log/nginx/error.log \ + --error-log-path=stderr \ --pid-path=/var/run/nginx.pid \ --lock-path=/var/lock/nginx.lock \ --http-log-path=/var/log/nginx/access.log \ @@ -377,25 +350,16 @@ CONFIGURE_ARGS += \ --without-http_upstream_zone_module define Package/nginx-mod-luci/install - $(INSTALL_DIR) $(1)/etc/nginx - $(INSTALL_BIN) ./files-luci-support/luci_uwsgi.conf $(1)/etc/nginx/luci_uwsgi.conf - $(INSTALL_BIN) ./files-luci-support/luci_nginx.conf $(1)/etc/nginx/luci_nginx.conf + $(INSTALL_DIR) $(1)/etc/nginx/conf.d + $(INSTALL_CONF) ./files-luci-support/luci.locations $(1)/etc/nginx/conf.d/ $(INSTALL_DIR) $(1)/etc/uci-defaults $(INSTALL_BIN) ./files-luci-support/60_nginx-luci-support $(1)/etc/uci-defaults/60_nginx-luci-support endef -define Package/nginx-mod-luci-ssl/install - $(Package/nginx-mod-luci/install) - $(INSTALL_DIR) $(1)/etc/nginx - $(INSTALL_BIN) ./files-luci-support/luci_nginx_ssl.conf $(1)/etc/nginx/luci_nginx_ssl.conf - $(INSTALL_DIR) $(1)/etc/uci-defaults - $(INSTALL_BIN) ./files-luci-support/70_nginx-luci-support-ssl $(1)/etc/uci-defaults/70_nginx-luci-support-ssl -endef - -define Package/nginx/install +define Package/nginx-ssl/install $(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/nginx $(1)/usr/sbin/ - $(INSTALL_DIR) $(1)/etc/nginx + $(INSTALL_DIR) $(1)/etc/nginx/conf.d $(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 @@ -408,8 +372,20 @@ endif $(if $(CONFIG_NGINX_NAXSI),$(chmod 0640 $(1)/etc/nginx/naxsi_core.rules)) endef -Package/nginx-ssl/install = $(Package/nginx/install) -Package/nginx-all-module/install = $(Package/nginx/install) +Package/nginx-all-module/install = $(Package/nginx-ssl/install) + +define Package/nginx-ssl/prerm +#!/bin/sh +[ -z "$${IPKG_INSTROOT}" ] || exit 0 +[ "$${PKG_UPGRADE}" = "1" ] && exit 0 +eval $$(/usr/bin/nginx-util get_env) +[ "$$(uci get "nginx.$${LAN_NAME}.$${MANAGE_SSL}")" = "self-signed" ] || exit 0 +rm -f "$$(uci get "nginx.$${LAN_NAME}.ssl_certificate")" +rm -f "$$(uci get "nginx.$${LAN_NAME}.ssl_certificate_key")" +exit 0 +endef + +Package/nginx-all-module/prerm = $(Package/nginx-ssl/prerm) define Build/Prepare $(Build/Prepare/Default) @@ -444,11 +420,11 @@ endif ifeq ($(CONFIG_NGINX_HTTP_BROTLI),y) define Download/nginx-brotli - VERSION:=dc37f658ccb5a51d090dc09d1a2aca2f24309869 + VERSION:=e505dce68acc190cc5a1e780a3b0275e39f160ca SUBDIR:=nginx-brotli FILE:=ngx-brotli-module-$$(VERSION).tar.xz - URL:=https://github.com/eustas/ngx_brotli.git - MIRROR_HASH:=6bc0c40ff24f6e0ac616dfddc803bdc7fcf54764ba9dc4f9cecb3a68beedcdaf + URL:=https://github.com/google/ngx_brotli.git + MIRROR_HASH:=04847f11ef808fed50f44b2af0ef3abf59ff0ffc06dfc7394d9ab51d53fef31f PROTO:=git endef $(eval $(call Download,nginx-brotli)) @@ -553,11 +529,11 @@ endif ifeq ($(CONFIG_NGINX_UBUS),y) define Download/nginx-ubus-module - VERSION:=f30b0167a2cdb40f23bd90928d601bdb0c1b8fad + VERSION:=b2d7260dcb428b2fb65540edb28d7538602b4a26 SUBDIR:=nginx-ubus-module FILE:=nginx-ubus-module-$$(VERSION).tar.xz URL:=https://github.com/Ansuel/nginx-ubus-module.git - MIRROR_HASH:=02c7d4b0df7f4b69605e71b0fefdc99b5a9470c68cad7ccfb31ebefe4e7e0704 + MIRROR_HASH:=472cef416d25effcac66c85417ab6596e634a7a64d45b709bb090892d567553c PROTO:=git endef $(eval $(call Download,nginx-ubus-module)) @@ -568,8 +544,34 @@ ifeq ($(CONFIG_NGINX_UBUS),y) endef endif -$(eval $(call BuildPackage,nginx)) $(eval $(call BuildPackage,nginx-ssl)) $(eval $(call BuildPackage,nginx-all-module)) $(eval $(call BuildPackage,nginx-mod-luci)) + +# TODO: remove after a transition period (together with pkg nginx-util): +# It is for smoothly substituting nginx and nginx-mod-luci-ssl (by nginx-ssl +# respectively nginx-mod-luci). Add above commented PROVIDES when removing. + +define Package/nginx + TITLE:=Dummy package for transition when upgrading. + DEPENDS:=+nginx-ssl + PKGARCH:=all +endef + +define Package/nginx/install + $(INSTALL_DIR) $(1)/usr/bin +endef + +$(eval $(call BuildPackage,nginx)) + +define Package/nginx-mod-luci-ssl + TITLE:=Dummy package for transition when upgrading. + DEPENDS:=+nginx-mod-luci + PKGARCH:=all +endef + +define Package/nginx-mod-luci-ssl/install + $(INSTALL_DIR) $(1)/usr/bin +endef + $(eval $(call BuildPackage,nginx-mod-luci-ssl)) diff --git a/nginx/files-luci-support/60_nginx-luci-support b/nginx/files-luci-support/60_nginx-luci-support index b682a832e..b2564444c 100755 --- a/nginx/files-luci-support/60_nginx-luci-support +++ b/nginx/files-luci-support/60_nginx-luci-support @@ -1,41 +1,41 @@ #!/bin/sh -if [ -f "/etc/nginx/luci_nginx.conf" ] && [ -f "/etc/nginx/nginx.conf" ]; then - if [ ! "$(cat '/etc/nginx/nginx.conf' | grep 'luci_uwsgi.conf')" ]; then - mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf_old - mv /etc/nginx/luci_nginx.conf /etc/nginx/nginx.conf - core_number=$(grep -c ^processor /proc/cpuinfo) - sed -i "3s/.*/worker_processes "$core_number";/" /etc/nginx/nginx.conf - if [ -n "$(pgrep uhttpd)" ]; then - /etc/init.d/uhttpd stop - /etc/init.d/uhttpd disable - fi - if [ -n "$(pgrep nginx)" ]; then - /etc/init.d/nginx restart - else - /etc/init.d/nginx start - fi - if [ -n "$(pgrep uwsgi)" ]; then - /etc/init.d/uwsgi restart - else - /etc/init.d/uwsgi start - fi - else - rm /etc/nginx/luci_nginx.conf - fi -fi - if nginx -V 2>&1 | grep -q ubus; then - if [ -z "$(cat /etc/nginx/luci_uwsgi.conf | grep ubus)" ]; then - cat <> /etc/nginx/luci_uwsgi.conf + if [ -z "$(cat /etc/nginx/conf.d/luci.locations | grep ubus)" ]; then + cat <> /etc/nginx/conf.d/luci.locations location /ubus { ubus_interpreter; - ubus_socket_path /var/run/ubus.sock; + ubus_socket_path /var/run/ubus/ubus.sock; ubus_parallel_req 2; } EOT fi fi +grep -q /var/run/ubus.sock /etc/nginx/conf.d/luci.locations && + sed -i 's#/var/run/ubus.sock#/var/run/ubus/ubus.sock#' /etc/nginx/conf.d/luci.locations + +if [ -x /etc/init.d/uhttpd ]; then + /etc/init.d/uhttpd disable + if [ -n "$(pgrep uhttpd)" ]; then + /etc/init.d/uhttpd stop + fi +fi + +/etc/init.d/nginx enable +if [ -n "$(pgrep nginx)" ]; then + /etc/init.d/nginx restart +else + /etc/init.d/nginx start +fi + +/etc/init.d/uwsgi enable +if [ -n "$(pgrep uwsgi)" ]; then + /etc/init.d/uwsgi restart +else + /etc/init.d/uwsgi start +fi + + exit 0 diff --git a/nginx/files-luci-support/70_nginx-luci-support-ssl b/nginx/files-luci-support/70_nginx-luci-support-ssl deleted file mode 100755 index 76ce3a819..000000000 --- a/nginx/files-luci-support/70_nginx-luci-support-ssl +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh - - -if [ -f "/etc/nginx/luci_nginx_ssl.conf" ] && [ -f "/etc/nginx/nginx.conf" ]; then - if [ ! "$(cat '/etc/nginx/nginx.conf' | grep 'return 301 https://$host$request_uri;')" ]; then - if [ -f "/etc/nginx/nginx.conf_old" ]; then - rm /etc/nginx/nginx.conf - else - mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf_old - fi - mv /etc/nginx/luci_nginx_ssl.conf /etc/nginx/nginx.conf - core_number=$(grep -c ^processor /proc/cpuinfo) - sed -i "3s/.*/worker_processes "$core_number";/" /etc/nginx/nginx.conf - if [ -n "$(pgrep nginx)" ]; then - /etc/init.d/nginx restart - else - /etc/init.d/nginx start - fi - else - rm /etc/nginx/luci_nginx_ssl.conf - fi -fi - - -if [ ! -f "/etc/nginx/nginx.key" ]; then - - NGINX_KEY=/etc/nginx/nginx.key - NGINX_CER=/etc/nginx/nginx.cer - OPENSSL_BIN=/usr/bin/openssl - PX5G_BIN=/usr/sbin/px5g - - # Prefer px5g for certificate generation (existence evaluated last) - GENKEY_CMD="" - UNIQUEID=$(dd if=/dev/urandom bs=1 count=4 | hexdump -e '1/1 "%02x"') - [ -x "$OPENSSL_BIN" ] && GENKEY_CMD="$OPENSSL_BIN req -x509 -nodes" - [ -x "$PX5G_BIN" ] && GENKEY_CMD="$PX5G_BIN selfsigned" - [ -n "$GENKEY_CMD" ] && { - $GENKEY_CMD \ - -days 730 -newkey rsa:2048 -keyout "${NGINX_KEY}.new" -out "${NGINX_CER}.new" \ - -subj /C="ZZ"/ST="Somewhere"/L="Unknown"/O="OpenWrt""$UNIQUEID"/CN="OpenWrt" - sync - mv "${NGINX_KEY}.new" "${NGINX_KEY}" - mv "${NGINX_CER}.new" "${NGINX_CER}" - } -fi - - -exit 0 diff --git a/nginx/files-luci-support/luci_uwsgi.conf b/nginx/files-luci-support/luci.locations old mode 100755 new mode 100644 similarity index 94% rename from nginx/files-luci-support/luci_uwsgi.conf rename to nginx/files-luci-support/luci.locations index 3ea3de914..374ee5d9f --- a/nginx/files-luci-support/luci_uwsgi.conf +++ b/nginx/files-luci-support/luci.locations @@ -13,4 +13,5 @@ location ~ /cgi-bin/cgi-(backup|download|upload|exec) { } location /luci-static { + error_log stderr crit; } diff --git a/nginx/files-luci-support/luci_nginx.conf b/nginx/files-luci-support/luci_nginx.conf deleted file mode 100755 index 75f0f78a6..000000000 --- a/nginx/files-luci-support/luci_nginx.conf +++ /dev/null @@ -1,52 +0,0 @@ - -user root; -worker_processes 1; - -#error_log logs/error.log; -#error_log logs/error.log notice; -#error_log logs/error.log info; - -pid /var/run/nginx.pid; - - -events { - worker_connections 1024; -} - - -http { - include mime.types; - default_type application/octet-stream; - - sendfile on; - keepalive_timeout 0; - - client_body_buffer_size 10K; - client_header_buffer_size 1k; - client_max_body_size 1G; - large_client_header_buffers 2 1k; - - gzip on; - gzip_http_version 1.1; - gzip_vary on; - gzip_comp_level 1; - gzip_proxied any; - gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml; - - root /www; - - server { - listen 80 default_server; - listen [::]:80 default_server; - server_name localhost; - - location ~* .(jpg|jpeg|png|gif|ico|css|js)$ { - expires 365d; - } - - include luci_uwsgi.conf; - - } - - include /etc/nginx/conf.d/*.conf; -} diff --git a/nginx/files-luci-support/luci_nginx_ssl.conf b/nginx/files-luci-support/luci_nginx_ssl.conf deleted file mode 100755 index db33e554c..000000000 --- a/nginx/files-luci-support/luci_nginx_ssl.conf +++ /dev/null @@ -1,67 +0,0 @@ - -user root; -worker_processes 1; - -#error_log logs/error.log; -#error_log logs/error.log notice; -#error_log logs/error.log info; - -pid /var/run/nginx.pid; - - -events { - worker_connections 1024; -} - - -http { - include mime.types; - default_type application/octet-stream; - - sendfile on; - keepalive_timeout 0; - - client_body_buffer_size 10K; - client_header_buffer_size 1k; - client_max_body_size 1G; - large_client_header_buffers 2 1k; - - gzip on; - gzip_http_version 1.1; - gzip_vary on; - gzip_comp_level 1; - gzip_proxied any; - gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml; - - root /www; - - server { - listen 80 default_server; - listen [::]:80 default_server; - server_name _; - return 301 https://$host$request_uri; - } - - server { - listen 443 ssl default_server; - listen [::]:443 ssl default_server; - server_name localhost; - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_prefer_server_ciphers on; - ssl_ciphers "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:DHE+AESGCM:DHE:!RSA!aNULL:!eNULL:!LOW:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!CAMELLIA:!SEED"; - ssl_session_tickets off; - - ssl_certificate /etc/nginx/nginx.cer; - ssl_certificate_key /etc/nginx/nginx.key; - - location ~* .(jpg|jpeg|png|gif|ico|css|js)$ { - expires 365d; - } - - include luci_uwsgi.conf; - - } - - include /etc/nginx/conf.d/*.conf; -} diff --git a/nginx/files/nginx.init b/nginx/files/nginx.init index 528f390e1..300a8c657 100755 --- a/nginx/files/nginx.init +++ b/nginx/files/nginx.init @@ -5,20 +5,69 @@ START=80 USE_PROCD=1 -start_service() { - [ -f /etc/init.d/uhttpd ] && { - /etc/init.d/uhttpd enabled && { - /etc/init.d/uhttpd stop - /etc/init.d/uhttpd disable - } - } +G_OPTS="daemon off;" + +NGINX_UTIL="/usr/bin/nginx-util" + +eval $("${NGINX_UTIL}" get_env) + +CONF="" + + +nginx_init() { + [ -z "${CONF}" ] || return # already called. [ -d /var/log/nginx ] || mkdir -p /var/log/nginx [ -d /var/lib/nginx ] || mkdir -p /var/lib/nginx + rm -f "$(readlink "${UCI_CONF}")" + ${NGINX_UTIL} init_lan + + if [ -e "${UCI_CONF}" ] + then CONF="${UCI_CONF}" + else CONF="${NGINX_CONF}" + fi + + local message + message="$(/usr/sbin/nginx -t -c "${CONF}" -g "${G_OPTS}" 2>&1)" || + { + echo -e "${message}" | logger -t "nginx_init" -p "daemon.err" + logger -s -t "nginx_init" -p "daemon.err" "NOT using conf file!" + echo "show config to be used by: nginx -T -c '${CONF}'" >&2 + exit 1 + } + + logger -t "nginx_init" -p "daemon.info" "using ${CONF} (the test is ok)" +} + + +start_service() { + nginx_init + procd_open_instance - procd_set_param command /usr/sbin/nginx -c /etc/nginx/nginx.conf -g 'daemon off;' - procd_set_param file /etc/nginx/nginx.conf + procd_set_param command /usr/sbin/nginx -c "${CONF}" -g "${G_OPTS}" + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_set_param file "${CONF}" "${CONF_DIR}*.crt" "${CONF_DIR}*.key" \ + "${CONF_DIR}*.conf" "${CONF_DIR}*.locations" procd_set_param respawn procd_close_instance } + + +reload_service() { + nginx_init + + if [ "$(cat "/proc/$(cat "/var/run/nginx.pid")/cmdline")" = \ + "nginx: master process /usr/sbin/nginx -c ${CONF} -g ${G_OPTS}" ] + then procd_send_signal nginx + else restart + fi +} + + +extra_command "relog" "Reopen log files (without reloading)" +relog() { + [ -d /var/log/nginx ] || mkdir -p /var/log/nginx + procd_send_signal nginx '*' USR1 +} diff --git a/nginx/patches-lua-nginx/101-add-lua-ngx-pipe.patch b/nginx/patches-lua-nginx/101-add-lua-ngx-pipe.patch deleted file mode 100644 index bbeb5dce5..000000000 --- a/nginx/patches-lua-nginx/101-add-lua-ngx-pipe.patch +++ /dev/null @@ -1,579 +0,0 @@ -Index: nginx-1.17.7/lua-nginx/config -=================================================================== ---- nginx-1.17.7.orig/lua-nginx/config -+++ nginx-1.17.7/lua-nginx/config -@@ -362,6 +362,7 @@ HTTP_LUA_SRCS=" \ - $ngx_addon_dir/src/ngx_http_lua_ssl.c \ - $ngx_addon_dir/src/ngx_http_lua_log_ringbuf.c \ - $ngx_addon_dir/src/ngx_http_lua_input_filters.c \ -+ $ngx_addon_dir/src/ngx_http_lua_pipe.c \ - " - - HTTP_LUA_DEPS=" \ -@@ -424,6 +425,7 @@ HTTP_LUA_DEPS=" \ - $ngx_addon_dir/src/ngx_http_lua_ssl.h \ - $ngx_addon_dir/src/ngx_http_lua_log_ringbuf.h \ - $ngx_addon_dir/src/ngx_http_lua_input_filters.h \ -+ $ngx_addon_dir/src/ngx_http_lua_pipe.h \ - " - - CFLAGS="$CFLAGS -DNDK_SET_VAR" -@@ -508,6 +510,51 @@ ngx_feature_test="int rc = malloc_trim(( - SAVED_CC_TEST_FLAGS="$CC_TEST_FLAGS" - CC_TEST_FLAGS="-Werror -Wall $CC_TEST_FLAGS" - -+. auto/feature -+ -+CC_TEST_FLAGS="$SAVED_CC_TEST_FLAGS" -+ -+# ---------------------------------------- -+ -+ngx_feature="pipe2" -+ngx_feature_libs= -+ngx_feature_name="NGX_HTTP_LUA_HAVE_PIPE2" -+ngx_feature_run=no -+ngx_feature_incs="#include " -+ngx_feature_test="int fd[2]; pipe2(fd, O_CLOEXEC|O_NONBLOCK);" -+SAVED_CC_TEST_FLAGS="$CC_TEST_FLAGS" -+CC_TEST_FLAGS="-Werror -Wall $CC_TEST_FLAGS" -+ -+. auto/feature -+ -+CC_TEST_FLAGS="$SAVED_CC_TEST_FLAGS" -+ -+# ---------------------------------------- -+ -+ngx_feature="signalfd" -+ngx_feature_libs= -+ngx_feature_name="NGX_HTTP_LUA_HAVE_SIGNALFD" -+ngx_feature_run=no -+ngx_feature_incs="#include " -+ngx_feature_test="sigset_t set; signalfd(-1, &set, SFD_NONBLOCK|SFD_CLOEXEC);" -+SAVED_CC_TEST_FLAGS="$CC_TEST_FLAGS" -+CC_TEST_FLAGS="-Werror -Wall $CC_TEST_FLAGS" -+ -+. auto/feature -+ -+CC_TEST_FLAGS="$SAVED_CC_TEST_FLAGS" -+ -+# ---------------------------------------- -+ -+ngx_feature="execvpe" -+ngx_feature_libs= -+ngx_feature_name="NGX_HTTP_LUA_HAVE_EXECVPE" -+ngx_feature_run=no -+ngx_feature_incs= -+ngx_feature_test='char* argv[] = {"/bin/sh"};execvpe("/bin/sh", argv, NULL);' -+SAVED_CC_TEST_FLAGS="$CC_TEST_FLAGS" -+CC_TEST_FLAGS="-Werror -Wall $CC_TEST_FLAGS" -+ - . auto/feature - - CC_TEST_FLAGS="$SAVED_CC_TEST_FLAGS" -Index: nginx-1.17.7/lua-nginx/src/ngx_http_lua_initworkerby.c -=================================================================== ---- nginx-1.17.7.orig/lua-nginx/src/ngx_http_lua_initworkerby.c -+++ nginx-1.17.7/lua-nginx/src/ngx_http_lua_initworkerby.c -@@ -12,6 +12,7 @@ - - #include "ngx_http_lua_initworkerby.h" - #include "ngx_http_lua_util.h" -+#include "ngx_http_lua_pipe.h" - - - static u_char *ngx_http_lua_log_init_worker_error(ngx_log_t *log, -@@ -65,6 +66,12 @@ ngx_http_lua_init_worker(ngx_cycle_t *cy - - return NGX_OK; - } -+ -+#ifdef HAVE_NGX_LUA_PIPE -+ if (ngx_http_lua_pipe_add_signal_handler(cycle) != NGX_OK) { -+ return NGX_ERROR; -+ } -+#endif - #endif /* NGX_WIN32 */ - - if (lmcf->init_worker_handler == NULL) { -Index: nginx-1.17.7/lua-nginx/src/ngx_http_lua_module.c -=================================================================== ---- nginx-1.17.7.orig/lua-nginx/src/ngx_http_lua_module.c -+++ nginx-1.17.7/lua-nginx/src/ngx_http_lua_module.c -@@ -29,6 +29,7 @@ - #include "ngx_http_lua_ssl_session_storeby.h" - #include "ngx_http_lua_ssl_session_fetchby.h" - #include "ngx_http_lua_headers.h" -+#include "ngx_http_lua_pipe.h" - - - static void *ngx_http_lua_create_main_conf(ngx_conf_t *cf); -@@ -734,6 +735,10 @@ ngx_http_lua_init(ngx_conf_t *cf) - cln->handler = ngx_http_lua_sema_mm_cleanup; - #endif - -+#ifdef HAVE_NGX_LUA_PIPE -+ ngx_http_lua_pipe_init(); -+#endif -+ - #if nginx_version >= 1011011 - cln = ngx_pool_cleanup_add(cf->pool, 0); - if (cln == NULL) { -Index: nginx-1.17.7/lua-nginx/src/ngx_http_lua_util.h -=================================================================== ---- nginx-1.17.7.orig/lua-nginx/src/ngx_http_lua_util.h -+++ nginx-1.17.7/lua-nginx/src/ngx_http_lua_util.h -@@ -30,6 +30,12 @@ typedef struct { - * user code cache table */ - extern char ngx_http_lua_code_cache_key; - -+#define NGX_HTTP_LUA_CONTEXT_YIELDABLE (NGX_HTTP_LUA_CONTEXT_REWRITE \ -+ | NGX_HTTP_LUA_CONTEXT_ACCESS \ -+ | NGX_HTTP_LUA_CONTEXT_CONTENT \ -+ | NGX_HTTP_LUA_CONTEXT_TIMER \ -+ | NGX_HTTP_LUA_CONTEXT_SSL_CERT \ -+ | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH) - - /* key in Lua vm registry for all the "ngx.ctx" tables */ - #define ngx_http_lua_ctx_tables_key "ngx_lua_ctx_tables" -Index: nginx-1.17.7/lua-nginx/src/ngx_http_lua_util.c -=================================================================== ---- nginx-1.17.7.orig/lua-nginx/src/ngx_http_lua_util.c -+++ nginx-1.17.7/lua-nginx/src/ngx_http_lua_util.c -@@ -52,6 +52,7 @@ - #include "ngx_http_lua_ssl_certby.h" - #include "ngx_http_lua_ssl.h" - #include "ngx_http_lua_log_ringbuf.h" -+#include "ngx_http_lua_pipe.h" - - - #if 1 -@@ -744,6 +745,9 @@ ngx_http_lua_inject_ngx_api(lua_State *L - ngx_http_lua_inject_timer_api(L); - ngx_http_lua_inject_config_api(L); - ngx_http_lua_inject_worker_api(L); -+#ifdef HAVE_NGX_LUA_PIPE -+ ngx_http_lua_inject_pipe_api(L); -+#endif - - ngx_http_lua_inject_misc_api(L); - -Index: nginx-1.17.7/lua-nginx/src/ngx_http_lua_pipe.c -=================================================================== ---- nginx-1.17.7.orig/lua-nginx/src/ngx_http_lua_pipe.c -+++ nginx-1.17.7/lua-nginx/src/ngx_http_lua_pipe.c -@@ -83,6 +83,7 @@ static void ngx_http_lua_pipe_proc_wait_ - static ngx_rbtree_t ngx_http_lua_pipe_rbtree; - static ngx_rbtree_node_t ngx_http_lua_pipe_proc_sentinel; - -+static char ngx_http_lua_proc_metatable_key; - - #if (NGX_HTTP_LUA_HAVE_SIGNALFD) - static int ngx_http_lua_signalfd; -@@ -418,6 +419,8 @@ ngx_http_lua_pipe_sigchld_event_handler( - */ - ngx_post_event((&pipe_node->wait_co_ctx->sleep), - &ngx_posted_events); -+ } else { -+ ngx_http_lua_pipe_proc_finalize(pipe_node->proc); - } - - pipe_node->proc->pipe->dead = 1; -@@ -2090,7 +2093,31 @@ ngx_http_lua_pipe_read_retval_helper(ngx - - rc = ngx_http_lua_pipe_read(pipe, pipe_ctx); - if (rc != NGX_AGAIN) { -- return 0; -+ size_t buf_size = 4096; -+ -+ while (1) { -+ u_char *buf, *p; -+ -+ buf = ngx_pcalloc(pipe->pool, buf_size); -+ if (!buf) { -+ lua_pushnil(L); -+ lua_pushliteral(L, "no memory"); -+ return 2; -+ } -+ -+ p = buf; -+ -+ ngx_http_lua_pipe_put_data(pipe, pipe_ctx, &p, &buf_size); -+ if (!p) { -+ ngx_pfree(pipe->pool, buf); -+ continue; -+ } -+ -+ lua_pushlstring(L, (char *)buf, buf_size); -+ ngx_pfree(pipe->pool, buf); -+ break; -+ } -+ return 1; - } - - rev = pipe_ctx->c->read; -@@ -2493,6 +2520,353 @@ ngx_http_lua_pipe_proc_wait_cleanup(void - wait_co_ctx->cleanup = NULL; - } - -+static int lua_table_array_cnt(lua_State *L, int idx) -+{ -+ int n = 0; -+ -+ if (idx < 0) -+ idx = lua_gettop(L) + idx + 1; -+ -+ if (!lua_istable(L, idx)) -+ return 0; -+ -+ lua_pushnil(L); /* stack: table key */ -+ -+ while (lua_next(L, idx)) { /* stack: table key value */ -+ if (lua_type(L, -2) == LUA_TNUMBER) { -+ lua_Number idx = lua_tonumber(L, -2); -+ if (floor(idx) != idx || idx != n + 1) -+ goto non_array; -+ n++; -+ lua_pop(L, 1); /* stack: table key */ -+ continue; -+ } -+non_array: -+ lua_pop(L, 2); -+ break; -+ } -+ -+ return n; -+} -+ -+static void ngx_http_lua_ngx_pipe_set_opt(lua_State *L, int idx, const char *name, int *val) -+{ -+ lua_getfield(L, idx, name); -+ if (!lua_isnil(L, -1)) -+ *val = lua_tointeger(L, -1); -+ lua_pop(L, 1); -+} -+ -+static int ngx_http_lua_ngx_pipe_spawn(lua_State *L) -+{ -+ ngx_http_lua_ffi_pipe_proc_t *proc; -+ int merge_stderr = 0; -+ int buffer_size = 4096; -+ int write_timeout = 10000; -+ int stdout_read_timeout = 10000; -+ int stderr_read_timeout = 10000; -+ int wait_timeout = 10000; -+ const char **args = NULL, **envs = NULL; -+ u_char errbuf[512] = ""; -+ size_t errbuf_size = sizeof(errbuf); -+ ngx_http_request_t *r; -+ int rc = 1; -+ -+ r = ngx_http_lua_get_req(L); -+ if (!r) -+ return luaL_error(L, "no request found"); -+ -+ if (lua_istable(L, 1)) { -+ int nargs = lua_table_array_cnt(L, 1); -+ -+ if (nargs == 0) -+ return luaL_error(L, "bad args arg: non-empty table expected"); -+ -+ args = ngx_pcalloc(r->pool, sizeof(char *) * (nargs + 1)); -+ -+ for (int i = 0; i < nargs; i++) { -+ lua_rawgeti(L, 1, i + 1); -+ args[i] = lua_tostring(L, -1); -+ lua_pop(L, 1); -+ } -+ } else if (lua_isstring(L, 1)) { -+ args = ngx_pcalloc(r->pool, sizeof(char *) * 4); -+ args[0] = "/bin/sh"; -+ args[1] = "-c"; -+ args[2] = lua_tostring(L, 1); -+ } else { -+ return luaL_error(L, "bad args arg: table expected, got '%s'", lua_typename(L, lua_type(L, 1))); -+ } -+ -+ if (lua_istable(L, 2)) { -+ lua_getfield(L, 2, "merge_stderr"); -+ merge_stderr = lua_toboolean(L, -1); -+ lua_pop(L, 1); -+ -+ ngx_http_lua_ngx_pipe_set_opt(L, 2, "buffer_size", &buffer_size); -+ ngx_http_lua_ngx_pipe_set_opt(L, 2, "write_timeout", &write_timeout); -+ ngx_http_lua_ngx_pipe_set_opt(L, 2, "stdout_read_timeout", &stdout_read_timeout); -+ ngx_http_lua_ngx_pipe_set_opt(L, 2, "stderr_read_timeout", &stderr_read_timeout); -+ ngx_http_lua_ngx_pipe_set_opt(L, 2, "wait_timeout", &wait_timeout); -+ -+ lua_getfield(L, 2, "environ"); -+ if (lua_istable(L, -1)) { -+ int nenv = lua_table_array_cnt(L, -1); -+ -+ envs = ngx_pcalloc(r->pool, sizeof(char *) * (nenv + 1)); -+ -+ for (int i = 0; i < nenv; i++) { -+ lua_rawgeti(L, -1, i + 1); -+ envs[i] = lua_tostring(L, -1); -+ lua_pop(L, 1); -+ } -+ } -+ lua_pop(L, 1); -+ } -+ -+ proc = lua_newuserdata(L, sizeof(ngx_http_lua_ffi_pipe_proc_t)); -+ if (!proc) { -+ lua_pushnil(L); -+ lua_pushliteral(L, "no memory"); -+ rc = 2; -+ goto free_mem; -+ } -+ -+ proc->write_timeout = write_timeout; -+ proc->stdout_read_timeout = stdout_read_timeout; -+ proc->stderr_read_timeout = stderr_read_timeout; -+ proc->wait_timeout = wait_timeout; -+ -+ lua_pushlightuserdata(L, &ngx_http_lua_proc_metatable_key); -+ lua_rawget(L, LUA_REGISTRYINDEX); -+ lua_setmetatable(L, -2); -+ -+ rc = ngx_http_lua_ffi_pipe_spawn(proc, args[0], args, merge_stderr, buffer_size, envs, -+ errbuf, &errbuf_size); -+ if (rc != NGX_OK) { -+ lua_pushnil(L); -+ lua_pushlstring(L, (char *)errbuf, errbuf_size); -+ rc = 2; -+ } else { -+ rc = 1; -+ } -+ -+free_mem: -+ if (args) -+ ngx_pfree(r->pool, args); -+ if (envs) -+ ngx_pfree(r->pool, envs); -+ return rc; -+} -+ -+static int ngx_http_lua_proc_pid(lua_State *L) -+{ -+ ngx_http_lua_ffi_pipe_proc_t *proc = lua_touserdata(L, 1); -+ -+ lua_pushinteger(L, proc->_pid); -+ return 1; -+} -+ -+static int ngx_http_lua_proc_wait(lua_State *L) -+{ -+ ngx_http_lua_ffi_pipe_proc_t *proc = lua_touserdata(L, 1); -+ ngx_http_request_t *r; -+ char *reason; -+ int status; -+ u_char errbuf[128] = ""; -+ size_t errbuf_size = sizeof(errbuf); -+ int rc; -+ -+ r = ngx_http_lua_get_req(L); -+ if (!r) -+ return luaL_error(L, "no request found"); -+ -+ rc = ngx_http_lua_ffi_pipe_proc_wait(r, proc, &reason, &status, errbuf, &errbuf_size); -+ switch (rc) { -+ case NGX_OK: -+ lua_pushboolean(L, 1); -+ lua_pushstring(L, reason); -+ lua_pushinteger(L, status); -+ return 3; -+ case NGX_DECLINED: -+ lua_pushboolean(L, 0); -+ lua_pushstring(L, reason); -+ lua_pushinteger(L, status); -+ return 3; -+ case NGX_ERROR: -+ lua_pushnil(L); -+ lua_pushlstring(L, (char *)errbuf, errbuf_size); -+ return 2; -+ default: -+ return lua_yield(L, 0); -+ } -+} -+ -+static int ngx_http_lua_proc_kill(lua_State *L) -+{ -+ ngx_http_lua_ffi_pipe_proc_t *proc = lua_touserdata(L, 1); -+ u_char errbuf[128] = ""; -+ size_t errbuf_size = sizeof(errbuf); -+ int signal; -+ int rc; -+ -+ signal = luaL_checkinteger(L, 2); -+ -+ rc = ngx_http_lua_ffi_pipe_proc_kill(proc, signal, errbuf, &errbuf_size); -+ if (rc == NGX_OK) { -+ lua_pushnil(L); -+ lua_pushlstring(L, (char *)errbuf, errbuf_size); -+ return 2; -+ } -+ -+ lua_pushboolean(L, 1); -+ return 1; -+} -+ -+static int ngx_http_lua_proc_read(lua_State *L, int from_stderr, int reader_type) -+{ -+ ngx_http_lua_ffi_pipe_proc_t *proc = lua_touserdata(L, 1); -+ ssize_t len = lua_tointeger(L, 2); -+ ngx_http_lua_pipe_ctx_t *pipe_ctx; -+ ngx_http_request_t *r; -+ u_char *buf, *p; -+ size_t buf_size = 4096; -+ u_char errbuf[128] = ""; -+ size_t errbuf_size = sizeof(errbuf); -+ int rc; -+ -+ switch (reader_type) { -+ case PIPE_READ_BYTES: -+ if (len <= 0) { -+ if (len < 0) -+ return luaL_error(L, "bad len argument"); -+ lua_pushliteral(L, ""); -+ return 1; -+ } -+ break; -+ case PIPE_READ_ANY: -+ if (len <= 0) -+ return luaL_error(L, "bad max argument"); -+ break; -+ default: -+ len = 0; -+ break; -+ } -+ -+ r = ngx_http_lua_get_req(L); -+ if (!r) -+ return luaL_error(L, "no request found"); -+ -+ buf = ngx_pcalloc(proc->pipe->pool, buf_size); -+ p = buf; -+ -+ if (!p) { -+ lua_pushnil(L); -+ lua_pushliteral(L, "no memory"); -+ return 2; -+ } -+ -+ rc = ngx_http_lua_ffi_pipe_proc_read(r, proc, from_stderr, reader_type, len, &p, -+ &buf_size, errbuf, -+ &errbuf_size); -+ if (rc == NGX_OK || rc == NGX_DECLINED) { -+ if (!p) { -+ if (from_stderr) -+ pipe_ctx = proc->pipe->stderr_ctx; -+ else -+ pipe_ctx = proc->pipe->stdout_ctx; -+ -+ ngx_pfree(proc->pipe->pool, buf); -+ -+ buf = ngx_pcalloc(proc->pipe->pool, buf_size); -+ if (!buf) { -+ lua_pushnil(L); -+ lua_pushliteral(L, "no memory"); -+ return 2; -+ } -+ ngx_http_lua_pipe_put_data(proc->pipe, pipe_ctx, &buf, &buf_size); -+ } -+ -+ if (rc == NGX_OK) { -+ lua_pushlstring(L, (char *)buf, buf_size); -+ ngx_pfree(proc->pipe->pool, buf); -+ return 1; -+ } -+ -+ lua_pushnil(L); -+ lua_pushlstring(L, (char *)errbuf, errbuf_size); -+ lua_pushlstring(L, (char *)buf, buf_size); -+ ngx_pfree(proc->pipe->pool, buf); -+ return 3; -+ } -+ -+ if (rc == NGX_ERROR) { -+ lua_pushnil(L); -+ lua_pushlstring(L, (char *)errbuf, errbuf_size); -+ ngx_pfree(proc->pipe->pool, buf); -+ return 2; -+ } -+ -+ ngx_pfree(proc->pipe->pool, buf); -+ -+ return lua_yield(L, 0); -+} -+ -+#define NGX_LUA_PIPE_DEF_READ_FUN(name, from_stderr, reader_type) \ -+ static int ngx_http_lua_proc_##name(lua_State *L) \ -+ { \ -+ return ngx_http_lua_proc_read(L, from_stderr, reader_type); \ -+ } -+ -+NGX_LUA_PIPE_DEF_READ_FUN(stdout_read_all, 0, PIPE_READ_ALL) -+NGX_LUA_PIPE_DEF_READ_FUN(stdout_read_bytes, 0, PIPE_READ_BYTES) -+NGX_LUA_PIPE_DEF_READ_FUN(stdout_read_line, 0, PIPE_READ_LINE) -+NGX_LUA_PIPE_DEF_READ_FUN(stdout_read_any, 0, PIPE_READ_ANY) -+ -+NGX_LUA_PIPE_DEF_READ_FUN(stderr_read_all, 1, PIPE_READ_ALL) -+NGX_LUA_PIPE_DEF_READ_FUN(stderr_read_bytes, 1, PIPE_READ_BYTES) -+NGX_LUA_PIPE_DEF_READ_FUN(stderr_read_line, 1, PIPE_READ_LINE) -+NGX_LUA_PIPE_DEF_READ_FUN(stderr_read_any, 1, PIPE_READ_ANY) -+ -+#define NGX_LUA_PIPE_ADD_FUN(name) \ -+ do { \ -+ lua_pushcfunction(L, ngx_http_lua_proc_##name); \ -+ lua_setfield(L, -2, #name); \ -+ } while (0) -+ -+void ngx_http_lua_inject_pipe_api(lua_State *L) -+{ -+ lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* ngx.pipe. */ -+ -+ lua_pushcfunction(L, ngx_http_lua_ngx_pipe_spawn); -+ lua_setfield(L, -2, "spawn"); -+ -+ lua_setfield(L, -2, "pipe"); -+ -+ /* {{{proc object metatable */ -+ lua_pushlightuserdata(L, &ngx_http_lua_proc_metatable_key); -+ -+ lua_createtable(L, 0 /* narr */, 2 /* nrec */); /* mt */ -+ -+ lua_createtable(L, 0 /* narr */, 11 /* nrec */); /* __index */ -+ -+ NGX_LUA_PIPE_ADD_FUN(pid); -+ NGX_LUA_PIPE_ADD_FUN(wait); -+ NGX_LUA_PIPE_ADD_FUN(kill); -+ NGX_LUA_PIPE_ADD_FUN(stdout_read_all); -+ NGX_LUA_PIPE_ADD_FUN(stdout_read_bytes); -+ NGX_LUA_PIPE_ADD_FUN(stdout_read_line); -+ NGX_LUA_PIPE_ADD_FUN(stdout_read_any); -+ NGX_LUA_PIPE_ADD_FUN(stderr_read_all); -+ NGX_LUA_PIPE_ADD_FUN(stderr_read_bytes); -+ NGX_LUA_PIPE_ADD_FUN(stderr_read_line); -+ NGX_LUA_PIPE_ADD_FUN(stderr_read_any); -+ -+ lua_setfield(L, -2, "__index"); -+ -+ lua_rawset(L, LUA_REGISTRYINDEX); -+ /* }}} */ -+} - - #endif /* HAVE_NGX_LUA_PIPE */ - -Index: nginx-1.17.7/lua-nginx/src/ngx_http_lua_pipe.h -=================================================================== ---- nginx-1.17.7.orig/lua-nginx/src/ngx_http_lua_pipe.h -+++ nginx-1.17.7/lua-nginx/src/ngx_http_lua_pipe.h -@@ -86,6 +86,7 @@ typedef struct { - - void ngx_http_lua_pipe_init(void); - ngx_int_t ngx_http_lua_pipe_add_signal_handler(ngx_cycle_t *cycle); -+void ngx_http_lua_inject_pipe_api(lua_State *L); - #endif - - diff --git a/nginx/patches/104-endianness_fix.patch b/nginx/patches/104-endianness_fix.patch new file mode 100644 index 000000000..4d8255e93 --- /dev/null +++ b/nginx/patches/104-endianness_fix.patch @@ -0,0 +1,19 @@ +--- a/auto/endianness ++++ b/auto/endianness +@@ -12,6 +12,16 @@ checking for system byte ordering + + END + ++if [ "${CONFIG_BIG_ENDIAN}" != "y" ]; then ++ echo " little endian" ++ have=NGX_HAVE_LITTLE_ENDIAN . auto/have ++else ++ echo " big endian" ++fi ++ ++return ++ ++ + + cat << END > $NGX_AUTOTEST.c + diff --git a/nginx/patches/201-ignore-invalid-options.patch b/nginx/patches/201-ignore-invalid-options.patch index 88b521353..d208bf507 100755 --- a/nginx/patches/201-ignore-invalid-options.patch +++ b/nginx/patches/201-ignore-invalid-options.patch @@ -1,6 +1,6 @@ --- a/auto/options +++ b/auto/options -@@ -396,8 +396,7 @@ $0: warning: the \"--with-sha1-asm\" opt +@@ -400,8 +400,7 @@ $0: warning: the \"--with-sha1-asm\" opt --test-build-solaris-sendfilev) NGX_TEST_BUILD_SOLARIS_SENDFILEV=YES ;; *) diff --git a/nginx/patches/300-max-processes.patch b/nginx/patches/300-max-processes.patch deleted file mode 100755 index f7465d434..000000000 --- a/nginx/patches/300-max-processes.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/src/os/unix/ngx_process.h -+++ b/src/os/unix/ngx_process.h -@@ -44,7 +44,7 @@ typedef struct { - } ngx_exec_ctx_t; - - --#define NGX_MAX_PROCESSES 1024 -+#define NGX_MAX_PROCESSES 8 - - #define NGX_PROCESS_NORESPAWN -1 - #define NGX_PROCESS_JUST_SPAWN -2 diff --git a/nginx/patches/400-socket-cloexec.patch b/nginx/patches/400-socket-cloexec.patch deleted file mode 100644 index 96e48b605..000000000 --- a/nginx/patches/400-socket-cloexec.patch +++ /dev/null @@ -1,174 +0,0 @@ -Index: nginx-1.17.7/auto/unix -=================================================================== ---- nginx-1.17.7.orig/auto/unix -+++ nginx-1.17.7/auto/unix -@@ -1037,3 +1037,27 @@ ngx_feature_test='struct addrinfo *res; - if (getaddrinfo("localhost", NULL, NULL, &res) != 0) return 1; - freeaddrinfo(res)' - . auto/feature -+ -+ngx_feature="SOCK_CLOEXEC support" -+ngx_feature_name="NGX_HAVE_SOCKET_CLOEXEC" -+ngx_feature_run=no -+ngx_feature_incs="#include -+ #include " -+ngx_feature_path= -+ngx_feature_libs= -+ngx_feature_test="int fd; -+ fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);" -+. auto/feature -+ -+ngx_feature="FD_CLOEXEC support" -+ngx_feature_name="NGX_HAVE_FD_CLOEXEC" -+ngx_feature_run=no -+ngx_feature_incs="#include -+ #include -+ #include " -+ngx_feature_path= -+ngx_feature_libs= -+ngx_feature_test="int fd; -+ fd = socket(AF_INET, SOCK_STREAM, 0); -+ fcntl(fd, F_SETFD, FD_CLOEXEC);" -+. auto/feature -Index: nginx-1.17.7/src/core/ngx_resolver.c -=================================================================== ---- nginx-1.17.7.orig/src/core/ngx_resolver.c -+++ nginx-1.17.7/src/core/ngx_resolver.c -@@ -4492,7 +4492,11 @@ ngx_tcp_connect(ngx_resolver_connection_ - ngx_event_t *rev, *wev; - ngx_connection_t *c; - -+#if (NGX_HAVE_SOCKET_CLOEXEC) -+ s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0); -+#else - s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM, 0); -+#endif - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &rec->log, 0, "TCP socket %d", s); - -@@ -4520,6 +4524,15 @@ ngx_tcp_connect(ngx_resolver_connection_ - goto failed; - } - -+#if (NGX_HAVE_FD_CLOEXEC) -+ if (ngx_cloexec(s) == -1) { -+ ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno, -+ ngx_cloexec_n " failed"); -+ -+ goto failed; -+ } -+#endif -+ - rev = c->read; - wev = c->write; - -Index: nginx-1.17.7/src/event/ngx_event.h -=================================================================== ---- nginx-1.17.7.orig/src/event/ngx_event.h -+++ nginx-1.17.7/src/event/ngx_event.h -@@ -73,6 +73,9 @@ struct ngx_event_s { - /* to test on worker exit */ - unsigned channel:1; - unsigned resolver:1; -+#if (HAVE_SOCKET_CLOEXEC_PATCH) -+ unsigned skip_socket_leak_check:1; -+#endif - - unsigned cancelable:1; - -Index: nginx-1.17.7/src/event/ngx_event_accept.c -=================================================================== ---- nginx-1.17.7.orig/src/event/ngx_event_accept.c -+++ nginx-1.17.7/src/event/ngx_event_accept.c -@@ -57,7 +57,7 @@ ngx_event_accept(ngx_event_t *ev) - - #if (NGX_HAVE_ACCEPT4) - if (use_accept4) { -- s = accept4(lc->fd, &sa.sockaddr, &socklen, SOCK_NONBLOCK); -+ s = accept4(lc->fd, &sa.sockaddr, &socklen, SOCK_NONBLOCK | SOCK_CLOEXEC); - } else { - s = accept(lc->fd, &sa.sockaddr, &socklen); - } -@@ -197,6 +197,14 @@ ngx_event_accept(ngx_event_t *ev) - ngx_close_accepted_connection(c); - return; - } -+#if (NGX_HAVE_FD_CLOEXEC) -+ if (ngx_cloexec(s) == -1) { -+ ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, -+ ngx_cloexec_n " failed"); -+ ngx_close_accepted_connection(c); -+ return; -+ } -+#endif - } - } - -Index: nginx-1.17.7/src/event/ngx_event_connect.c -=================================================================== ---- nginx-1.17.7.orig/src/event/ngx_event_connect.c -+++ nginx-1.17.7/src/event/ngx_event_connect.c -@@ -38,7 +38,11 @@ ngx_event_connect_peer(ngx_peer_connecti - - type = (pc->type ? pc->type : SOCK_STREAM); - -+#if (NGX_HAVE_SOCKET_CLOEXEC) -+ s = ngx_socket(pc->sockaddr->sa_family, type | SOCK_CLOEXEC, 0); -+#else - s = ngx_socket(pc->sockaddr->sa_family, type, 0); -+#endif - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pc->log, 0, "%s socket %d", - (type == SOCK_STREAM) ? "stream" : "dgram", s); -@@ -92,6 +96,15 @@ ngx_event_connect_peer(ngx_peer_connecti - goto failed; - } - -+#if (NGX_HAVE_FD_CLOEXEC) -+ if (ngx_cloexec(s) == -1) { -+ ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, -+ ngx_cloexec_n " failed"); -+ -+ goto failed; -+ } -+#endif -+ - if (pc->local) { - - #if (NGX_HAVE_TRANSPARENT_PROXY) -Index: nginx-1.17.7/src/os/unix/ngx_process_cycle.c -=================================================================== ---- nginx-1.17.7.orig/src/os/unix/ngx_process_cycle.c -+++ nginx-1.17.7/src/os/unix/ngx_process_cycle.c -@@ -991,6 +991,9 @@ ngx_worker_process_exit(ngx_cycle_t *cyc - for (i = 0; i < cycle->connection_n; i++) { - if (c[i].fd != -1 - && c[i].read -+#if (HAVE_SOCKET_CLOEXEC_PATCH) -+ && !c[i].read->skip_socket_leak_check -+#endif - && !c[i].read->accept - && !c[i].read->channel - && !c[i].read->resolver) -Index: nginx-1.17.7/src/os/unix/ngx_socket.h -=================================================================== ---- nginx-1.17.7.orig/src/os/unix/ngx_socket.h -+++ nginx-1.17.7/src/os/unix/ngx_socket.h -@@ -45,6 +45,17 @@ int ngx_blocking(ngx_socket_t s); - - #endif - -+#if (NGX_HAVE_FD_CLOEXEC) -+ -+#define ngx_cloexec(s) fcntl(s, F_SETFD, FD_CLOEXEC) -+#define ngx_cloexec_n "fcntl(FD_CLOEXEC)" -+ -+/* at least FD_CLOEXEC is required to ensure connection fd is closed -+ * after execve */ -+#define HAVE_SOCKET_CLOEXEC_PATCH 1 -+ -+#endif -+ - int ngx_tcp_nopush(ngx_socket_t s); - int ngx_tcp_push(ngx_socket_t s); - diff --git a/nginx/src/lua-nginx/src/ngx_http_lua_pipe.c b/nginx/src/lua-nginx/src/ngx_http_lua_pipe.c deleted file mode 100644 index 9ea0ba1c4..000000000 --- a/nginx/src/lua-nginx/src/ngx_http_lua_pipe.c +++ /dev/null @@ -1,2499 +0,0 @@ - -/* - * Copyright (C) by OpenResty Inc. - */ - - -#ifndef DDEBUG -#define DDEBUG 0 -#endif -#include "ddebug.h" - - -#include "ngx_http_lua_common.h" -#include "ngx_http_lua_input_filters.h" -#include "ngx_http_lua_util.h" -#include "ngx_http_lua_pipe.h" -#if (NGX_HTTP_LUA_HAVE_SIGNALFD) -#include -#endif - - -#ifdef HAVE_NGX_LUA_PIPE -static ngx_rbtree_node_t *ngx_http_lua_pipe_lookup_pid(ngx_rbtree_key_t key); -#if !(NGX_HTTP_LUA_HAVE_SIGNALFD) -static void ngx_http_lua_pipe_sigchld_handler(int signo, siginfo_t *siginfo, - void *ucontext); -#endif -static void ngx_http_lua_pipe_sigchld_event_handler(ngx_event_t *ev); -static ssize_t ngx_http_lua_pipe_fd_read(ngx_connection_t *c, u_char *buf, - size_t size); -static ssize_t ngx_http_lua_pipe_fd_write(ngx_connection_t *c, u_char *buf, - size_t size); -static void ngx_http_lua_pipe_close_helper(ngx_http_lua_pipe_t *pipe, - ngx_http_lua_pipe_ctx_t *pipe_ctx, ngx_event_t *ev); -static void ngx_http_lua_pipe_close_stdin(ngx_http_lua_pipe_t *pipe); -static void ngx_http_lua_pipe_close_stdout(ngx_http_lua_pipe_t *pipe); -static void ngx_http_lua_pipe_close_stderr(ngx_http_lua_pipe_t *pipe); -static void ngx_http_lua_pipe_proc_finalize(ngx_http_lua_ffi_pipe_proc_t *proc); -static ngx_int_t ngx_http_lua_pipe_get_lua_ctx(ngx_http_request_t *r, - ngx_http_lua_ctx_t **ctx, u_char *errbuf, size_t *errbuf_size); -static void ngx_http_lua_pipe_put_error(ngx_http_lua_pipe_ctx_t *pipe_ctx, - u_char *errbuf, size_t *errbuf_size); -static void ngx_http_lua_pipe_put_data(ngx_http_lua_pipe_t *pipe, - ngx_http_lua_pipe_ctx_t *pipe_ctx, u_char **buf, size_t *buf_size); -static ngx_int_t ngx_http_lua_pipe_add_input_buffer(ngx_http_lua_pipe_t *pipe, - ngx_http_lua_pipe_ctx_t *pipe_ctx); -static ngx_int_t ngx_http_lua_pipe_read_all(void *data, ssize_t bytes); -static ngx_int_t ngx_http_lua_pipe_read_bytes(void *data, ssize_t bytes); -static ngx_int_t ngx_http_lua_pipe_read_line(void *data, ssize_t bytes); -static ngx_int_t ngx_http_lua_pipe_read_any(void *data, ssize_t bytes); -static ngx_int_t ngx_http_lua_pipe_read(ngx_http_lua_pipe_t *pipe, - ngx_http_lua_pipe_ctx_t *pipe_ctx); -static ngx_int_t ngx_http_lua_pipe_init_ctx( - ngx_http_lua_pipe_ctx_t **pipe_ctx_pt, int fd, ngx_pool_t *pool, - u_char *errbuf, size_t *errbuf_size); -static ngx_int_t ngx_http_lua_pipe_write(ngx_http_lua_pipe_t *pipe, - ngx_http_lua_pipe_ctx_t *pipe_ctx); -static int ngx_http_lua_pipe_read_stdout_retval( - ngx_http_lua_ffi_pipe_proc_t *proc, lua_State *L); -static int ngx_http_lua_pipe_read_stderr_retval( - ngx_http_lua_ffi_pipe_proc_t *proc, lua_State *L); -static int ngx_http_lua_pipe_read_retval_helper( - ngx_http_lua_ffi_pipe_proc_t *proc, lua_State *L, int from_stderr); -static int ngx_http_lua_pipe_write_retval(ngx_http_lua_ffi_pipe_proc_t *proc, - lua_State *L); -static int ngx_http_lua_pipe_wait_retval(ngx_http_lua_ffi_pipe_proc_t *proc, - lua_State *L); -static void ngx_http_lua_pipe_resume_helper(ngx_event_t *ev, - ngx_http_lua_co_ctx_t *wait_co_ctx); -static void ngx_http_lua_pipe_resume_read_stdout_handler(ngx_event_t *ev); -static void ngx_http_lua_pipe_resume_read_stderr_handler(ngx_event_t *ev); -static void ngx_http_lua_pipe_resume_write_handler(ngx_event_t *ev); -static void ngx_http_lua_pipe_resume_wait_handler(ngx_event_t *ev); -static ngx_int_t ngx_http_lua_pipe_resume(ngx_http_request_t *r); -static void ngx_http_lua_pipe_dummy_event_handler(ngx_event_t *ev); -static void ngx_http_lua_pipe_clear_event(ngx_event_t *ev); -static void ngx_http_lua_pipe_proc_read_stdout_cleanup(void *data); -static void ngx_http_lua_pipe_proc_read_stderr_cleanup(void *data); -static void ngx_http_lua_pipe_proc_write_cleanup(void *data); -static void ngx_http_lua_pipe_proc_wait_cleanup(void *data); - - -static ngx_rbtree_t ngx_http_lua_pipe_rbtree; -static ngx_rbtree_node_t ngx_http_lua_pipe_proc_sentinel; - - -#if (NGX_HTTP_LUA_HAVE_SIGNALFD) -static int ngx_http_lua_signalfd; -static struct signalfd_siginfo ngx_http_lua_pipe_notification; - -#define ngx_http_lua_read_sigfd ngx_http_lua_signalfd - -#else -static int ngx_http_lua_sigchldfd[2]; -static u_char ngx_http_lua_pipe_notification[1]; - -#define ngx_http_lua_read_sigfd ngx_http_lua_sigchldfd[0] -#define ngx_http_lua_write_sigfd ngx_http_lua_sigchldfd[1] -#endif - - -static ngx_connection_t *ngx_http_lua_sigfd_conn = NULL; - - -/* The below signals are ignored by Nginx. - * We need to reset them for the spawned child processes. */ -ngx_http_lua_pipe_signal_t ngx_signals[] = { - { SIGSYS, "SIGSYS" }, - { SIGPIPE, "SIGPIPE" }, - { 0, NULL } -}; - - -enum { - PIPE_ERR_CLOSED = 1, - PIPE_ERR_SYSCALL, - PIPE_ERR_NOMEM, - PIPE_ERR_TIMEOUT, - PIPE_ERR_ADD_READ_EV, - PIPE_ERR_ADD_WRITE_EV, - PIPE_ERR_ABORTED, -}; - - -enum { - PIPE_READ_ALL = 0, - PIPE_READ_BYTES, - PIPE_READ_LINE, - PIPE_READ_ANY, -}; - - -#define REASON_EXIT "exit" -#define REASON_SIGNAL "signal" -#define REASON_UNKNOWN "unknown" - -#define REASON_RUNNING_CODE 0 -#define REASON_EXIT_CODE 1 -#define REASON_SIGNAL_CODE 2 -#define REASON_UNKNOWN_CODE 3 - - -void -ngx_http_lua_pipe_init(void) -{ - ngx_rbtree_init(&ngx_http_lua_pipe_rbtree, - &ngx_http_lua_pipe_proc_sentinel, ngx_rbtree_insert_value); -} - - -ngx_int_t -ngx_http_lua_pipe_add_signal_handler(ngx_cycle_t *cycle) -{ - ngx_event_t *rev; -#if (NGX_HTTP_LUA_HAVE_SIGNALFD) - sigset_t set; - -#else - int rc; - struct sigaction sa; -#endif - -#if (NGX_HTTP_LUA_HAVE_SIGNALFD) - if (sigemptyset(&set) != 0) { - ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, - "lua pipe init signal set failed"); - return NGX_ERROR; - } - - if (sigaddset(&set, SIGCHLD) != 0) { - ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, - "lua pipe add SIGCHLD to signal set failed"); - return NGX_ERROR; - } - - if (sigprocmask(SIG_BLOCK, &set, NULL) != 0) { - ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, - "lua pipe block SIGCHLD failed"); - return NGX_ERROR; - } - - ngx_http_lua_signalfd = signalfd(-1, &set, SFD_NONBLOCK|SFD_CLOEXEC); - if (ngx_http_lua_signalfd < 0) { - ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, - "lua pipe create signalfd instance failed"); - return NGX_ERROR; - } - -#else /* !(NGX_HTTP_LUA_HAVE_SIGNALFD) */ -# if (NGX_HTTP_LUA_HAVE_PIPE2) - rc = pipe2(ngx_http_lua_sigchldfd, O_NONBLOCK|O_CLOEXEC); -# else - rc = pipe(ngx_http_lua_sigchldfd); -# endif - - if (rc == -1) { - ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, - "lua pipe init SIGCHLD fd failed"); - return NGX_ERROR; - } - -# if !(NGX_HTTP_LUA_HAVE_PIPE2) - if (ngx_nonblocking(ngx_http_lua_read_sigfd) == -1) { - ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, "lua pipe " - ngx_nonblocking_n " SIGCHLD read fd failed"); - goto failed; - } - - if (ngx_nonblocking(ngx_http_lua_write_sigfd) == -1) { - ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, "lua pipe " - ngx_nonblocking_n " SIGCHLD write fd failed"); - goto failed; - } - - /* it's ok not to set the pipe fd with O_CLOEXEC. This requires - * extra syscall */ -# endif /* !(NGX_HTTP_LUA_HAVE_PIPE2) */ -#endif /* NGX_HTTP_LUA_HAVE_SIGNALFD */ - - ngx_http_lua_sigfd_conn = ngx_get_connection(ngx_http_lua_read_sigfd, - cycle->log); - if (ngx_http_lua_sigfd_conn == NULL) { - goto failed; - } - - ngx_http_lua_sigfd_conn->log = cycle->log; - ngx_http_lua_sigfd_conn->recv = ngx_http_lua_pipe_fd_read; - rev = ngx_http_lua_sigfd_conn->read; - rev->log = ngx_http_lua_sigfd_conn->log; - rev->handler = ngx_http_lua_pipe_sigchld_event_handler; - -#ifdef HAVE_SOCKET_CLOEXEC_PATCH - rev->skip_socket_leak_check = 1; -#endif - - if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { - goto failed; - } - -#if !(NGX_HTTP_LUA_HAVE_SIGNALFD) - ngx_memzero(&sa, sizeof(struct sigaction)); - sa.sa_sigaction = ngx_http_lua_pipe_sigchld_handler; - sa.sa_flags = SA_SIGINFO; - - if (sigemptyset(&sa.sa_mask) != 0) { - ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, - "lua pipe init signal mask failed"); - goto failed; - } - - if (sigaction(SIGCHLD, &sa, NULL) == -1) { - ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, - "lua pipe sigaction(SIGCHLD) failed"); - goto failed; - } -#endif - - return NGX_OK; - -failed: - - if (ngx_http_lua_sigfd_conn != NULL) { - ngx_close_connection(ngx_http_lua_sigfd_conn); - ngx_http_lua_sigfd_conn = NULL; - } - - if (close(ngx_http_lua_read_sigfd) == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - "lua pipe close the read sigfd failed"); - } - -#if !(NGX_HTTP_LUA_HAVE_SIGNALFD) - if (close(ngx_http_lua_write_sigfd) == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - "lua pipe close the write sigfd failed"); - } -#endif - - return NGX_ERROR; -} - - -static ngx_rbtree_node_t * -ngx_http_lua_pipe_lookup_pid(ngx_rbtree_key_t key) -{ - ngx_rbtree_node_t *node, *sentinel; - - node = ngx_http_lua_pipe_rbtree.root; - sentinel = ngx_http_lua_pipe_rbtree.sentinel; - - while (node != sentinel) { - if (key < node->key) { - node = node->left; - continue; - } - - if (key > node->key) { - node = node->right; - continue; - } - - return node; - } - - return NULL; -} - - -#if !(NGX_HTTP_LUA_HAVE_SIGNALFD) -static void -ngx_http_lua_pipe_sigchld_handler(int signo, siginfo_t *siginfo, - void *ucontext) -{ - ngx_err_t err, saved_err; - ngx_int_t n; - - saved_err = ngx_errno; - - for ( ;; ) { - n = write(ngx_http_lua_write_sigfd, ngx_http_lua_pipe_notification, - sizeof(ngx_http_lua_pipe_notification)); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, - "lua pipe SIGCHLD fd write siginfo:%p", siginfo); - - if (n >= 0) { - break; - } - - err = ngx_errno; - - if (err != NGX_EINTR) { - if (err != NGX_EAGAIN) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, err, - "lua pipe SIGCHLD fd write failed"); - } - - break; - } - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, err, - "lua pipe SIGCHLD fd write was interrupted"); - } - - ngx_set_errno(saved_err); -} -#endif - - -static void -ngx_http_lua_pipe_sigchld_event_handler(ngx_event_t *ev) -{ - int n; - int status; - ngx_pid_t pid; - ngx_connection_t *c = ev->data; - ngx_rbtree_node_t *node; - ngx_http_lua_pipe_node_t *pipe_node; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, - "lua pipe reaping children"); - - for ( ;; ) { -#if (NGX_HTTP_LUA_HAVE_SIGNALFD) - n = c->recv(c, (u_char *) &ngx_http_lua_pipe_notification, -#else - n = c->recv(c, ngx_http_lua_pipe_notification, -#endif - sizeof(ngx_http_lua_pipe_notification)); - - if (n <= 0) { - if (n == NGX_ERROR) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe SIGCHLD fd read failed"); - } - - break; - } - - for ( ;; ) { - pid = waitpid(-1, &status, WNOHANG); - - if (pid == 0) { - break; - } - - if (pid < 0) { - if (ngx_errno != NGX_ECHILD) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe waitpid failed"); - } - - break; - } - - /* This log is ported from Nginx's signal handler since we override - * or block it in this implementation. */ - ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, - "signal %d (SIGCHLD) received from %P", - SIGCHLD, pid); - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe SIGCHLD fd read pid:%P status:%d", pid, - status); - - node = ngx_http_lua_pipe_lookup_pid(pid); - if (node != NULL) { - pipe_node = (ngx_http_lua_pipe_node_t *) &node->color; - if (pipe_node->wait_co_ctx != NULL) { - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe resume process:%p waiting for %P", - pipe_node->proc, pid); - - /* - * We need the extra parentheses around the first argument - * of ngx_post_event() just to work around macro issues in - * nginx cores older than 1.7.12 (exclusive). - */ - ngx_post_event((&pipe_node->wait_co_ctx->sleep), - &ngx_posted_events); - } - - pipe_node->proc->pipe->dead = 1; - - if (WIFSIGNALED(status)) { - pipe_node->status = WTERMSIG(status); - pipe_node->reason_code = REASON_SIGNAL_CODE; - - } else if (WIFEXITED(status)) { - pipe_node->status = WEXITSTATUS(status); - pipe_node->reason_code = REASON_EXIT_CODE; - - } else { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, - "lua pipe unknown exit status %d from " - "process %P", status, pid); - pipe_node->status = status; - pipe_node->reason_code = REASON_UNKNOWN_CODE; - } - } - } - } -} - - -static ssize_t -ngx_http_lua_pipe_fd_read(ngx_connection_t *c, u_char *buf, size_t size) -{ - ssize_t n; - ngx_err_t err; - ngx_event_t *rev; - - rev = c->read; - - do { - n = read(c->fd, buf, size); - - err = ngx_errno; - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "read: fd:%d %z of %uz", c->fd, n, size); - - if (n == 0) { - rev->ready = 0; - rev->eof = 1; - return 0; - } - - if (n > 0) { - if ((size_t) n < size - && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) - { - rev->ready = 0; - } - - return n; - } - - if (err == NGX_EAGAIN || err == NGX_EINTR) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, - "read() not ready"); - n = NGX_AGAIN; - - } else { - n = ngx_connection_error(c, err, "read() failed"); - break; - } - - } while (err == NGX_EINTR); - - rev->ready = 0; - - if (n == NGX_ERROR) { - rev->error = 1; - } - - return n; -} - - -static ssize_t -ngx_http_lua_pipe_fd_write(ngx_connection_t *c, u_char *buf, size_t size) -{ - ssize_t n; - ngx_err_t err; - ngx_event_t *wev; - - wev = c->write; - - do { - n = write(c->fd, buf, size); - - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "write: fd:%d %z of %uz", c->fd, n, size); - - if (n >= 0) { - if ((size_t) n != size) { - wev->ready = 0; - } - - return n; - } - - err = ngx_errno; - - if (err == NGX_EAGAIN || err == NGX_EINTR) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, - "write() not ready"); - n = NGX_AGAIN; - - } else if (err != NGX_EPIPE) { - n = ngx_connection_error(c, err, "write() failed"); - break; - } - - } while (err == NGX_EINTR); - - wev->ready = 0; - - if (n == NGX_ERROR) { - wev->error = 1; - } - - return n; -} - - -#if !(NGX_HTTP_LUA_HAVE_EXECVPE) -static int -ngx_http_lua_execvpe(const char *program, char * const argv[], - char * const envp[]) -{ - int rc; - char **saved = environ; - - environ = (char **) envp; - rc = execvp(program, argv); - environ = saved; - return rc; -} -#endif - - -int -ngx_http_lua_ffi_pipe_spawn(ngx_http_lua_ffi_pipe_proc_t *proc, - const char *file, const char **argv, int merge_stderr, size_t buffer_size, - const char **environ, u_char *errbuf, size_t *errbuf_size) -{ - int rc; - int in[2]; - int out[2]; - int err[2]; - int stdin_fd, stdout_fd, stderr_fd; - int errlog_fd, temp_errlog_fd; - ngx_pid_t pid; - ssize_t pool_size; - ngx_pool_t *pool; - ngx_uint_t i; - ngx_listening_t *ls; - ngx_http_lua_pipe_t *pp; - ngx_rbtree_node_t *node; - ngx_http_lua_pipe_node_t *pipe_node; - struct sigaction sa; - ngx_http_lua_pipe_signal_t *sig; - sigset_t set; - - pool_size = ngx_align(NGX_MIN_POOL_SIZE + buffer_size * 2, - NGX_POOL_ALIGNMENT); - - pool = ngx_create_pool(pool_size, ngx_cycle->log); - if (pool == NULL) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "no memory") - - errbuf; - return NGX_ERROR; - } - - pp = ngx_pcalloc(pool, sizeof(ngx_http_lua_pipe_t) - + offsetof(ngx_rbtree_node_t, color) - + sizeof(ngx_http_lua_pipe_node_t)); - if (pp == NULL) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "no memory") - - errbuf; - goto free_pool; - } - - rc = pipe(in); - if (rc == -1) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "pipe failed: %s", - strerror(errno)) - - errbuf; - goto free_pool; - } - - rc = pipe(out); - if (rc == -1) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "pipe failed: %s", - strerror(errno)) - - errbuf; - goto close_in_fd; - } - - if (!merge_stderr) { - rc = pipe(err); - if (rc == -1) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, - "pipe failed: %s", strerror(errno)) - - errbuf; - goto close_in_out_fd; - } - } - - pid = fork(); - if (pid == -1) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "fork failed: %s", - strerror(errno)) - - errbuf; - goto close_in_out_err_fd; - } - - if (pid == 0) { - -#if (NGX_HAVE_CPU_AFFINITY) - /* reset the CPU affinity mask */ - ngx_uint_t log_level; - ngx_cpuset_t child_cpu_affinity; - - if (ngx_process == NGX_PROCESS_WORKER - && ngx_get_cpu_affinity(ngx_worker) != NULL) - { - CPU_ZERO(&child_cpu_affinity); - - for (i = 0; i < (ngx_uint_t) ngx_min(ngx_ncpu, CPU_SETSIZE); i++) { - CPU_SET(i, &child_cpu_affinity); - } - - log_level = ngx_cycle->log->log_level; - ngx_cycle->log->log_level = NGX_LOG_WARN; - ngx_setaffinity(&child_cpu_affinity, ngx_cycle->log); - ngx_cycle->log->log_level = log_level; - } -#endif - - /* reset the handler of ignored signals to the default */ - for (sig = ngx_signals; sig->signo != 0; sig++) { - ngx_memzero(&sa, sizeof(struct sigaction)); - sa.sa_handler = SIG_DFL; - - if (sigemptyset(&sa.sa_mask) != 0) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe child init signal mask failed"); - exit(EXIT_FAILURE); - } - - if (sigaction(sig->signo, &sa, NULL) == -1) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe child reset signal handler for %s " - "failed", sig->signame); - exit(EXIT_FAILURE); - } - } - - /* reset signal mask */ - if (sigemptyset(&set) != 0) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe child init signal set failed"); - exit(EXIT_FAILURE); - } - - if (sigprocmask(SIG_SETMASK, &set, NULL) != 0) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe child reset signal mask failed"); - exit(EXIT_FAILURE); - } - - /* close listening socket fd */ - ls = ngx_cycle->listening.elts; - for (i = 0; i < ngx_cycle->listening.nelts; i++) { - if (ls[i].fd != (ngx_socket_t) -1 && - ngx_close_socket(ls[i].fd) == -1) - { - ngx_log_error(NGX_LOG_WARN, ngx_cycle->log, ngx_socket_errno, - "lua pipe child " ngx_close_socket_n - " %V failed", &ls[i].addr_text); - } - } - - /* close and dup pipefd */ - if (close(in[1]) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "lua pipe child failed to close the in[1] " - "pipe fd"); - } - - if (close(out[0]) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "lua pipe child failed to close the out[0] " - "pipe fd"); - } - - if (ngx_cycle->log->file && ngx_cycle->log->file->fd == STDERR_FILENO) { - errlog_fd = ngx_cycle->log->file->fd; - temp_errlog_fd = dup(errlog_fd); - - if (temp_errlog_fd == -1) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe child dup errlog fd failed"); - exit(EXIT_FAILURE); - } - - if (ngx_cloexec(temp_errlog_fd) == -1) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe child new errlog fd " ngx_cloexec_n - " failed"); - } - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe child dup old errlog fd %d to new fd %d", - ngx_cycle->log->file->fd, temp_errlog_fd); - - ngx_cycle->log->file->fd = temp_errlog_fd; - } - - if (dup2(in[0], STDIN_FILENO) == -1) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe child dup2 stdin failed"); - exit(EXIT_FAILURE); - } - - if (dup2(out[1], STDOUT_FILENO) == -1) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe child dup2 stdout failed"); - exit(EXIT_FAILURE); - } - - if (merge_stderr) { - if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe child dup2 stderr failed"); - exit(EXIT_FAILURE); - } - - } else { - if (close(err[0]) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "lua pipe child failed to close the err[0] " - "pipe fd"); - } - - if (dup2(err[1], STDERR_FILENO) == -1) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe child dup2 stderr failed"); - exit(EXIT_FAILURE); - } - } - - if (environ != NULL) { -#if (NGX_HTTP_LUA_HAVE_EXECVPE) - if (execvpe(file, (char * const *) argv, (char * const *) environ) -#else - if (ngx_http_lua_execvpe(file, (char * const *) argv, - (char * const *) environ) -#endif - == -1) - { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe child execvpe() failed while " - "executing %s", file); - } - - } else { - if (execvp(file, (char * const *) argv) == -1) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe child execvp() failed while " - "executing %s", file); - } - } - - exit(EXIT_FAILURE); - } - - /* parent process */ - if (close(in[0]) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "lua pipe: failed to close the in[0] pipe fd"); - } - - stdin_fd = in[1]; - - if (ngx_nonblocking(stdin_fd) == -1) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, - ngx_nonblocking_n " failed: %s", - strerror(errno)) - - errbuf; - goto close_in_out_err_fd; - } - - pp->stdin_fd = stdin_fd; - - if (close(out[1]) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "lua pipe: failed to close the out[1] pipe fd"); - } - - stdout_fd = out[0]; - - if (ngx_nonblocking(stdout_fd) == -1) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, - ngx_nonblocking_n " failed: %s", - strerror(errno)) - - errbuf; - goto close_in_out_err_fd; - } - - pp->stdout_fd = stdout_fd; - - if (!merge_stderr) { - if (close(err[1]) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "lua pipe: failed to close the err[1] pipe fd"); - } - - stderr_fd = err[0]; - - if (ngx_nonblocking(stderr_fd) == -1) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, - ngx_nonblocking_n " failed: %s", - strerror(errno)) - - errbuf; - goto close_in_out_err_fd; - } - - pp->stderr_fd = stderr_fd; - } - - node = (ngx_rbtree_node_t *) (pp + 1); - node->key = pid; - pipe_node = (ngx_http_lua_pipe_node_t *) &node->color; - pipe_node->proc = proc; - ngx_rbtree_insert(&ngx_http_lua_pipe_rbtree, node); - - pp->node = node; - pp->pool = pool; - pp->merge_stderr = merge_stderr; - pp->buffer_size = buffer_size; - - proc->_pid = pid; - proc->pipe = pp; - - ngx_log_debug4(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe spawn process:%p pid:%P merge_stderr:%d " - "buffer_size:%uz", proc, pid, merge_stderr, buffer_size); - return NGX_OK; - -close_in_out_err_fd: - - if (!merge_stderr) { - if (close(err[0]) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "failed to close the err[0] pipe fd"); - } - - if (close(err[1]) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "failed to close the err[1] pipe fd"); - } - } - -close_in_out_fd: - - if (close(out[0]) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "failed to close the out[0] pipe fd"); - } - - if (close(out[1]) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "failed to close the out[1] pipe fd"); - } - -close_in_fd: - - if (close(in[0]) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "failed to close the in[0] pipe fd"); - } - - if (close(in[1]) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "failed to close the in[1] pipe fd"); - } - -free_pool: - - ngx_destroy_pool(pool); - return NGX_ERROR; -} - - -static void -ngx_http_lua_pipe_close_helper(ngx_http_lua_pipe_t *pipe, - ngx_http_lua_pipe_ctx_t *pipe_ctx, ngx_event_t *ev) -{ - if (ev->handler != ngx_http_lua_pipe_dummy_event_handler) { - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe abort blocking operation pipe_ctx:%p ev:%p", - pipe_ctx, ev); - - if (pipe->dead) { - pipe_ctx->err_type = PIPE_ERR_CLOSED; - - } else { - pipe_ctx->err_type = PIPE_ERR_ABORTED; - } - - ngx_post_event(ev, &ngx_posted_events); - return; - } - - ngx_close_connection(pipe_ctx->c); - pipe_ctx->c = NULL; -} - - -static void -ngx_http_lua_pipe_close_stdin(ngx_http_lua_pipe_t *pipe) -{ - ngx_event_t *wev; - - if (pipe->stdin_ctx == NULL) { - if (pipe->stdin_fd != -1) { - if (close(pipe->stdin_fd) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "failed to close the stdin pipe fd"); - } - - pipe->stdin_fd = -1; - } - - } else if (pipe->stdin_ctx->c != NULL) { - wev = pipe->stdin_ctx->c->write; - ngx_http_lua_pipe_close_helper(pipe, pipe->stdin_ctx, wev); - } -} - - -static void -ngx_http_lua_pipe_close_stdout(ngx_http_lua_pipe_t *pipe) -{ - ngx_event_t *rev; - - if (pipe->stdout_ctx == NULL) { - if (pipe->stdout_fd != -1) { - if (close(pipe->stdout_fd) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "failed to close the stdout pipe fd"); - } - - pipe->stdout_fd = -1; - } - - } else if (pipe->stdout_ctx->c != NULL) { - rev = pipe->stdout_ctx->c->read; - ngx_http_lua_pipe_close_helper(pipe, pipe->stdout_ctx, rev); - } -} - - -static void -ngx_http_lua_pipe_close_stderr(ngx_http_lua_pipe_t *pipe) -{ - ngx_event_t *rev; - - if (pipe->stderr_ctx == NULL) { - if (pipe->stderr_fd != -1) { - if (close(pipe->stderr_fd) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, - "failed to close the stderr pipe fd"); - } - - pipe->stderr_fd = -1; - } - - } else if (pipe->stderr_ctx->c != NULL) { - rev = pipe->stderr_ctx->c->read; - ngx_http_lua_pipe_close_helper(pipe, pipe->stderr_ctx, rev); - } -} - - -int -ngx_http_lua_ffi_pipe_proc_shutdown_stdin(ngx_http_lua_ffi_pipe_proc_t *proc, - u_char *errbuf, size_t *errbuf_size) -{ - ngx_http_lua_pipe_t *pipe; - - pipe = proc->pipe; - if (pipe == NULL || pipe->closed) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "closed") - errbuf; - return NGX_ERROR; - } - - ngx_http_lua_pipe_close_stdin(pipe); - - return NGX_OK; -} - - -int -ngx_http_lua_ffi_pipe_proc_shutdown_stdout(ngx_http_lua_ffi_pipe_proc_t *proc, - u_char *errbuf, size_t *errbuf_size) -{ - ngx_http_lua_pipe_t *pipe; - - pipe = proc->pipe; - if (pipe == NULL || pipe->closed) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "closed") - errbuf; - return NGX_ERROR; - } - - ngx_http_lua_pipe_close_stdout(pipe); - - return NGX_OK; -} - - -int -ngx_http_lua_ffi_pipe_proc_shutdown_stderr(ngx_http_lua_ffi_pipe_proc_t *proc, - u_char *errbuf, size_t *errbuf_size) -{ - ngx_http_lua_pipe_t *pipe; - - pipe = proc->pipe; - if (pipe == NULL || pipe->closed) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "closed") - errbuf; - return NGX_ERROR; - } - - if (pipe->merge_stderr) { - /* stdout is used internally as stderr when merge_stderr is true */ - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "merged to stdout") - - errbuf; - return NGX_ERROR; - } - - ngx_http_lua_pipe_close_stderr(pipe); - - return NGX_OK; -} - - -static void -ngx_http_lua_pipe_proc_finalize(ngx_http_lua_ffi_pipe_proc_t *proc) -{ - ngx_http_lua_pipe_t *pipe; - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe finalize process:%p pid:%P", - proc, proc->_pid); - pipe = proc->pipe; - - if (pipe->node) { - ngx_rbtree_delete(&ngx_http_lua_pipe_rbtree, pipe->node); - pipe->node = NULL; - } - - pipe->dead = 1; - - ngx_http_lua_pipe_close_stdin(pipe); - ngx_http_lua_pipe_close_stdout(pipe); - - if (!pipe->merge_stderr) { - ngx_http_lua_pipe_close_stderr(pipe); - } - - pipe->closed = 1; -} - - -void -ngx_http_lua_ffi_pipe_proc_destroy(ngx_http_lua_ffi_pipe_proc_t *proc) -{ - ngx_http_lua_pipe_t *pipe; - - pipe = proc->pipe; - if (pipe == NULL) { - return; - } - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe destroy process:%p pid:%P", proc, proc->_pid); - - if (!pipe->dead) { - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe kill process:%p pid:%P", proc, proc->_pid); - - if (kill(proc->_pid, SIGKILL) == -1) { - if (ngx_errno != ESRCH) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe failed to kill process:%p pid:%P", - proc, proc->_pid); - } - } - } - - ngx_http_lua_pipe_proc_finalize(proc); - ngx_destroy_pool(pipe->pool); - proc->pipe = NULL; -} - - -static ngx_int_t -ngx_http_lua_pipe_get_lua_ctx(ngx_http_request_t *r, - ngx_http_lua_ctx_t **ctx, u_char *errbuf, size_t *errbuf_size) -{ - int rc; - - *ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); - if (ctx == NULL) { - return NGX_HTTP_LUA_FFI_NO_REQ_CTX; - } - - rc = ngx_http_lua_ffi_check_context(*ctx, NGX_HTTP_LUA_CONTEXT_YIELDABLE, - errbuf, errbuf_size); - if (rc != NGX_OK) { - return NGX_HTTP_LUA_FFI_BAD_CONTEXT; - } - - return NGX_OK; -} - - -static void -ngx_http_lua_pipe_put_error(ngx_http_lua_pipe_ctx_t *pipe_ctx, u_char *errbuf, - size_t *errbuf_size) -{ - switch (pipe_ctx->err_type) { - - case PIPE_ERR_CLOSED: - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "closed") - errbuf; - break; - - case PIPE_ERR_SYSCALL: - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "%s", - strerror(pipe_ctx->pipe_errno)) - - errbuf; - break; - - case PIPE_ERR_NOMEM: - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "no memory") - - errbuf; - break; - - case PIPE_ERR_TIMEOUT: - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "timeout") - - errbuf; - break; - - case PIPE_ERR_ADD_READ_EV: - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, - "failed to add read event") - - errbuf; - break; - - case PIPE_ERR_ADD_WRITE_EV: - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, - "failed to add write event") - - errbuf; - break; - - case PIPE_ERR_ABORTED: - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "aborted") - errbuf; - break; - - default: - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, - "unexpected err type: %d", pipe_ctx->err_type); - ngx_http_lua_assert(NULL); - } -} - - -static void -ngx_http_lua_pipe_put_data(ngx_http_lua_pipe_t *pipe, - ngx_http_lua_pipe_ctx_t *pipe_ctx, u_char **buf, size_t *buf_size) -{ - size_t size = 0; - size_t chunk_size; - size_t nbufs; - u_char *p; - ngx_buf_t *b; - ngx_chain_t *cl; - ngx_chain_t **ll; - - nbufs = 0; - ll = NULL; - - for (cl = pipe_ctx->bufs_in; cl; cl = cl->next) { - b = cl->buf; - chunk_size = b->last - b->pos; - - if (cl->next) { - ll = &cl->next; - } - - size += chunk_size; - - nbufs++; - } - - if (*buf_size < size) { - *buf = NULL; - *buf_size = size; - - return; - } - - *buf_size = size; - - p = *buf; - for (cl = pipe_ctx->bufs_in; cl; cl = cl->next) { - b = cl->buf; - chunk_size = b->last - b->pos; - p = ngx_cpymem(p, b->pos, chunk_size); - } - - if (nbufs > 1 && ll) { - *ll = pipe->free_bufs; - pipe->free_bufs = pipe_ctx->bufs_in; - pipe_ctx->bufs_in = pipe_ctx->buf_in; - } - - if (pipe_ctx->buffer.pos == pipe_ctx->buffer.last) { - pipe_ctx->buffer.pos = pipe_ctx->buffer.start; - pipe_ctx->buffer.last = pipe_ctx->buffer.start; - } - - if (pipe_ctx->bufs_in) { - pipe_ctx->buf_in->buf->last = pipe_ctx->buffer.pos; - pipe_ctx->buf_in->buf->pos = pipe_ctx->buffer.pos; - } -} - - -static ngx_int_t -ngx_http_lua_pipe_add_input_buffer(ngx_http_lua_pipe_t *pipe, - ngx_http_lua_pipe_ctx_t *pipe_ctx) -{ - ngx_chain_t *cl; - - cl = ngx_http_lua_chain_get_free_buf(ngx_cycle->log, pipe->pool, - &pipe->free_bufs, - pipe->buffer_size); - - if (cl == NULL) { - pipe_ctx->err_type = PIPE_ERR_NOMEM; - return NGX_ERROR; - } - - pipe_ctx->buf_in->next = cl; - pipe_ctx->buf_in = cl; - pipe_ctx->buffer = *cl->buf; - - return NGX_OK; -} - - -static ngx_int_t -ngx_http_lua_pipe_read_all(void *data, ssize_t bytes) -{ - ngx_http_lua_pipe_ctx_t *pipe_ctx = data; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "lua pipe read all"); - return ngx_http_lua_read_all(&pipe_ctx->buffer, pipe_ctx->buf_in, bytes, - ngx_cycle->log); -} - - -static ngx_int_t -ngx_http_lua_pipe_read_bytes(void *data, ssize_t bytes) -{ - ngx_int_t rc; - ngx_http_lua_pipe_ctx_t *pipe_ctx = data; - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe read bytes %z", bytes); - - rc = ngx_http_lua_read_bytes(&pipe_ctx->buffer, pipe_ctx->buf_in, - &pipe_ctx->rest, bytes, ngx_cycle->log); - if (rc == NGX_ERROR) { - pipe_ctx->err_type = PIPE_ERR_CLOSED; - return NGX_ERROR; - } - - return rc; -} - - -static ngx_int_t -ngx_http_lua_pipe_read_line(void *data, ssize_t bytes) -{ - ngx_int_t rc; - ngx_http_lua_pipe_ctx_t *pipe_ctx = data; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe read line"); - rc = ngx_http_lua_read_line(&pipe_ctx->buffer, pipe_ctx->buf_in, bytes, - ngx_cycle->log); - if (rc == NGX_ERROR) { - pipe_ctx->err_type = PIPE_ERR_CLOSED; - return NGX_ERROR; - } - - return rc; -} - - -static ngx_int_t -ngx_http_lua_pipe_read_any(void *data, ssize_t bytes) -{ - ngx_int_t rc; - ngx_http_lua_pipe_ctx_t *pipe_ctx = data; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "lua pipe read any"); - rc = ngx_http_lua_read_any(&pipe_ctx->buffer, pipe_ctx->buf_in, - &pipe_ctx->rest, bytes, ngx_cycle->log); - if (rc == NGX_ERROR) { - pipe_ctx->err_type = PIPE_ERR_CLOSED; - return NGX_ERROR; - } - - return rc; -} - - -static ngx_int_t -ngx_http_lua_pipe_read(ngx_http_lua_pipe_t *pipe, - ngx_http_lua_pipe_ctx_t *pipe_ctx) -{ - int rc; - int read; - size_t size; - ssize_t n; - ngx_buf_t *b; - ngx_event_t *rev; - ngx_connection_t *c; - - c = pipe_ctx->c; - rev = c->read; - b = &pipe_ctx->buffer; - read = 0; - - for ( ;; ) { - size = b->last - b->pos; - - if (size || pipe_ctx->eof) { - rc = pipe_ctx->input_filter(pipe_ctx->input_filter_ctx, size); - if (rc == NGX_ERROR) { - return NGX_ERROR; - } - - if (rc == NGX_OK) { - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe read done pipe:%p", pipe_ctx); - return NGX_OK; - } - - /* rc == NGX_AGAIN */ - continue; - } - - if (read && !rev->ready) { - break; - } - - size = b->end - b->last; - - if (size == 0) { - rc = ngx_http_lua_pipe_add_input_buffer(pipe, pipe_ctx); - if (rc == NGX_ERROR) { - return NGX_ERROR; - } - - b = &pipe_ctx->buffer; - size = (size_t) (b->end - b->last); - } - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe try to read data %uz pipe:%p", - size, pipe_ctx); - - n = c->recv(c, b->last, size); - read = 1; - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe read data returned %z pipe:%p", n, pipe_ctx); - - if (n == NGX_AGAIN) { - break; - } - - if (n == 0) { - pipe_ctx->eof = 1; - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe closed pipe:%p", pipe_ctx); - continue; - } - - if (n == NGX_ERROR) { - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, ngx_errno, - "lua pipe read data error pipe:%p", pipe_ctx); - - pipe_ctx->err_type = PIPE_ERR_SYSCALL; - pipe_ctx->pipe_errno = ngx_errno; - return NGX_ERROR; - } - - b->last += n; - } - - return NGX_AGAIN; -} - - -static ngx_int_t -ngx_http_lua_pipe_init_ctx(ngx_http_lua_pipe_ctx_t **pipe_ctx_pt, int fd, - ngx_pool_t *pool, u_char *errbuf, size_t *errbuf_size) -{ - ngx_connection_t *c; - - if (fd == -1) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "closed") - errbuf; - return NGX_ERROR; - } - - *pipe_ctx_pt = ngx_pcalloc(pool, sizeof(ngx_http_lua_pipe_ctx_t)); - if (*pipe_ctx_pt == NULL) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "no memory") - - errbuf; - return NGX_ERROR; - } - - c = ngx_get_connection(fd, ngx_cycle->log); - if (c == NULL) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "no connection") - - errbuf; - return NGX_ERROR; - } - - c->log = ngx_cycle->log; - c->recv = ngx_http_lua_pipe_fd_read; - c->read->handler = ngx_http_lua_pipe_dummy_event_handler; - c->read->log = c->log; - -#ifdef HAVE_SOCKET_CLOEXEC_PATCH - c->read->skip_socket_leak_check = 1; -#endif - - c->send = ngx_http_lua_pipe_fd_write; - c->write->handler = ngx_http_lua_pipe_dummy_event_handler; - c->write->log = c->log; - (*pipe_ctx_pt)->c = c; - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe init pipe ctx:%p fd:*%d", *pipe_ctx_pt, fd); - - return NGX_OK; -} - - -int -ngx_http_lua_ffi_pipe_proc_read(ngx_http_request_t *r, - ngx_http_lua_ffi_pipe_proc_t *proc, int from_stderr, int reader_type, - size_t length, u_char **buf, size_t *buf_size, u_char *errbuf, - size_t *errbuf_size) -{ - int rc; - ngx_msec_t timeout; - ngx_event_t *rev; - ngx_connection_t *c; - ngx_http_lua_ctx_t *ctx; - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_co_ctx_t *wait_co_ctx; - ngx_http_lua_pipe_ctx_t *pipe_ctx; - - rc = ngx_http_lua_pipe_get_lua_ctx(r, &ctx, errbuf, errbuf_size); - if (rc != NGX_OK) { - return rc; - } - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua pipe read process:%p pid:%P", proc, proc->_pid); - - pipe = proc->pipe; - if (pipe == NULL || pipe->closed) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "closed") - errbuf; - return NGX_ERROR; - } - - if (pipe->merge_stderr && from_stderr) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "merged to stdout") - - errbuf; - return NGX_ERROR; - } - - if (from_stderr) { - if (pipe->stderr_ctx == NULL) { - if (ngx_http_lua_pipe_init_ctx(&pipe->stderr_ctx, pipe->stderr_fd, - pipe->pool, errbuf, - errbuf_size) - != NGX_OK) - { - return NGX_ERROR; - } - - } else { - pipe->stderr_ctx->err_type = 0; - } - - pipe_ctx = pipe->stderr_ctx; - - } else { - if (pipe->stdout_ctx == NULL) { - if (ngx_http_lua_pipe_init_ctx(&pipe->stdout_ctx, pipe->stdout_fd, - pipe->pool, errbuf, - errbuf_size) - != NGX_OK) - { - return NGX_ERROR; - } - - } else { - pipe->stdout_ctx->err_type = 0; - } - - pipe_ctx = pipe->stdout_ctx; - } - - c = pipe_ctx->c; - if (c == NULL) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "closed") - errbuf; - return NGX_ERROR; - } - - rev = c->read; - if (rev->handler != ngx_http_lua_pipe_dummy_event_handler) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "pipe busy reading") - - errbuf; - return NGX_ERROR; - } - - pipe_ctx->input_filter_ctx = pipe_ctx; - - switch (reader_type) { - - case PIPE_READ_ALL: - pipe_ctx->input_filter = ngx_http_lua_pipe_read_all; - break; - - case PIPE_READ_BYTES: - pipe_ctx->input_filter = ngx_http_lua_pipe_read_bytes; - break; - - case PIPE_READ_LINE: - pipe_ctx->input_filter = ngx_http_lua_pipe_read_line; - break; - - case PIPE_READ_ANY: - pipe_ctx->input_filter = ngx_http_lua_pipe_read_any; - break; - - default: - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, - "unexpected reader_type: %d", reader_type); - ngx_http_lua_assert(NULL); - } - - pipe_ctx->rest = length; - - if (pipe_ctx->bufs_in == NULL) { - pipe_ctx->bufs_in = - ngx_http_lua_chain_get_free_buf(ngx_cycle->log, pipe->pool, - &pipe->free_bufs, - pipe->buffer_size); - - if (pipe_ctx->bufs_in == NULL) { - pipe_ctx->err_type = PIPE_ERR_NOMEM; - goto error; - } - - pipe_ctx->buf_in = pipe_ctx->bufs_in; - pipe_ctx->buffer = *pipe_ctx->buf_in->buf; - } - - rc = ngx_http_lua_pipe_read(pipe, pipe_ctx); - if (rc == NGX_ERROR) { - goto error; - } - - if (rc == NGX_OK) { - ngx_http_lua_pipe_put_data(pipe, pipe_ctx, buf, buf_size); - return NGX_OK; - } - - /* rc == NGX_AGAIN */ - wait_co_ctx = ctx->cur_co_ctx; - - c->data = wait_co_ctx; - if (ngx_handle_read_event(rev, 0) != NGX_OK) { - pipe_ctx->err_type = PIPE_ERR_ADD_READ_EV; - goto error; - } - - wait_co_ctx->data = proc; - - if (from_stderr) { - rev->handler = ngx_http_lua_pipe_resume_read_stderr_handler; - wait_co_ctx->cleanup = ngx_http_lua_pipe_proc_read_stderr_cleanup; - timeout = proc->stderr_read_timeout; - - } else { - rev->handler = ngx_http_lua_pipe_resume_read_stdout_handler; - wait_co_ctx->cleanup = ngx_http_lua_pipe_proc_read_stdout_cleanup; - timeout = proc->stdout_read_timeout; - } - - if (timeout > 0) { - ngx_add_timer(rev, timeout); - ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua pipe add timer for reading: %d(ms) process:%p " - "pid:%P pipe:%p ev:%p", timeout, proc, proc->_pid, pipe, - rev); - } - - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua pipe read yielding process:%p pid:%P pipe:%p", proc, - proc->_pid, pipe); - - return NGX_AGAIN; - -error: - - if (pipe_ctx->bufs_in) { - ngx_http_lua_pipe_put_data(pipe, pipe_ctx, buf, buf_size); - ngx_http_lua_pipe_put_error(pipe_ctx, errbuf, errbuf_size); - return NGX_DECLINED; - } - - ngx_http_lua_pipe_put_error(pipe_ctx, errbuf, errbuf_size); - - return NGX_ERROR; -} - - -/* - * ngx_http_lua_ffi_pipe_get_read_result should only be called just after - * ngx_http_lua_ffi_pipe_proc_read, so we omit most of the sanity check already - * done in ngx_http_lua_ffi_pipe_proc_read. - */ -int -ngx_http_lua_ffi_pipe_get_read_result(ngx_http_request_t *r, - ngx_http_lua_ffi_pipe_proc_t *proc, int from_stderr, u_char **buf, - size_t *buf_size, u_char *errbuf, size_t *errbuf_size) -{ - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_pipe_ctx_t *pipe_ctx; - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua pipe get read result process:%p pid:%P", proc, - proc->_pid); - - pipe = proc->pipe; - pipe_ctx = from_stderr ? pipe->stderr_ctx : pipe->stdout_ctx; - - if (!pipe_ctx->err_type) { - ngx_http_lua_pipe_put_data(pipe, pipe_ctx, buf, buf_size); - return NGX_OK; - } - - if (pipe_ctx->bufs_in) { - ngx_http_lua_pipe_put_data(pipe, pipe_ctx, buf, buf_size); - ngx_http_lua_pipe_put_error(pipe_ctx, errbuf, errbuf_size); - return NGX_DECLINED; - } - - ngx_http_lua_pipe_put_error(pipe_ctx, errbuf, errbuf_size); - - return NGX_ERROR; -} - - -static ngx_int_t -ngx_http_lua_pipe_write(ngx_http_lua_pipe_t *pipe, - ngx_http_lua_pipe_ctx_t *pipe_ctx) -{ - size_t size; - ngx_int_t n; - ngx_buf_t *b; - ngx_connection_t *c; - - c = pipe_ctx->c; - b = pipe_ctx->buf_in->buf; - - for ( ;; ) { - size = b->last - b->pos; - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe try to write data %uz pipe:%p", size, - pipe_ctx); - - n = c->send(c, b->pos, size); - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe write returned %i pipe:%p", n, pipe_ctx); - - if (n >= 0) { - b->pos += n; - - if (b->pos == b->last) { - b->pos = b->start; - b->last = b->start; - - if (!pipe->free_bufs) { - pipe->free_bufs = pipe_ctx->buf_in; - - } else { - pipe->free_bufs->next = pipe_ctx->buf_in; - } - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe write done pipe:%p", pipe_ctx); - return NGX_OK; - } - - continue; - } - - /* NGX_ERROR || NGX_AGAIN */ - break; - } - - if (n == NGX_ERROR) { - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, ngx_errno, - "lua pipe write data error pipe:%p", pipe_ctx); - - if (ngx_errno == NGX_EPIPE) { - pipe_ctx->err_type = PIPE_ERR_CLOSED; - - } else { - pipe_ctx->err_type = PIPE_ERR_SYSCALL; - pipe_ctx->pipe_errno = ngx_errno; - } - - return NGX_ERROR; - } - - return NGX_AGAIN; -} - - -ssize_t -ngx_http_lua_ffi_pipe_proc_write(ngx_http_request_t *r, - ngx_http_lua_ffi_pipe_proc_t *proc, const u_char *data, size_t len, - u_char *errbuf, size_t *errbuf_size) -{ - int rc; - ngx_buf_t *b; - ngx_msec_t timeout; - ngx_chain_t *cl; - ngx_event_t *wev; - ngx_http_lua_ctx_t *ctx; - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_co_ctx_t *wait_co_ctx; - ngx_http_lua_pipe_ctx_t *pipe_ctx; - - rc = ngx_http_lua_pipe_get_lua_ctx(r, &ctx, errbuf, errbuf_size); - if (rc != NGX_OK) { - return rc; - } - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua pipe write process:%p pid:%P", proc, proc->_pid); - - pipe = proc->pipe; - if (pipe == NULL || pipe->closed) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "closed") - errbuf; - return NGX_ERROR; - } - - if (pipe->stdin_ctx == NULL) { - if (ngx_http_lua_pipe_init_ctx(&pipe->stdin_ctx, pipe->stdin_fd, - pipe->pool, errbuf, - errbuf_size) - != NGX_OK) - { - return NGX_ERROR; - } - - } else { - pipe->stdin_ctx->err_type = 0; - } - - pipe_ctx = pipe->stdin_ctx; - if (pipe_ctx->c == NULL) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "closed") - errbuf; - return NGX_ERROR; - } - - wev = pipe_ctx->c->write; - if (wev->handler != ngx_http_lua_pipe_dummy_event_handler) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "pipe busy writing") - - errbuf; - return NGX_ERROR; - } - - pipe_ctx->rest = len; - - cl = ngx_http_lua_chain_get_free_buf(ngx_cycle->log, pipe->pool, - &pipe->free_bufs, len); - if (cl == NULL) { - pipe_ctx->err_type = PIPE_ERR_NOMEM; - goto error; - } - - pipe_ctx->buf_in = cl; - b = pipe_ctx->buf_in->buf; - b->last = ngx_copy(b->last, data, len); - - rc = ngx_http_lua_pipe_write(pipe, pipe_ctx); - if (rc == NGX_ERROR) { - goto error; - } - - if (rc == NGX_OK) { - return len; - } - - /* rc == NGX_AGAIN */ - wait_co_ctx = ctx->cur_co_ctx; - pipe_ctx->c->data = wait_co_ctx; - - wev->handler = ngx_http_lua_pipe_resume_write_handler; - if (ngx_handle_write_event(wev, 0) != NGX_OK) { - pipe_ctx->err_type = PIPE_ERR_ADD_WRITE_EV; - goto error; - } - - wait_co_ctx->data = proc; - wait_co_ctx->cleanup = ngx_http_lua_pipe_proc_write_cleanup; - timeout = proc->write_timeout; - - if (timeout > 0) { - ngx_add_timer(wev, timeout); - ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua pipe add timer for writing: %d(ms) process:%p " - "pid:%P pipe:%p ev:%p", timeout, proc, proc->_pid, pipe, - wev); - } - - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua pipe write yielding process:%p pid:%P pipe:%p", proc, - proc->_pid, pipe); - - return NGX_AGAIN; - -error: - - ngx_http_lua_pipe_put_error(pipe_ctx, errbuf, errbuf_size); - return NGX_ERROR; -} - - -/* - * ngx_http_lua_ffi_pipe_get_write_result should only be called just after - * ngx_http_lua_ffi_pipe_proc_write, so we omit most of the sanity check - * already done in ngx_http_lua_ffi_pipe_proc_write. - */ -ssize_t -ngx_http_lua_ffi_pipe_get_write_result(ngx_http_request_t *r, - ngx_http_lua_ffi_pipe_proc_t *proc, u_char *errbuf, size_t *errbuf_size) -{ - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_pipe_ctx_t *pipe_ctx; - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua pipe get write result process:%p pid:%P", proc, - proc->_pid); - - pipe = proc->pipe; - pipe_ctx = pipe->stdin_ctx; - - if (pipe_ctx->err_type) { - ngx_http_lua_pipe_put_error(pipe_ctx, errbuf, errbuf_size); - return NGX_ERROR; - } - - return pipe_ctx->rest; -} - - -int -ngx_http_lua_ffi_pipe_proc_wait(ngx_http_request_t *r, - ngx_http_lua_ffi_pipe_proc_t *proc, char **reason, int *status, - u_char *errbuf, size_t *errbuf_size) -{ - int rc; - ngx_rbtree_node_t *node; - ngx_http_lua_ctx_t *ctx; - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_co_ctx_t *wait_co_ctx; - ngx_http_lua_pipe_node_t *pipe_node; - - rc = ngx_http_lua_pipe_get_lua_ctx(r, &ctx, errbuf, errbuf_size); - if (rc != NGX_OK) { - return rc; - } - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua pipe wait process:%p pid:%P", proc, proc->_pid); - - pipe = proc->pipe; - if (pipe == NULL || pipe->closed) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "exited") - errbuf; - return NGX_ERROR; - } - - node = pipe->node; - pipe_node = (ngx_http_lua_pipe_node_t *) &node->color; - if (pipe_node->wait_co_ctx) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "pipe busy waiting") - - errbuf; - return NGX_ERROR; - } - - if (pipe_node->reason_code == REASON_RUNNING_CODE) { - wait_co_ctx = ctx->cur_co_ctx; - wait_co_ctx->data = proc; - ngx_memzero(&wait_co_ctx->sleep, sizeof(ngx_event_t)); - wait_co_ctx->sleep.handler = ngx_http_lua_pipe_resume_wait_handler; - wait_co_ctx->sleep.data = wait_co_ctx; - wait_co_ctx->sleep.log = r->connection->log; - wait_co_ctx->cleanup = ngx_http_lua_pipe_proc_wait_cleanup; - - pipe_node->wait_co_ctx = wait_co_ctx; - - if (proc->wait_timeout > 0) { - ngx_add_timer(&wait_co_ctx->sleep, proc->wait_timeout); - ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua pipe add timer for waiting: %d(ms) process:%p " - "pid:%P ev:%p", proc->wait_timeout, proc, - proc->_pid, &wait_co_ctx->sleep); - } - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua pipe wait yielding process:%p pid:%P", proc, - proc->_pid); - - return NGX_AGAIN; - } - - *status = pipe_node->status; - - switch (pipe_node->reason_code) { - - case REASON_EXIT_CODE: - *reason = REASON_EXIT; - break; - - case REASON_SIGNAL_CODE: - *reason = REASON_SIGNAL; - break; - - default: - *reason = REASON_UNKNOWN; - } - - ngx_http_lua_pipe_proc_finalize(proc); - - if (*status == 0) { - return NGX_OK; - } - - return NGX_DECLINED; -} - - -int -ngx_http_lua_ffi_pipe_proc_kill(ngx_http_lua_ffi_pipe_proc_t *proc, int signal, - u_char *errbuf, size_t *errbuf_size) -{ - ngx_pid_t pid; - ngx_http_lua_pipe_t *pipe; - - pipe = proc->pipe; - - if (pipe == NULL || pipe->dead) { - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "exited") - errbuf; - return NGX_ERROR; - } - - pid = proc->_pid; - - if (kill(pid, signal) == -1) { - switch (ngx_errno) { - case EINVAL: - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "invalid signal") - - errbuf; - break; - - case ESRCH: - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "exited") - - errbuf; - break; - - default: - *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "%s", - strerror(ngx_errno)) - - errbuf; - } - - return NGX_ERROR; - } - - return NGX_OK; -} - - -static int -ngx_http_lua_pipe_read_stdout_retval(ngx_http_lua_ffi_pipe_proc_t *proc, - lua_State *L) -{ - return ngx_http_lua_pipe_read_retval_helper(proc, L, 0); -} - - -static int -ngx_http_lua_pipe_read_stderr_retval(ngx_http_lua_ffi_pipe_proc_t *proc, - lua_State *L) -{ - return ngx_http_lua_pipe_read_retval_helper(proc, L, 1); -} - - -static int -ngx_http_lua_pipe_read_retval_helper(ngx_http_lua_ffi_pipe_proc_t *proc, - lua_State *L, int from_stderr) -{ - int rc; - ngx_msec_t timeout; - ngx_event_t *rev; - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_pipe_ctx_t *pipe_ctx; - - pipe = proc->pipe; - if (from_stderr) { - pipe_ctx = pipe->stderr_ctx; - - } else { - pipe_ctx = pipe->stdout_ctx; - } - - if (pipe->timeout) { - pipe->timeout = 0; - pipe_ctx->err_type = PIPE_ERR_TIMEOUT; - return 0; - } - - if (pipe_ctx->err_type == PIPE_ERR_ABORTED) { - ngx_close_connection(pipe_ctx->c); - pipe_ctx->c = NULL; - return 0; - } - - rc = ngx_http_lua_pipe_read(pipe, pipe_ctx); - if (rc != NGX_AGAIN) { - return 0; - } - - rev = pipe_ctx->c->read; - - if (from_stderr) { - rev->handler = ngx_http_lua_pipe_resume_read_stderr_handler; - timeout = proc->stderr_read_timeout; - - } else { - rev->handler = ngx_http_lua_pipe_resume_read_stdout_handler; - timeout = proc->stdout_read_timeout; - } - - if (timeout > 0) { - ngx_add_timer(rev, timeout); - ngx_log_debug5(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe add timer for reading: %d(ms) proc:%p " - "pid:%P pipe:%p ev:%p", timeout, proc, proc->_pid, pipe, - rev); - } - - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe read yielding process:%p pid:%P pipe:%p", proc, - proc->_pid, pipe); - - return NGX_AGAIN; -} - - -static int -ngx_http_lua_pipe_write_retval(ngx_http_lua_ffi_pipe_proc_t *proc, - lua_State *L) -{ - int rc; - ngx_msec_t timeout; - ngx_event_t *wev; - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_pipe_ctx_t *pipe_ctx; - - pipe = proc->pipe; - pipe_ctx = pipe->stdin_ctx; - - if (pipe->timeout) { - pipe->timeout = 0; - pipe_ctx->err_type = PIPE_ERR_TIMEOUT; - return 0; - } - - if (pipe_ctx->err_type == PIPE_ERR_ABORTED) { - ngx_close_connection(pipe_ctx->c); - pipe_ctx->c = NULL; - return 0; - } - - rc = ngx_http_lua_pipe_write(pipe, pipe_ctx); - if (rc != NGX_AGAIN) { - return 0; - } - - wev = pipe_ctx->c->write; - wev->handler = ngx_http_lua_pipe_resume_write_handler; - timeout = proc->write_timeout; - - if (timeout > 0) { - ngx_add_timer(wev, timeout); - ngx_log_debug5(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe add timer for writing: %d(ms) proc:%p " - "pid:%P pipe:%p ev:%p", timeout, proc, proc->_pid, pipe, - wev); - } - - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe write yielding process:%p pid:%P pipe:%p", proc, - proc->_pid, pipe); - - return NGX_AGAIN; -} - - -static int -ngx_http_lua_pipe_wait_retval(ngx_http_lua_ffi_pipe_proc_t *proc, lua_State *L) -{ - int nret; - ngx_rbtree_node_t *node; - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_pipe_node_t *pipe_node; - - pipe = proc->pipe; - node = pipe->node; - pipe_node = (ngx_http_lua_pipe_node_t *) &node->color; - pipe_node->wait_co_ctx = NULL; - - if (pipe->timeout) { - pipe->timeout = 0; - lua_pushnil(L); - lua_pushliteral(L, "timeout"); - return 2; - } - - ngx_http_lua_pipe_proc_finalize(pipe_node->proc); - - if (pipe_node->status == 0) { - lua_pushboolean(L, 1); - lua_pushliteral(L, REASON_EXIT); - lua_pushinteger(L, pipe_node->status); - nret = 3; - - } else { - lua_pushboolean(L, 0); - - switch (pipe_node->reason_code) { - - case REASON_EXIT_CODE: - lua_pushliteral(L, REASON_EXIT); - break; - - case REASON_SIGNAL_CODE: - lua_pushliteral(L, REASON_SIGNAL); - break; - - default: - lua_pushliteral(L, REASON_UNKNOWN); - } - - lua_pushinteger(L, pipe_node->status); - nret = 3; - } - - return nret; -} - - -static void -ngx_http_lua_pipe_resume_helper(ngx_event_t *ev, - ngx_http_lua_co_ctx_t *wait_co_ctx) -{ - ngx_connection_t *c; - ngx_http_request_t *r; - ngx_http_lua_ctx_t *ctx; - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_ffi_pipe_proc_t *proc; - - if (ev->timedout) { - proc = wait_co_ctx->data; - pipe = proc->pipe; - pipe->timeout = 1; - ev->timedout = 0; - } - - ngx_http_lua_pipe_clear_event(ev); - - r = ngx_http_lua_get_req(wait_co_ctx->co); - c = r->connection; - - ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); - ngx_http_lua_assert(ctx != NULL); - - ctx->cur_co_ctx = wait_co_ctx; - - if (ctx->entered_content_phase) { - (void) ngx_http_lua_pipe_resume(r); - - } else { - ctx->resume_handler = ngx_http_lua_pipe_resume; - ngx_http_core_run_phases(r); - } - - ngx_http_run_posted_requests(c); -} - - -static void -ngx_http_lua_pipe_resume_read_stdout_handler(ngx_event_t *ev) -{ - ngx_connection_t *c = ev->data; - ngx_http_lua_co_ctx_t *wait_co_ctx; - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_ffi_pipe_proc_t *proc; - - wait_co_ctx = c->data; - proc = wait_co_ctx->data; - pipe = proc->pipe; - pipe->retval_handler = ngx_http_lua_pipe_read_stdout_retval; - ngx_http_lua_pipe_resume_helper(ev, wait_co_ctx); -} - - -static void -ngx_http_lua_pipe_resume_read_stderr_handler(ngx_event_t *ev) -{ - ngx_connection_t *c = ev->data; - ngx_http_lua_co_ctx_t *wait_co_ctx; - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_ffi_pipe_proc_t *proc; - - wait_co_ctx = c->data; - proc = wait_co_ctx->data; - pipe = proc->pipe; - pipe->retval_handler = ngx_http_lua_pipe_read_stderr_retval; - ngx_http_lua_pipe_resume_helper(ev, wait_co_ctx); -} - - -static void -ngx_http_lua_pipe_resume_write_handler(ngx_event_t *ev) -{ - ngx_connection_t *c = ev->data; - ngx_http_lua_co_ctx_t *wait_co_ctx; - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_ffi_pipe_proc_t *proc; - - wait_co_ctx = c->data; - proc = wait_co_ctx->data; - pipe = proc->pipe; - pipe->retval_handler = ngx_http_lua_pipe_write_retval; - ngx_http_lua_pipe_resume_helper(ev, wait_co_ctx); -} - - -static void -ngx_http_lua_pipe_resume_wait_handler(ngx_event_t *ev) -{ - ngx_http_lua_co_ctx_t *wait_co_ctx = ev->data; - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_ffi_pipe_proc_t *proc; - - proc = wait_co_ctx->data; - pipe = proc->pipe; - pipe->retval_handler = ngx_http_lua_pipe_wait_retval; - ngx_http_lua_pipe_resume_helper(ev, wait_co_ctx); -} - - -static ngx_int_t -ngx_http_lua_pipe_resume(ngx_http_request_t *r) -{ - int nret; - lua_State *vm; - ngx_int_t rc; - ngx_uint_t nreqs; - ngx_connection_t *c; - ngx_http_lua_ctx_t *ctx; - ngx_http_lua_pipe_t *pipe; - ngx_http_lua_ffi_pipe_proc_t *proc; - - ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); - if (ctx == NULL) { - return NGX_ERROR; - } - - ctx->resume_handler = ngx_http_lua_wev_handler; - ctx->cur_co_ctx->cleanup = NULL; - - proc = ctx->cur_co_ctx->data; - pipe = proc->pipe; - nret = pipe->retval_handler(proc, ctx->cur_co_ctx->co); - if (nret == NGX_AGAIN) { - return NGX_DONE; - } - - c = r->connection; - vm = ngx_http_lua_get_lua_vm(r, ctx); - nreqs = c->requests; - - rc = ngx_http_lua_run_thread(vm, r, ctx, nret); - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua run thread returned %d", rc); - - if (rc == NGX_AGAIN) { - return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs); - } - - if (rc == NGX_DONE) { - ngx_http_lua_finalize_request(r, NGX_DONE); - return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs); - } - - /* rc == NGX_ERROR || rc >= NGX_OK */ - - if (ctx->entered_content_phase) { - ngx_http_lua_finalize_request(r, rc); - return NGX_DONE; - } - - return rc; -} - - -static void -ngx_http_lua_pipe_dummy_event_handler(ngx_event_t *ev) -{ - /* do nothing */ -} - - -static void -ngx_http_lua_pipe_clear_event(ngx_event_t *ev) -{ - ev->handler = ngx_http_lua_pipe_dummy_event_handler; - - if (ev->timer_set) { - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0, - "lua pipe del timer for ev:%p", ev); - ngx_del_timer(ev); - } - - if (ev->posted) { - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0, - "lua pipe del posted event for ev:%p", ev); - ngx_delete_posted_event(ev); - } -} - - -static void -ngx_http_lua_pipe_proc_read_stdout_cleanup(void *data) -{ - ngx_event_t *rev; - ngx_connection_t *c; - ngx_http_lua_co_ctx_t *wait_co_ctx = data; - ngx_http_lua_ffi_pipe_proc_t *proc; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe proc read stdout cleanup"); - - proc = wait_co_ctx->data; - c = proc->pipe->stdout_ctx->c; - if (c) { - rev = c->read; - ngx_http_lua_pipe_clear_event(rev); - } - - wait_co_ctx->cleanup = NULL; -} - - -static void -ngx_http_lua_pipe_proc_read_stderr_cleanup(void *data) -{ - ngx_event_t *rev; - ngx_connection_t *c; - ngx_http_lua_co_ctx_t *wait_co_ctx = data; - ngx_http_lua_ffi_pipe_proc_t *proc; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe proc read stderr cleanup"); - - proc = wait_co_ctx->data; - c = proc->pipe->stderr_ctx->c; - if (c) { - rev = c->read; - ngx_http_lua_pipe_clear_event(rev); - } - - wait_co_ctx->cleanup = NULL; -} - - -static void -ngx_http_lua_pipe_proc_write_cleanup(void *data) -{ - ngx_event_t *wev; - ngx_connection_t *c; - ngx_http_lua_co_ctx_t *wait_co_ctx = data; - ngx_http_lua_ffi_pipe_proc_t *proc; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe proc write cleanup"); - - proc = wait_co_ctx->data; - c = proc->pipe->stdin_ctx->c; - if (c) { - wev = c->write; - ngx_http_lua_pipe_clear_event(wev); - } - - wait_co_ctx->cleanup = NULL; -} - - -static void -ngx_http_lua_pipe_proc_wait_cleanup(void *data) -{ - ngx_rbtree_node_t *node; - ngx_http_lua_co_ctx_t *wait_co_ctx = data; - ngx_http_lua_pipe_node_t *pipe_node; - ngx_http_lua_ffi_pipe_proc_t *proc; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe proc wait cleanup"); - - proc = wait_co_ctx->data; - node = proc->pipe->node; - pipe_node = (ngx_http_lua_pipe_node_t *) &node->color; - pipe_node->wait_co_ctx = NULL; - - ngx_http_lua_pipe_clear_event(&wait_co_ctx->sleep); - - wait_co_ctx->cleanup = NULL; -} - - -#endif /* HAVE_NGX_LUA_PIPE */ - -/* vi:set ft=c ts=4 sw=4 et fdm=marker: */ diff --git a/nginx/src/lua-nginx/src/ngx_http_lua_pipe.h b/nginx/src/lua-nginx/src/ngx_http_lua_pipe.h deleted file mode 100644 index ecb86c880..000000000 --- a/nginx/src/lua-nginx/src/ngx_http_lua_pipe.h +++ /dev/null @@ -1,94 +0,0 @@ - -/* - * Copyright (C) by OpenResty Inc. - */ - - -#ifndef _NGX_HTTP_LUA_PIPE_H_INCLUDED_ -#define _NGX_HTTP_LUA_PIPE_H_INCLUDED_ - - -#include "ngx_http_lua_common.h" - - -typedef ngx_int_t (*ngx_http_lua_pipe_input_filter)(void *data, ssize_t bytes); - - -typedef struct { - ngx_connection_t *c; - ngx_http_lua_pipe_input_filter input_filter; - void *input_filter_ctx; - size_t rest; - ngx_chain_t *buf_in; - ngx_chain_t *bufs_in; - ngx_buf_t buffer; - ngx_err_t pipe_errno; - unsigned err_type:16; - unsigned eof:1; -} ngx_http_lua_pipe_ctx_t; - - -typedef struct ngx_http_lua_pipe_s ngx_http_lua_pipe_t; - - -typedef struct { - ngx_pid_t _pid; - ngx_msec_t write_timeout; - ngx_msec_t stdout_read_timeout; - ngx_msec_t stderr_read_timeout; - ngx_msec_t wait_timeout; - /* pipe hides the implementation from the Lua binding */ - ngx_http_lua_pipe_t *pipe; -} ngx_http_lua_ffi_pipe_proc_t; - - -typedef int (*ngx_http_lua_pipe_retval_handler)( - ngx_http_lua_ffi_pipe_proc_t *proc, lua_State *L); - - -struct ngx_http_lua_pipe_s { - ngx_pool_t *pool; - ngx_chain_t *free_bufs; - ngx_rbtree_node_t *node; - int stdin_fd; - int stdout_fd; - int stderr_fd; - ngx_http_lua_pipe_ctx_t *stdin_ctx; - ngx_http_lua_pipe_ctx_t *stdout_ctx; - ngx_http_lua_pipe_ctx_t *stderr_ctx; - ngx_http_lua_pipe_retval_handler retval_handler; - size_t buffer_size; - unsigned closed:1; - unsigned dead:1; - unsigned timeout:1; - unsigned merge_stderr:1; -}; - - -typedef struct { - u_char color; - u_char reason_code; - int status; - ngx_http_lua_co_ctx_t *wait_co_ctx; - ngx_http_lua_ffi_pipe_proc_t *proc; -} ngx_http_lua_pipe_node_t; - - -typedef struct { - int signo; - char *signame; -} ngx_http_lua_pipe_signal_t; - - -#if !(NGX_WIN32) && defined(HAVE_SOCKET_CLOEXEC_PATCH) -#define HAVE_NGX_LUA_PIPE 1 - - -void ngx_http_lua_pipe_init(void); -ngx_int_t ngx_http_lua_pipe_add_signal_handler(ngx_cycle_t *cycle); -#endif - - -#endif /* _NGX_HTTP_LUA_PIPE_H_INCLUDED_ */ - -/* vi:set ft=c ts=4 sw=4 et fdm=marker: */