#!/bin/env awk -f function debug(t) { printf "%s\n", t >>"/dev/stderr"; } function PATH( str, seg, out ) { while ( str ) { seg = str; sub( /\/.*$/, "", seg); sub( /^[^\/]*\//, "", str); if ( seg == ".." ) sub(/\/[^\/]*\/?$/, "", out); else if ( seg ~ /^\.?$/) sub(/\/?$/, "/", out); else sub(/\/?$/, "/" seg, out); if (seg == str) break; } if (!(str && out)) sub(/\/?$/,"/" out); return out; } function HEX_DECODE( pfx, inp, out, n, k ) { k = length(pfx); gsub(/[].*+?^${}()|\\[]/,"\\\\&",pfx); while ( inp ) if ( n = match(inp, pfx "[0-9a-fA-F][0-9a-fA-F]") ) { out = out substr(inp, 1, n - 1); inp = substr(inp, n + k); if (inp ~ /^[0-9]/) n = 16 * substr(inp, 1, 1); else if (inp ~ /^[aA]/) n = 160; else if (inp ~ /^[bB]/) n = 176; else if (inp ~ /^[cC]/) n = 192; else if (inp ~ /^[dD]/) n = 208; else if (inp ~ /^[eE]/) n = 224; else if (inp ~ /^[fF]/) n = 240; if (inp ~ /^.[0-9]/) n += substr(inp, 2, 1); else if (inp ~ /^.[aA]/) n += 10; else if (inp ~ /^.[bB]/) n += 11; else if (inp ~ /^.[cC]/) n += 12; else if (inp ~ /^.[dD]/) n += 13; else if (inp ~ /^.[eE]/) n += 14; else if (inp ~ /^.[fF]/) n += 15; out = out sprintf("%c", n); inp = substr(inp, 3); } else { out = out inp; break; } return out; } function HTML( text ) { gsub( /&/, "\\&", text ); gsub( //, "\\>", text ); gsub( /"/, "\\"", text ); gsub( /'/, "\\'", text ); gsub( /\[/, "\\[", text ); gsub( /\]/, "\\]", text ); gsub( /\r/, "\\ ", text ); gsub( /\n/, "\\ ", text ); gsub( /\\/, "\\\", text ); return text; } function URL( text ) { gsub( /&/, "%26", text ); gsub( /"/, "%22", text ); gsub( /'/, "%27", text ); gsub( /`/, "%60", text ); gsub( /\?/, "%3F", text ); gsub( /#/, "%23", text ); gsub( /\[/, "%5B", text ); gsub( /\]/, "%5D", text ); gsub( / /, "%20", text ); gsub( /\t/, "%09", text ); gsub( /\r/, "%0D", text ); gsub( /\n/, "%0A", text ); gsub( /%/, "%25", text ); gsub( /\\/, "%5C", text ); return text; } function _cgilite_urldecode( str, arr, spl, form, k, n, key) { if (! spl) spl="&" split(str, form, spl); for ( k in form ) { key = form[k]; sub(/=.*$/, "", key); sub(/^[^=]*=/, "", form[k]); if ( key in arr ) { n = 1; while ( (key, n) in arr ) n++; arr[key,n] = HEX_DECODE( "%", form[k]); } else { arr[key] = HEX_DECODE( "%", form[k]); } } } function _cgilite_request( key, val) { # Read request from client connection # Read Headers getline; REQUEST_METHOD = $1; REQUEST_URI = $2; SERVER_PROTOCOL = $3; while ( getline ) { if ($0 ~ /^\r?$/) break; else if ($0 ~ /^[a-zA-Z][0-9a-zA-Z_-]+: .*/) { key = toupper($0); sub(/:.*$/, "", key); gsub(/-/, "_", key); _HEADER[key] = $0; sub(/^[^:]:[\t ]*/, "", _HEADER[key]); sub(/[\t ]*\r?$/, "", _HEADER[key]); } } CONTENT_LENGTH = _HEADER["CONTENT_LENGTH"]; CONTENT_TYPE = _HEADER["CONTENT_TYPE"]; PATH_INFO = REQUEST_URI; gsub(/\?.*$/, "", PATH_INFO) PATH_INFO = PATH( HEX_DECODE( "%", PATH_INFO ) ); QUERY_STRING = REQUEST_URI; if ( !gsub(/^[^?]+\?/, "", QUERY_STRING) ) QUERY_STRING = ""; # Set up _GET[]-Array _cgilite_urldecode(QUERY_STRING, _GET); if ( _HEADER["CONTENT_TYPE"] == "application/x-www-form-urlencoded" \ && _HEADER["CONTENT_LENGTH"] ) { # Set up _POST[]-Array val = ""; key = "head -c " _HEADER["CONTENT_LENGTH"]; while (key |getline) val = val $0; close(key); _cgilite_urldecode(val, _POST); } if ( _HEADER["COOKIE"] ) { # Set up _COOKIE[]-Array _cgilite_urldecode(_HEADER["COOKIE"], _COOKIE, "; ?"); } if ( _HEADER["REFERER"] ) { key = HEADER["REFERER"]; if (! sub(/^[^\?]+?/, "", key)) key = "" _cgilite_urldecode(key, _REF); } } function _cgilite_headers() { # Import request data from webserver environment variables } BEGIN { REQUEST_METHOD=""; REQUEST_URI=""; SERVER_PROTOCOL=""; PATH_INFO=""; QUERY_STRING=""; CONTENT_LENGTH=""; CONTENT_TYPE=""; split("", _GET); split("", _POST); split("", _REF); split("", _HEADER); split("", _COOKIE); if ( ENVIRON["REQUEST_METHOD"] ) { _cgilite_headers(); } else { _cgilite_request(); } }