From b1154ddc4c5852a310b55436f9e34e0c93247926 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Paul=20H=C3=A4nsch?= Date: Mon, 2 Jul 2018 15:15:26 +0200 Subject: [PATCH] enable connection reuse in builtin web server --- cgilite.sh | 51 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/cgilite.sh b/cgilite.sh index cac905f..4686626 100755 --- a/cgilite.sh +++ b/cgilite.sh @@ -24,6 +24,7 @@ setopt -o OCTAL_ZEROES 2>&- BR="$(printf '\n')" CR="$(printf '\r')" +cgilite_timeout=2 HEADER(){ # Read value of header line. Use this instead of @@ -52,22 +53,42 @@ HEX_DECODE(){ if [ -z "$REQUEST_METHOD" -a -z "$SERVER_PROTOCOL" ]; then # no webserver variables means we are running via inetd / ncat # so use builtin web server - REMOTE_ADDR="${TCPREMOTEIP:-$NCAT_REMOTE_ADDR}" - SERVER_NAME="${TCPLOCALIP:-$NCAT_LOCAL_ADDR}" - SERVER_PORT="${TCPLOCALPORT:-$NCAT_LOCAL_PORT}" - read REQUEST_METHOD REQUEST_URI SERVER_PROTOCOL - PATH_INFO="$(HEX_DECODE "${REQUEST_URI%\?*}")" - QUERY_STRING="${REQUEST_URI#*\?}" - cgilite_headers="$(sed -u '/^\r\?$/q')" - - HTTP_CONTENT_LENGTH="$(HEADER Content-Length |grep -xE '[0-9]+')" - - export REMOTE_ADDR SERVER_NAME SERVER_PORT REQUEST_METHOD REQUEST_URI SERVER_PROTOCOL \ - PATH_INFO QUERY_STRING HTTP_CONTENT_LENGTH - - . "$0" |sed '1{s;^Status: ;HTTP/1.0 ;; t; s;^;HTTP/1.0 200 OK\r\n;;}' - exit $? + # Use env from inetd as webserver variables + REMOTE_ADDR="${TCPREMOTEIP}" + SERVER_NAME="${TCPLOCALIP}" + SERVER_PORT="${TCPLOCALPORT}" + + # Wait 2 seconds for request or kill connection through watchdog. + # Once Request is received the watchdog will be suspended (killed). + # At the end of the loop the watchdog will be restarted to enable + # timeout for the subsequent request. + + (sleep $cgilite_timeout && kill $$) & cgilite_watchdog=$! + while read REQUEST_METHOD REQUEST_URI SERVER_PROTOCOL; do + kill $cgilite_watchdog + PATH_INFO="$(HEX_DECODE "${REQUEST_URI%\?*}")" + QUERY_STRING="${REQUEST_URI#*\?}" + cgilite_headers="$(sed -u '/^\r\?$/q')" + + HTTP_CONTENT_LENGTH="$(HEADER Content-Length |grep -xE '[0-9]+')" + + export REMOTE_ADDR SERVER_NAME SERVER_PORT REQUEST_METHOD REQUEST_URI SERVER_PROTOCOL \ + PATH_INFO QUERY_STRING HTTP_CONTENT_LENGTH + + # Try to serve multiple requests, provided that script serves a + # Content-Length header. + # Without Content-Length header, connection will terminate after + # script. + + . "$0" |sed '1{s;^Status: ;HTTP/1.1 ;; t; s;^;HTTP/1.1 200 OK\r\n;;}' \ + | while read -r l; do case $l in + Content-Length:*) printf '%s\n' "$l"; cat;; + $CR) printf 'Connection: close\r\n\r\n'; cat; exit 1;; + *) printf '%s\n' "$l";; + esac; done || exit 0; + (sleep $cgilite_timeout && kill $$) & cgilite_watchdog=$! + done fi if [ "$REQUEST_METHOD" = POST -a "${HTTP_CONTENT_LENGTH:=${CONTENT_LENGTH:=0}}" -gt 0 ]; then -- 2.39.2