From 1ad2b9f6c155af0b73c8aadf116f8d6938d204ad Mon Sep 17 00:00:00 2001 From: Emilis Dambauskas Date: Tue, 1 Dec 2020 03:30:02 +0200 Subject: [PATCH] Implemented some CGI variable support. --- Makefile | 6 +++--- {srv => lib}/exec.awk | 0 lib/io.awk | 3 +++ lib/request.awk | 11 +++++++++++ lib/response.awk | 41 +++++++++++++++++++++++++++++++++++++++ lib/str.awk | 11 +++++++++++ lib/tags.awk | 44 ++++++++++++++++++++++++++++++++++++++++++ lib/url.awk | 15 +++++++++++++++ serve-request.awk | 41 +++++++++++++++++++++++++++++++++++++++ serve-request.sh | 45 +++++++++++++++++++++++++++++++++++++++++++ server-main.sh | 17 ---------------- srv/main.awk | 25 ------------------------ srv/response.awk | 22 --------------------- srv/tags.awk | 31 ----------------------------- 14 files changed, 214 insertions(+), 98 deletions(-) rename {srv => lib}/exec.awk (100%) create mode 100644 lib/io.awk create mode 100644 lib/request.awk create mode 100644 lib/response.awk create mode 100644 lib/str.awk create mode 100644 lib/tags.awk create mode 100644 lib/url.awk create mode 100644 serve-request.awk create mode 100755 serve-request.sh delete mode 100755 server-main.sh delete mode 100644 srv/main.awk delete mode 100644 srv/response.awk delete mode 100644 srv/tags.awk diff --git a/Makefile b/Makefile index f6c0eac..6781484 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CERT_DAYS=10000 -COMMAND="./server-main.sh" +COMMAND="./serve-request.sh" COUNTRY=LT DOMAIN=localhost @@ -16,10 +16,10 @@ server: ncat-server .PHONY: ncat-server ncat-server: certs - ncat -v \ + ncat \ --listen --keep-open -p 1965 \ --ssl --ssl-cert "certs/${DOMAIN}.crt" --ssl-key "certs/${DOMAIN}.key" \ - -c "${COMMAND}" + --exec ${COMMAND} .PHONY: socat-server diff --git a/srv/exec.awk b/lib/exec.awk similarity index 100% rename from srv/exec.awk rename to lib/exec.awk diff --git a/lib/io.awk b/lib/io.awk new file mode 100644 index 0000000..74fe424 --- /dev/null +++ b/lib/io.awk @@ -0,0 +1,3 @@ +function debug( str ) { + print str > "/dev/stderr"; +} diff --git a/lib/request.awk b/lib/request.awk new file mode 100644 index 0000000..059fecc --- /dev/null +++ b/lib/request.awk @@ -0,0 +1,11 @@ +BEGIN { + debug( REMOTE_ADDR " " REQUEST_FULL_URL ); + + _REQUEST_NO_PROTOCOL = str_replace( "[^:]+:\\/\\/", "", REQUEST_FULL_URL ); + REQUEST_URI = str_replace( "[^/]+\\/?", "/", _REQUEST_NO_PROTOCOL ); + + PATH_INFO = url_decode( str_replace( "\\?.+$", "", REQUEST_URI )); + QUERY_STRING = url_decode( str_replace( "[^?]+\\??", "", REQUEST_URI )); + SERVER_NAME = str_replace( "\\/.*$", "", _REQUEST_NO_PROTOCOL ); + SERVER_PROTOCOL = str_replace( ":\\/\\/.+$", "", REQUEST_FULL_URL ); +} diff --git a/lib/response.awk b/lib/response.awk new file mode 100644 index 0000000..fe431cc --- /dev/null +++ b/lib/response.awk @@ -0,0 +1,41 @@ +BEGIN { + response_code = "51" + response_meta = "text/gemini" + response_body = "" +} + +function println( arg ) { + response_body = response_body "\n" arg +} + +function response_end() { + + printf "%s %s\r\n", response_code, response_meta + print response_body + exit; +} + +function response_error() { + + response_code = "42" + response_body = "Internal server error" + response_end() +} + +function response_not_found() { + + response_code = "51" + response_body = "Page not found" + response_end(); +} + +function response_ok() { + + response_code = "20" + response_end() +} + +function response_reset() { + + response_body = "" +} diff --git a/lib/str.awk b/lib/str.awk new file mode 100644 index 0000000..45809bf --- /dev/null +++ b/lib/str.awk @@ -0,0 +1,11 @@ +function str_replace( regexp, replacement, string ) { + _tmp_str_replace = string; + sub( regexp, replacement, _tmp_str_replace ); + return _tmp_str_replace; +} + +function str_replace_global( regexp, replacement, string ) { + _tmp_str_replace = string; + gsub( regexp, replacement, _tmp_str_replace ); + return _tmp_str_replace; +} diff --git a/lib/tags.awk b/lib/tags.awk new file mode 100644 index 0000000..295ff29 --- /dev/null +++ b/lib/tags.awk @@ -0,0 +1,44 @@ +function h1( str ) { + + println( "# " str ); +} + +function h2( str ) { + + println( "## " str ); +} + +function h3( str ) { + + println( "### " str ); +} + +function li( str ) { + + println( "* " str ); +} + +function link( url, str ) { + + println( "=> " url " " str ); +} + +function pre_open() { + println( "```" ); +} + +function pre_close() { + println( "```" ); +} + +function pre( str ) { + + pre_open(); + println( str ); + pre_close(); +} + +function text( str ) { + + println( str ); +} diff --git a/lib/url.awk b/lib/url.awk new file mode 100644 index 0000000..e4cac7d --- /dev/null +++ b/lib/url.awk @@ -0,0 +1,15 @@ +function url_decode( str ) { + for ( y = 0; y < 127; y++ ) { + if ( y != 37 ) { + gsub( \ + sprintf( "%%%02x|%%%02X", y, y ), \ + y == 38 \ + ? "\\&" \ + : sprintf("%c", y), \ + str \ + ); + } + gsub( /%25/, "%", str ); + } + return str; +} diff --git a/serve-request.awk b/serve-request.awk new file mode 100644 index 0000000..f239f75 --- /dev/null +++ b/serve-request.awk @@ -0,0 +1,41 @@ +PATH_INFO ~ /^\/test-cgi/ { + + h1( "Test CGI" ); + + pre_open(); + println( REQUEST_FULL_URL ); + println(); + println( "GATEWAY_INTERFACE: " GATEWAY_INTERFACE ); + println( "PATH_INFO: " PATH_INFO ); + println( "PATH_TRANSLATED: " PATH_TRANSLATED ); + println( "QUERY_STRING: " QUERY_STRING ); + println( "REMOTE_ADDR: " REMOTE_ADDR ); + println( "REMOTE_HOST: " REMOTE_HOST ); + println( "REMOTE_USER: " REMOTE_USER ); + println( "REQUEST_URI: " REQUEST_URI ); + println( "SERVER_NAME: " SERVER_NAME ); + println( "SERVER_PORT: " SERVER_PORT ); + pre_close(); + + link( "/", "Back to home" ); + + response_ok(); +} + +PATH_INFO == "/" { + + h1( "Hello World from Awk!" ); + text( "This is a test." ); + pre( REQUEST_FULL_URL ); + link( "/test-cgi/abc%20123?query%20string", "Test CGI" ); + text( "Updated " \ + exec_to_string( "date -Iseconds" ) \ + ); + + response_ok(); +} + +{ + debug( "* matched" ); + response_not_found(); +} diff --git a/serve-request.sh b/serve-request.sh new file mode 100755 index 0000000..695a0ae --- /dev/null +++ b/serve-request.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env sh + +PATH_TRANSLATED=`readlink -fn ./serve-request.awk`; +SERVER_NAME=`uname -n`; + +if [ -n "$NCAT_REMOTE_ADDR" ]; +then REMOTE_ADDR="$NCAT_REMOTE_ADDR"; +elif [ -n "$SOCAT_PEERADDR" ]; +then REMOTE_ADDR="$SOCAT_PEERADDR"; +else REMOTE_ADDR="127.0.0.1"; +fi + +if [ -n "$SOCAT_SOCKPORT" ]; +then SERVER_PORT="$SOCAT_SOCKPORT"; +else SERVER_PORT="1965"; +fi + + +read -r URL GARBAGE; +REQUEST_FULL_URL=${URL%?}; # Remove "\r" at the end + +echo "$REQUEST_FULL_URL" | awk \ + -v AUTH_TYPE="" \ + -v CONTENT_LENGTH="" \ + -v CONTENT_TYPE="" \ + -v GATEWAY_INTERFACE="CGI/1.1" \ + -v PATH_TRANSLATED="$PATH_TRANSLATED" \ + -v REMOTE_ADDR="$REMOTE_ADDR" \ + -v REMOTE_HOST="$REMOTE_ADDR" \ + -v REMOTE_USER="" \ + -v REQUEST_FULL_URL="$REQUEST_FULL_URL" \ + -v REQUEST_METHOD="GET" \ + -v SCRIPT_NAME="/" \ + -v SERVER_NAME="$SERVER_NAME" \ + -v SERVER_PORT="$SERVER_PORT" \ + -v SERVER_PROTOCOL="GEMINI" \ + -v SERVER_SOFTWARE="Gebase" \ + -f lib/exec.awk \ + -f lib/io.awk \ + -f lib/str.awk \ + -f lib/url.awk \ + -f lib/request.awk \ + -f lib/response.awk \ + -f lib/tags.awk \ + -f serve-request.awk diff --git a/server-main.sh b/server-main.sh deleted file mode 100755 index ea7cff5..0000000 --- a/server-main.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -read -r URL GARBAGE; - -REQUEST_URL=${URL%?}; # Remove "\r" at the end -URL_NO_PROTOCOL=${REQUEST_URL#*://} -REQUEST_PATH=/${URL_NO_PROTOCOL#*/} -REQUEST_QUERY=${URL#*\?} - -echo "$REQUEST_PATH" | awk \ - -v REQUEST_PATH="$REQUEST_PATH" \ - -v REQUEST_QUERY="$REQUEST_QUERY" \ - -v REQUEST_URL="$REQUEST_URL" \ - -f srv/exec.awk \ - -f srv/response.awk \ - -f srv/tags.awk \ - -f srv/main.awk diff --git a/srv/main.awk b/srv/main.awk deleted file mode 100644 index da923bc..0000000 --- a/srv/main.awk +++ /dev/null @@ -1,25 +0,0 @@ -REQUEST_PATH ~ /^\/test/ { - response_reset(); - - h1( "Test path" ); - println( "^/test matched" ); - pre( REQUEST_URL ); - link( "/", "Back to home" ); - - response_ok(); -} - -REQUEST_PATH == "/" { - response_reset(); - - h1( "Hello World from Awk!" ); - println( "This is a test." ); - pre( REQUEST_URL ); - link( "/test123", "A test page" ); - - println( "Updated " \ - exec_to_string( "date -Iseconds" ) \ - ); - - response_ok(); -} diff --git a/srv/response.awk b/srv/response.awk deleted file mode 100644 index 240defb..0000000 --- a/srv/response.awk +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN { - response_code = "51" - response_meta = "text/gemini" - response_body = "" -} - -END { - printf "%s %s\r\n", response_code, response_meta; - print response_body -} - -function response_ok() { - response_code = "20" -} - -function response_reset() { - response_body = "" -} - -function println( arg ) { - response_body = response_body "\n" arg; -} diff --git a/srv/tags.awk b/srv/tags.awk deleted file mode 100644 index 261efa6..0000000 --- a/srv/tags.awk +++ /dev/null @@ -1,31 +0,0 @@ -function h1( text ) { - - println( "#" text ); -} - -function h2( text ) { - - println( "##" text ); -} - -function h3( text ) { - - println( "###" text ); -} - -function li( text ) { - - println( "* " text ); -} - -function link( url, text ) { - - println( "=> " url " " text ); -} - -function pre( text ) { - - println( "```" ); - println( text ); - println( "```" ); -}