Created
April 13, 2015 22:38
-
-
Save mbbx6spp/0ba0406afe65db556eef to your computer and use it in GitHub Desktop.
ZOMG a bash powers HTTP web service that runs via the `socat` web app container like so: socat TCP4-LISTEN:8080 EXEC:/path/to/server/script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Purpose: Provide HTTP server that displays the current server date to | |
# validate the artifact structure and play with. | |
declare -a _http_responses=( | |
[200]="OK" | |
[201]="Created" | |
[202]="Accepted" | |
[204]="No Content" | |
[301]="Moved Permanently" | |
[302]="Found" | |
[307]="Temporary Redirect" | |
[400]="Bad Request" | |
[401]="Unauthorized" | |
[403]="Forbidden" | |
[404]="Not Found" | |
[405]="Method Not Allowed" | |
[500]="Internal Server Error" | |
[501]="Not Implemented Error" | |
[502]="Bad Gateway" | |
[503]="Temporarily Unavailable" | |
) | |
function _recv() { | |
echo "< $*" >&2 | |
} | |
function _send() { | |
printf '%s\r\n' "$*" | |
} | |
function _send_headers() { | |
local -r dt="$(date +"%a, %d %b %Y %H:%M:%S %Z")" | |
local -r hst="$(hostname -s)" | |
local -a hdrs=( | |
"Date: ${dt}" | |
"Expires: ${dt}" | |
"Content-Type: text/plain" | |
"Server: hello-bash@${hst}/0.0.1" | |
) | |
for h in "${hdrs[@]}"; do | |
_send "${h}" | |
done | |
} | |
function _send_body() { | |
_send "Yo yo yo!" | |
} | |
function _send_response() { | |
_send "${1}" | |
_send_headers | |
_send "" | |
_send_body | |
} | |
function _respond_with() { | |
if [ "$#" -ne 1 ]; then | |
>&2 "Error: Expected one argument for ${FUNCNAME}, received $#." | |
>&2 "Usage: ${0} CODE" | |
return 1 | |
fi | |
local -r code="${1}" | |
_send_response "${code} ${_http_responses[${code}]}" | |
} | |
function _parse_request() { | |
if [ "$#" -ne 1 ]; then | |
>&2 "Error: Expected one argument for ${FUNCNAME}, received $#." | |
>&2 "Usage: ${0} REQUEST_LINE" | |
return 1 | |
fi | |
local -r req="${1%%$'r'}" | |
read -r req_method req_uri req_http_ver <<<"${req}" | |
# Validate request (only support GET and / URI so far :) | |
if [ "${req_method}" = "GET" -a "${req_uri}" = "/" -a -n "${req_http_ver}" ]; then | |
_respond_with 200 | |
elif [ "${req_uri}" != "/" ]; then | |
_respond_with 404 | |
elif [ -z "${req_http_ver}" ]; then | |
_respond_with 400 | |
else | |
_respond_with 500 | |
fi | |
} | |
function _main() { | |
read -r line || _respond_with 400 | |
_parse_request "${line}" | |
} | |
if [ "${BASH_SOURCE[0]}" != "${0}" ]; then | |
export -f _respond_with | |
export -f _parse_request | |
else | |
set -eu | |
_main | |
fi |
It's the missing HTTP/1.0
See the example here:
https://stuff.mit.edu/afs/sipb/machine/penguin-lust/src/socat-1.7.1.2/EXAMPLES
socat -T 1 -d -d tcp-l:10081,reuseaddr,fork,crlf system:"echo -e \"\\\"HTTP/1.0 200 OK\\\nDocumentType: text/html\\\n\\\n<html>date: \$\(date\)<br>server:\$SOCAT_SOCKADDR:\$SOCAT_SOCKPORT<br>client: \$SOCAT_PEERADDR:\$SOCAT_PEERPORT\\\n<pre>\\\"\"; cat; echo -e \"\\\"\\\n</pre></html>\\\"\""
That example is also using socat to convert LF to CRLF, so, if following that example, you wouldn't need _send(), just plain echo everywhere.
We don't need to use the system: option from that example, exec: is fine, since we are using a script in a file, not shell commands directly on the commandline.
Restored my version that went away when that account was deleted (I'm the "ghost" above)
https://gist.github.com/bkw777/e026f514306065e3d4e2c5b85e911838
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Erm, second thought, this is not a web service after all.
The output all ends up in the content and the headers are not treated as headers by real http clients.
try:
curl -D apache_headers.txt localhost >apache_content.txt
curl -D bash_headers.txt localhost:8080 >bash_content.txt
Perhaps somehow a newline is getting output before the headers, or perhaps it's something else entirely.