Implemented some CGI variable support.

This commit is contained in:
Emilis Dambauskas 2020-12-01 03:30:02 +02:00
parent 24111c51fd
commit 1ad2b9f6c1
14 changed files with 214 additions and 98 deletions

View File

@ -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

3
lib/io.awk Normal file
View File

@ -0,0 +1,3 @@
function debug( str ) {
print str > "/dev/stderr";
}

11
lib/request.awk Normal file
View File

@ -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 );
}

41
lib/response.awk Normal file
View File

@ -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 = ""
}

11
lib/str.awk Normal file
View File

@ -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;
}

44
lib/tags.awk Normal file
View File

@ -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 );
}

15
lib/url.awk Normal file
View File

@ -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;
}

41
serve-request.awk Normal file
View File

@ -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();
}

45
serve-request.sh Executable file
View File

@ -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

View File

@ -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

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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( "```" );
}