Skip to content

Instantly share code, notes, and snippets.

@torosgo
Forked from dfletcher/tsws
Last active September 6, 2015 19:38
Show Gist options
  • Save torosgo/71b7934ec57bd816b226 to your computer and use it in GitHub Desktop.
Save torosgo/71b7934ec57bd816b226 to your computer and use it in GitHub Desktop.

Revisions

  1. @dfletcher dfletcher revised this gist Sep 6, 2015. 1 changed file with 96 additions and 53 deletions.
    149 changes: 96 additions & 53 deletions tsws
    Original file line number Diff line number Diff line change
    @@ -33,21 +33,24 @@
    # For more information, please refer to <http://unlicense.org>
    #

    # We use this to print to the terminal when the context
    # of STDOUT is something other than the pty.
    declare -r TTY="$(tty)"
    # All informative console log messages are piped to here so e.g. it could be
    # quieted by setting TSWS_LOG=/dev/null or alternatively logged to a file.
    # The default is $(tty) which prints logs to console.
    declare -r TSWS_LOG="$(tty)"

    # -----------------------------------------------------------------------------
    # tsws [addr [, port]]
    # tsws [host [, port]]
    # -----------------------------------------------------------------------------
    #
    # Start the Totally Simple Web Server.
    # Start the Totally Simple Web Server. Note that the `tsws` script that this
    # function lives in has the same interface as the function: tsws HOST PORT and
    # the script itself can be used in the same way as "Example usage" below.
    #
    # ---------
    # Arguments
    # ---------
    #
    # - addr: IP address (or hostname) to listen on. Optional. If not
    # - host: IP address (or hostname) to listen on. Optional. If not
    # supplied the default value is 127.0.0.1
    #
    # - port: Port to listen on. Optional. If not supplied the default
    @@ -59,16 +62,15 @@ declare -r TTY="$(tty)"
    #
    # # Launch the webserver. This version will not return, it will loop forever.
    # tsws localhost 8080
    #
    #
    # # Alternatively, launch the webserver and return immediately.
    # tsws localhost 8080 &
    # # Catch the PID so we can wait or kill later.
    # declare tsws_pid=$!
    # # Launch a browesr.
    # # Launch a browser. Don't detach, wait for exit.
    # firefox "http://localhost:8080"
    # # Done with other processing, join webserver.
    # wait ${tsws_pid}
    #
    # # User closed the browser, we're done, stop the server.
    # kill ${tsws_pid}
    #
    # -------------------
    # Theory of operation
    @@ -97,32 +99,60 @@ declare -r TTY="$(tty)"
    # --------------------------------------------------------------------------
    # Diagram: Theory of operation
    #
    # This model almost certainly has issues with concurrency. It is useful for
    # a single local user or demonstration purposes, but please do not use it
    # as a production web server connected to the internet.
    #
    # ------------
    # Requirements
    # ------------
    #
    # - nc (netcat) handles the network listen call for us and binds
    # stdin and stdout of the nc process to connected clients.
    # - Bash (obviously).
    #
    # - Netcat (nc) handles the network listen call for us and binds stdin and
    # stdout of the nc process to connected clients.
    #
    # - mkfifo: A FIFO pipe connects the output of nc to our _tsws_response
    # function which processes requests and sends responses back through stdin
    # of nc to browser client.
    #
    # - wc -c: For calculating Content-Length.
    #
    # - cat, tee: For pushing files and HTTP data through pipes.
    #
    # - date: Just to show some dynamic content in www_index.
    #
    # - base64: Demonstrates script-embedded binary files.
    #
    # - mkfifo: A FIFO pipe connects the output of nc to our
    # _tsws_response function which processes requests and sends
    # responses back through stdin of nc to browser client.
    # ---------------------
    # Known issues and bugs
    # ---------------------
    #
    # - wc -c: For calculating Content-Length.
    # - This setup almost certainly has issues with concurrency. It is useful for
    # a single local user or demonstration purposes, but please do not use it
    # as a production web server connected to the internet.
    #
    # - cat, tee: For pushing files and HTTP data through pipes.
    # - All HTTP caching is ignored keep things simple.
    #
    # - Cygwin doesn't work so great. Particularly, some requests just fail
    # inexplicably with nc never supplying a request or supplying a massively
    # delayed one.
    #
    # - It is easily confused, especially if multiple browsers or tabs are
    # pointed to it at the same time. Requests and responses might get dropped
    # (still not quite sure why on that) and the order can get out of whack,
    # sending the wrong file for a request.
    #
    function tsws {
    [ -z "$1" ] && local -r addr='127.0.0.1' || local -r addr="$1"
    [ -z "$2" ] && local -r port=18080 || local -r port="$2"

    local -r host="${1:-127.0.0.1}"
    local -r port="${2:-18080}"
    local -r fifo="$(mktemp -u)"

    # Initialize the FIFO pipe.
    mkfifo -m 600 "${fifo}"
    trap "rm ${fifo}" EXIT INT TERM HUP
    nc -kl "${addr}" ${port} \
    trap "rm ${fifo}" EXIT INT TERM HUP # Auto-cleanup at exit.

    # Connect _tsws_response to STDIN. Connect STDOUT to FIFO pipe. Then listen
    # on ${host}:${port}. nc -l is "listen" and -k is "listen forever".
    printf $'tsws HTTP/1.1 on %s:%s\n' "${host}" "${port}" > ${TSWS_LOG}
    nc -kl "${host}" ${port} \
    0< <(_tsws_response "${fifo}") \
    1> >(while : ; do cat - > "${fifo}"; done) # Loop keeps pipe open.
    }
    @@ -135,8 +165,7 @@ function tsws {
    # Do not call it directly.
    #
    function _tsws_response {
    local method path httpvers callback content_type
    local isfunc obf status msg
    local method path httpvers callback content_type status msg obf clen
    method=""
    while : ; do # Run forever.
    while read -r line; do
    @@ -168,29 +197,31 @@ function _tsws_response {
    obf="$(mktemp -u)"
    case "${method:?}" in
    GET)
    local -f "${callback}" > /dev/null
    isfunc=$(( ! $? ))
    if [ ${isfunc} = 1 ]; then
    if local -f "${callback}" > /dev/null; then
    # ${callback} is a function we declared.
    status=200; msg="OK"
    ${callback} > "${obf}"
    else
    # ${callback} is not defined.
    status=404; msg="Not Found"
    printf $'Not found: %s.' "${path}" > "${obf}"
    fi
    ;;
    *)
    # Currently we only handle GET requests.
    status=500; msg="Internal Server Error"
    printf $'Server Error: unknown method %s.' "${method}" > "${obf}"
    ;;
    esac
    clen=$(cat "${obf}"|wc -c)
    # Show request in term.
    printf $'%s %s\n' "${method}" "${path}" >${TTY}
    printf $'%s %s\n' "${method}" "${path}" >${TSWS_LOG}
    # Output headers, tee shows the response headers in term.
    printf $'HTTP/1.1 %s %s\r\n' "${status:?}" "${msg:?}" | tee ${TTY}
    printf $'Content-Length: %s\r\n' "$(cat "${obf}"|wc -c)" | tee ${TTY}
    printf $'Content-Type: %s\r\n' "${content_type}" | tee ${TTY}
    printf $'Connection: close\r\n' | tee ${TTY}
    printf $'\r\n' | tee ${TTY}
    printf $'HTTP/1.1 %s %s\r\n' "${status:?}" "${msg:?}" | tee ${TSWS_LOG}
    printf $'Content-Length: %s\r\n' "${clen}" | tee ${TSWS_LOG}
    printf $'Content-Type: %s\r\n' "${content_type}" | tee ${TSWS_LOG}
    printf $'Connection: close\r\n' | tee ${TSWS_LOG}
    printf $'\r\n' | tee ${TSWS_LOG}
    # Output the response data.
    cat "${obf}"
    rm "${obf}"
    @@ -217,19 +248,18 @@ cat <<EOF
    <style type="text/css">@import url("/style.css");</style>
    </head>
    <body>
    <a href="https://gist.github.com/dfletcher/4763be3295bd5638b797" title="Fork me on GitHub"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/e7bbb0521b397edbd5fe43e7f760759336b5e05f/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677265656e5f3030373230302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png"></a>
    <img class="graphic" src="/graphic.jpg" />
    <h1>Totally Simple Web Server</h1>
    <b>&copy; 2015 Dave Fletcher</b><br>
    All rights reserved</em><br>
    <p><em>A web server in <a href="https://www.gnu.org/software/bash/">Bash</a> and <a href="http://nc110.sourceforge.net/">Netcat</a>.</em></p>
    <b>$(date)</b><br><br>
    status: ${status}<br>
    statusmsg: ${msg}<br>
    method: ${method}<br>
    path: ${path}<br>
    httpvers: ${httpvers}<br>
    callback: ${callback}<br>
    <h1>Totally Simple Web Server</h1>
    <img class="graphic" src="/graphic.jpg" />
    <b>&copy; 2015 Dave Fletcher</b><br>
    All rights reserved</em><br>
    <p><em>A web server in <a href="https://www.gnu.org/software/bash/">Bash</a> and <a href="http://nc110.sourceforge.net/">Netcat</a>.</em></p>
    <b>$(date)</b><br><br>
    status: ${status} ${msg}<br>
    method: ${method}<br>
    path: ${path}<br>
    httpvers: ${httpvers}<br>
    callback: ${callback}<br>
    <a href="https://gist.github.com/dfletcher/4763be3295bd5638b797" title="Fork me on GitHub"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/e7bbb0521b397edbd5fe43e7f760759336b5e05f/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677265656e5f3030373230302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png"></a>
    </body>
    </html>
    EOF
    @@ -246,9 +276,22 @@ BODY {
    margin: 10%;
    }
    A, A:visited {
    color: #060;
    text-decoration: none;
    }
    A:active, A:hover {
    color: #393;
    text-decoration: underline;
    }
    .graphic {
    float: right;
    margin-left: 2em;
    position: relative;
    top: -2em;
    z-index: -1;
    }
    EOF
    @@ -517,6 +560,6 @@ EOF
    # | Main |
    # +---------------------------------------------------------------------------+

    [ -n "$1" ] && addr="$1" || addr="127.0.0.1"
    [ -n "$2" ] && port="$2" || port=18080
    tsws "${addr}" "${port}"
    declare host="${1:-127.0.0.1}"
    declare port="${2:-18080}"
    tsws "${host}" "${port}"
  2. @dfletcher dfletcher revised this gist Sep 6, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tsws
    Original file line number Diff line number Diff line change
    @@ -114,7 +114,7 @@ declare -r TTY="$(tty)"
    #
    # - wc -c: For calculating Content-Length.
    #
    # - cat: For pushing files requests and responses through pipes.
    # - cat, tee: For pushing files and HTTP data through pipes.
    #
    function tsws {
    [ -z "$1" ] && local -r addr='127.0.0.1' || local -r addr="$1"
  3. @dfletcher dfletcher revised this gist Sep 6, 2015. 1 changed file with 12 additions and 13 deletions.
    25 changes: 12 additions & 13 deletions tsws
    Original file line number Diff line number Diff line change
    @@ -136,7 +136,7 @@ function tsws {
    #
    function _tsws_response {
    local method path httpvers callback content_type
    local isfunc obf respf status msg
    local isfunc obf status msg
    method=""
    while : ; do # Run forever.
    while read -r line; do
    @@ -183,18 +183,17 @@ function _tsws_response {
    printf $'Server Error: unknown method %s.' "${method}" > "${obf}"
    ;;
    esac
    respf="$(mktemp)"
    # Output headers.
    printf $'HTTP/1.1 %s %s\r\n' "${status:?}" "${msg:?}" >> "${respf}"
    printf $'Content-Length: %s\r\n' "$(cat "${obf}"|wc -c)" >> "${respf}"
    printf $'Content-Type: %s\r\n' "${content_type}" >> "${respf}"
    printf $'Connection: close\r\n' >> "${respf}"
    printf $'\r\n' >> "${respf}"
    printf $'%s %s\n' "${method}" "${path}" >${TTY} # Show request in term.
    cat "${respf}" >${TTY} # Show response headers in term.
    # Write header and body to the stdin of `nc`.
    cat "${respf}" "${obf}"
    rm "${respf}" "${obf}"
    # Show request in term.
    printf $'%s %s\n' "${method}" "${path}" >${TTY}
    # Output headers, tee shows the response headers in term.
    printf $'HTTP/1.1 %s %s\r\n' "${status:?}" "${msg:?}" | tee ${TTY}
    printf $'Content-Length: %s\r\n' "$(cat "${obf}"|wc -c)" | tee ${TTY}
    printf $'Content-Type: %s\r\n' "${content_type}" | tee ${TTY}
    printf $'Connection: close\r\n' | tee ${TTY}
    printf $'\r\n' | tee ${TTY}
    # Output the response data.
    cat "${obf}"
    rm "${obf}"
    method=""
    fi
    done < "$1"
  4. @dfletcher dfletcher revised this gist Sep 6, 2015. 1 changed file with 5 additions and 3 deletions.
    8 changes: 5 additions & 3 deletions tsws
    Original file line number Diff line number Diff line change
    @@ -108,7 +108,7 @@ declare -r TTY="$(tty)"
    # - nc (netcat) handles the network listen call for us and binds
    # stdin and stdout of the nc process to connected clients.
    #
    # - mkfifo: A FIFO pip connects the output of nc to our
    # - mkfifo: A FIFO pipe connects the output of nc to our
    # _tsws_response function which processes requests and sends
    # responses back through stdin of nc to browser client.
    #
    @@ -243,11 +243,13 @@ cat <<\EOF
    @import url(//fonts.googleapis.com/css?family=Lato:400,700,400italic);
    BODY {
    font-family: 'Lato', sans-serif; margin: 10%;
    font-family: 'Lato', sans-serif;
    margin: 10%;
    }
    .graphic {
    float: right; margin-left: 3em;
    float: right;
    margin-left: 2em;
    }
    EOF
  5. @dfletcher dfletcher revised this gist Sep 6, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tsws
    Original file line number Diff line number Diff line change
    @@ -212,7 +212,7 @@ cat <<EOF
    <!DOCTYPE html>
    <html>
    <head>
    <title>Hi!</title>
    <title>Totally Simple Web Server</title>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script type="text/javascript" src="/site.js"></script>
    <style type="text/css">@import url("/style.css");</style>
  6. @dfletcher dfletcher revised this gist Sep 6, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tsws
    Original file line number Diff line number Diff line change
    @@ -226,7 +226,7 @@ cat <<EOF
    <p><em>A web server in <a href="https://www.gnu.org/software/bash/">Bash</a> and <a href="http://nc110.sourceforge.net/">Netcat</a>.</em></p>
    <b>$(date)</b><br><br>
    status: ${status}<br>
    statusmsg: ${statusmsg}<br>
    statusmsg: ${msg}<br>
    method: ${method}<br>
    path: ${path}<br>
    httpvers: ${httpvers}<br>
  7. @dfletcher dfletcher revised this gist Sep 6, 2015. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions tsws
    Original file line number Diff line number Diff line change
    @@ -264,6 +264,9 @@ EOF

    declare www_graphic_jpg_Content_Type="image/jpeg"
    function www_graphic_jpg {
    # Note: The base64 here is is just to show how a binary file could be
    # returned from a Bash function. As a different type of example, this could
    # be the output of ImageMagick instead of a hard-coded base64 jpeg.
    base64 -d <<\EOF
    /9j/4AAQSkZJRgABAQEASABIAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkz
    ODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2Nj
  8. @dfletcher dfletcher revised this gist Sep 6, 2015. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion tsws
    Original file line number Diff line number Diff line change
    @@ -222,7 +222,9 @@ cat <<EOF
    <img class="graphic" src="/graphic.jpg" />
    <h1>Totally Simple Web Server</h1>
    <b>&copy; 2015 Dave Fletcher</b><br>
    <em>All rights reserved</em><br><br>
    All rights reserved</em><br>
    <p><em>A web server in <a href="https://www.gnu.org/software/bash/">Bash</a> and <a href="http://nc110.sourceforge.net/">Netcat</a>.</em></p>
    <b>$(date)</b><br><br>
    status: ${status}<br>
    statusmsg: ${statusmsg}<br>
    method: ${method}<br>
  9. @dfletcher dfletcher revised this gist Sep 6, 2015. 2 changed files with 516 additions and 687 deletions.
    687 changes: 0 additions & 687 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,687 +0,0 @@
    #!/bin/bash

    # --------------------------------
    # Totally Simple Web Server (TSWS)
    # --------------------------------
    #
    # (c) 2015 Dave Fletcher
    # All Rights Reserved
    #
    # This is free and unencumbered software released into the public domain.
    #
    # Anyone is free to copy, modify, publish, use, compile, sell, or
    # distribute this software, either in source code form or as a compiled
    # binary, for any purpose, commercial or non-commercial, and by any
    # means.
    #
    # In jurisdictions that recognize copyright laws, the author or authors
    # of this software dedicate any and all copyright interest in the
    # software to the public domain. We make this dedication for the benefit
    # of the public at large and to the detriment of our heirs and
    # successors. We intend this dedication to be an overt act of
    # relinquishment in perpetuity of all present and future rights to this
    # software under copyright law.

    # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    # IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
    # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
    # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    # OTHER DEALINGS IN THE SOFTWARE.
    #
    # For more information, please refer to <http://unlicense.org>
    #

    declare -r TTY="$(tty)"
    declare ncpid reqfifo

    # ----------------
    # tsws(addr, port)
    # ----------------
    #
    # Totally Simple Web Server.
    #
    # Arguments: - addr: IP address (or hostname) to listen on.
    #
    # - port: Port to listen on.
    #
    # Exports: - reqfifo: A FIFO file pipe used while running.
    # Caller should remove when done.
    #
    # - ncpid: PID of the `nc` process that handles
    # http connections. Caller should kill when done.
    #
    #
    # Requires: - nc (netcat)
    #
    # Example usage:
    #
    # tsws 127.0.0.1 8080
    # trap 'kill ${ncpid}; rm ${reqfifo}' EXIT INT TERM HUP
    #
    function tsws {
    [ -z "$1" ] && local -r addr='127.0.0.1' || local -r addr="$1"
    [ -z "$2" ] && local -r port=18080 || local -r port="$2"
    export reqfifo="$(mktemp -u)"
    mkfifo -m 600 "${reqfifo}"
    nc -kl "${addr}" ${port} \
    0< <(_tsws_response "${reqfifo}") \
    1> >(while : ; do cat - > "${reqfifo}"; done) & # Loop keeps pipe open.
    export ncpid=$!
    }

    # --------------------
    # _tsws_response(fifo)
    # --------------------
    #
    # Internal workhorse function for handling requests and responses for tsws.
    # Do not call it directly.
    #
    function _tsws_response {
    local method path httpvers callback content_type
    local isfunc obf respf status msg
    method=""
    while : ; do # Run forever.
    while read -r line; do
    line="$(sed 's/\r//g' <<< "${line}")" # Replace CRLF with /n
    if [ -n "${line}" ]; then
    # ${line} is not empty, it is either a "Request-Line" or a header
    # line. If we have no 'method' yet we assume it is a Request-Line.
    # http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
    if [ -z "${method}" ]; then
    read -r method path httpvers <<< "${line}"
    continue
    fi
    # TODO: if we cared about any of the request headers, here is the
    # place to read them by parsing ${line}.
    else
    # ${line} is empty, so we received two consecutive CRLF.
    # Process the request.
    #
    # Currently all "files" served up by the server are functions in this
    # script that return content. This shows how dynamic content can be
    # served and keeps this example all in one single file. It should be
    # easy to adapt this to also read real files from disk Hint: obf below
    # and use `file` to get content_type.
    callback="www$(sed -e 's/\//_/g' -e 's/\./_/g' <<< "${path}")"
    [ "${callback}" = "www_" ] && callback="www_index"
    content_type="${callback}_Content_Type"
    content_type="${!content_type}"
    [ -z "${content_type}" ] && content_type="text/plain"
    obf="$(mktemp -u)"
    case "${method:?}" in
    GET)
    local -f "${callback}" > /dev/null
    isfunc=$(( ! $? ))
    if [ ${isfunc} = 1 ]; then
    status=200; msg="OK"
    ${callback} > "${obf}"
    else
    status=404; msg="Not Found"
    printf $'Not found: %s.' "${path}" > "${obf}"
    fi
    ;;
    *)
    status=500; msg="Internal Server Error"
    printf $'Server Error: unknown method %s.' "${method}" > "${obf}"
    ;;
    esac
    respf="$(mktemp)"
    # Output headers.
    printf $'HTTP/1.1 %s %s\r\n' "${status:?}" "${msg:?}" >> "${respf}"
    printf $'Content-Length: %s\r\n' "$(cat "${obf}" | wc -c)" >> "${respf}"
    printf $'Content-Type: %s\r\n' "${content_type}" >> "${respf}"
    printf $'Connection: close\r\n' >> "${respf}"
    printf $'\r\n' >> "${respf}"
    echo "${method} ${path}" > ${TTY} # Show request in term.
    cat "${respf}" > ${TTY} # Show response headers in term.
    # Write header and body to the stdin of `nc`.
    cat "${respf}" "${obf}"
    rm "${respf}" "${obf}"
    method=""
    fi
    done < "$1"
    done
    }


    # +---------------------------------------------------------------------------+
    # | WWW FILES |
    # +---------------------------------------------------------------------------+

    declare www_index_Content_Type="text/html; charset=utf-8"
    function www_index {
    cat <<EOF
    <!DOCTYPE html>
    <html>
    <head>
    <title>Hi!</title>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script type="text/javascript" src="/site.js"></script>
    <style type="text/css">@import url("/style.css");</style>
    </head>
    <body>
    status: ${status}<br>
    statusmsg: ${statusmsg}<br>
    method: ${method}<br>
    path: ${path}<br>
    httpvers: ${httpvers}<br>
    callback: ${callback}<br>
    <img src="/graphic.jpg" />
    </body>
    </html>
    EOF
    }

    declare www_style_css_Content_Type="text/css"
    function www_style_css {
    cat <<\EOF
    BODY { margin: 10%; }
    EOF
    }

    declare www_site_js_Content_Type="text/javascript"
    function www_site_js {
    cat <<\EOF
    (function ($) {
    //$(document).ready(function() { alert('hi!'); });
    }(jQuery));
    EOF
    }

    declare www_graphic_jpg_Content_Type="image/jpeg"
    function www_graphic_jpg {
    base64 -d <<\EOF
    /9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QNvaHR0cDov
    L25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENl
    aGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4
    OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjAtYzA2MCA2MS4xMzQ3NzcsIDIwMTAvMDIvMTItMTc6
    MzI6MDAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5
    OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHht
    bG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0i
    aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1w
    PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9
    InhtcC5kaWQ6RkY3RjExNzQwNzIwNjgxMTk3QTVDRDM0NzZENzAxMEEiIHhtcE1NOkRvY3VtZW50
    SUQ9InhtcC5kaWQ6MzkxMDQyNTI5RjE2MTFFMkJFQTVCNDNFN0U0RjgzNkMiIHhtcE1NOkluc3Rh
    bmNlSUQ9InhtcC5paWQ6MzkxMDQyNTE5RjE2MTFFMkJFQTVCNDNFN0U0RjgzNkMiIHhtcDpDcmVh
    dG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giPiA8eG1wTU06RGVyaXZlZEZy
    b20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozODhDQjhENTk1QjIxMUUyOUUyOEI1NDBEMDlE
    Q0U1MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozODhDQjhENjk1QjIxMUUyOUUyOEI1NDBE
    MDlEQ0U1MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94
    cGFja2V0IGVuZD0iciI/Pv/uAA5BZG9iZQBkwAAAAAH/2wCEAAYEBAQFBAYFBQYJBgUGCQsIBgYI
    CwwKCgsKCgwQDAwMDAwMEAwODxAPDgwTExQUExMcGxsbHB8fHx8fHx8fHx8BBwcHDQwNGBAQGBoV
    ERUaHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fH//AABEI
    AgwB2wMBEQACEQEDEQH/xACvAAEAAQUBAQAAAAAAAAAAAAAABAIDBQYHAQgBAQACAwEBAAAAAAAA
    AAAAAAABAgMEBQYHEAABAwMCAwUGBAMHAgcAAwABAAIDEQQFIRIxQQZRYSITB3GBoTJCFJFSIxWx
    YgjB0XKCM0MWkiTw4aKyU2Ml8cLSEQEAAgIBAgMFBwMDBAEFAAAAAQIRAwQhEjFBBVFhIjITcYGR
    obHRBkJSYsHhFPByIxUz8YKiUxb/2gAMAwEAAhEDEQA/APqlAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQKoFUBAQEBAQEBAQEBA
    QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECqC2Zq/IN1OLjo38UF
    iS9tmaSzgH8rUFl2Ux3Aucfef71GU4Gz4+cUDpGE8w57f4FTkwpfBk4hvsboXDR/sXFDX2SNAI96
    Ie4/OwXNw6zmY61yDBV9rJxI/Mw8HD2IMkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
    CAgICAgICAgICAgICAgICAgICAgpkkYxhe40aBUlBhMhnbWFu+Y+H6IRz73f3Ilyvqz1vgF8cXii
    Lq6B2v2H9KM9jnjie5vwUZIhrd71jevYXXF3I9zuLGO8qMdwDfF+JWKZ82TDGHOXcxrBZvl7w17q
    +9xWG3J1x5stdF58km16izlqa/b3MDe1hcKe4Ej4KscqntWnjX9jeulPUe7Lmxyy+YBo7dUOH+Jp
    /iFn17on3sFqTDe7+K16nxm6B/2+Utx5lpcN0cx414j6TzWdjXeiup5Mvj5or0CPKY95hvY+FSOD
    9fzURC/c594lMbJ7VjuUbPMupf8ApjDafiUFLbzLyt3Nfc07W2jY/hK6qDx91nI2lzXTkjX9S1Y/
    4RPaUGKufUKbFmuXsHmAfNNbtkY8AczBO1jj/kc9EZbF0/1RgOobL7zDX0V9ADteYnVcxw4te35m
    kdhCJyyiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDWuoMy1r
    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
    Bd/bYuxB7+3R/lQP29nYgft8fYg9+wj7EHn7fH2IH7fH2IH7fH2IH7ezsQP2+PsQejHx9iCoWEfY
    g9+xZ+VBULNg5IKhasHJB79s3sQVeS3sQeiIdiD3y0HoYgrAQehAQEBAQEBAQEBAQEBAQEBAQEBA
    QEBAQECgQKIFAgUQECgQKBAoECg7ECg7ECg7EDa3sCDza3sCBtb2BB7QdiBQIFAgUCBQIFAgUCBQ
    diBQdiBQdiBQdiBQdiBQIFAgUCBQIFAgUCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgIP/Z
    EOF
    }


    # +---------------------------------------------------------------------------+
    # | Main |
    # +---------------------------------------------------------------------------+

    [ -n "$1" ] && addr="$1" || addr="127.0.0.1"
    [ -n "$2" ] && port="$2" || port=18080
    tsws "${addr}" "${port}"
    trap 'kill ${ncpid}; rm ${reqfifo}' EXIT INT TERM HUP
    wait ${ncpid}
    516 changes: 516 additions & 0 deletions tsws
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,516 @@
    #!/bin/bash

    # --------------------------------
    # Totally Simple Web Server (TSWS)
    # --------------------------------
    #
    # (c) 2015 Dave Fletcher
    # All Rights Reserved
    #
    # This is free and unencumbered software released into the public domain.
    #
    # Anyone is free to copy, modify, publish, use, compile, sell, or
    # distribute this software, either in source code form or as a compiled
    # binary, for any purpose, commercial or non-commercial, and by any
    # means.
    #
    # In jurisdictions that recognize copyright laws, the author or authors
    # of this software dedicate any and all copyright interest in the
    # software to the public domain. We make this dedication for the benefit
    # of the public at large and to the detriment of our heirs and
    # successors. We intend this dedication to be an overt act of
    # relinquishment in perpetuity of all present and future rights to this
    # software under copyright law.

    # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    # IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
    # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
    # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    # OTHER DEALINGS IN THE SOFTWARE.
    #
    # For more information, please refer to <http://unlicense.org>
    #

    # We use this to print to the terminal when the context
    # of STDOUT is something other than the pty.
    declare -r TTY="$(tty)"

    # -----------------------------------------------------------------------------
    # tsws [addr [, port]]
    # -----------------------------------------------------------------------------
    #
    # Start the Totally Simple Web Server.
    #
    # ---------
    # Arguments
    # ---------
    #
    # - addr: IP address (or hostname) to listen on. Optional. If not
    # supplied the default value is 127.0.0.1
    #
    # - port: Port to listen on. Optional. If not supplied the default
    # value is 18080
    #
    # -------------
    # Example usage
    # -------------
    #
    # # Launch the webserver. This version will not return, it will loop forever.
    # tsws localhost 8080
    #
    # # Alternatively, launch the webserver and return immediately.
    # tsws localhost 8080 &
    # # Catch the PID so we can wait or kill later.
    # declare tsws_pid=$!
    # # Launch a browesr.
    # firefox "http://localhost:8080"
    # # Done with other processing, join webserver.
    # wait ${tsws_pid}
    #
    #
    # -------------------
    # Theory of operation
    # -------------------
    #
    # The nc program opens a network port and begins listening. When an inbound
    # connection is made, the STDOUT of nc is pushed to a FIFO pipe. The
    # _tsws_response function runs concurrently and waits for input from the FIFO
    # pipe. When _tsws_response finds an HTTP request there, it processes and
    # returns a well-formed HTTP response back to nc STDIN. nc sends this
    # response back to the requesting client.
    #
    # --------------------------------------------------------------------------
    #
    # +----+ (1)
    # Browser <===> The Internet <===> | nc | ---> FIFO pipe ---+
    # +----+ |
    # (0) ^ |
    # | |
    # +-- _tsws_response <--+
    #
    # - 1: STDOUT of `nc` process which carries HTTP requests.
    # - 0: STDIN of `nc` process which carries HTTP responses.
    # - _tsws_response: handler function reads requests, produces responses.
    #
    # --------------------------------------------------------------------------
    # Diagram: Theory of operation
    #
    # This model almost certainly has issues with concurrency. It is useful for
    # a single local user or demonstration purposes, but please do not use it
    # as a production web server connected to the internet.
    #
    # ------------
    # Requirements
    # ------------
    #
    # - nc (netcat) handles the network listen call for us and binds
    # stdin and stdout of the nc process to connected clients.
    #
    # - mkfifo: A FIFO pip connects the output of nc to our
    # _tsws_response function which processes requests and sends
    # responses back through stdin of nc to browser client.
    #
    # - wc -c: For calculating Content-Length.
    #
    # - cat: For pushing files requests and responses through pipes.
    #
    function tsws {
    [ -z "$1" ] && local -r addr='127.0.0.1' || local -r addr="$1"
    [ -z "$2" ] && local -r port=18080 || local -r port="$2"
    local -r fifo="$(mktemp -u)"
    mkfifo -m 600 "${fifo}"
    trap "rm ${fifo}" EXIT INT TERM HUP
    nc -kl "${addr}" ${port} \
    0< <(_tsws_response "${fifo}") \
    1> >(while : ; do cat - > "${fifo}"; done) # Loop keeps pipe open.
    }

    # -----------------------------------------------------------------------------
    # _tsws_response(fifo)
    # -----------------------------------------------------------------------------
    #
    # Internal workhorse function for handling requests and responses for tsws.
    # Do not call it directly.
    #
    function _tsws_response {
    local method path httpvers callback content_type
    local isfunc obf respf status msg
    method=""
    while : ; do # Run forever.
    while read -r line; do
    line="$(sed 's/\r//g' <<< "${line}")" # Replace CRLF with /n
    if [ -n "${line}" ]; then
    # ${line} is not empty, it is either a "Request-Line" or a header
    # line. If we have no 'method' yet we assume it is a Request-Line.
    # http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
    if [ -z "${method}" ]; then
    read -r method path httpvers <<< "${line}"
    continue
    fi
    # TODO: if we cared about any of the request headers, here is the
    # place to read them by parsing ${line}.
    else
    # ${line} is empty, so we received two consecutive CRLF.
    # Process the request.
    #
    # Currently all "files" served up by the server are functions in this
    # script that return content. This shows how dynamic content can be
    # served and keeps this example all in one single file. It should be
    # easy to adapt this to also read real files from disk Hint: obf below
    # and use `file` to get content_type.
    callback="www$(sed -e 's/\//_/g' -e 's/\./_/g' <<< "${path}")"
    [ "${callback}" = "www_" ] && callback="www_index"
    content_type="${callback}_Content_Type"
    content_type="${!content_type}"
    [ -z "${content_type}" ] && content_type="text/plain"
    obf="$(mktemp -u)"
    case "${method:?}" in
    GET)
    local -f "${callback}" > /dev/null
    isfunc=$(( ! $? ))
    if [ ${isfunc} = 1 ]; then
    status=200; msg="OK"
    ${callback} > "${obf}"
    else
    status=404; msg="Not Found"
    printf $'Not found: %s.' "${path}" > "${obf}"
    fi
    ;;
    *)
    status=500; msg="Internal Server Error"
    printf $'Server Error: unknown method %s.' "${method}" > "${obf}"
    ;;
    esac
    respf="$(mktemp)"
    # Output headers.
    printf $'HTTP/1.1 %s %s\r\n' "${status:?}" "${msg:?}" >> "${respf}"
    printf $'Content-Length: %s\r\n' "$(cat "${obf}"|wc -c)" >> "${respf}"
    printf $'Content-Type: %s\r\n' "${content_type}" >> "${respf}"
    printf $'Connection: close\r\n' >> "${respf}"
    printf $'\r\n' >> "${respf}"
    printf $'%s %s\n' "${method}" "${path}" >${TTY} # Show request in term.
    cat "${respf}" >${TTY} # Show response headers in term.
    # Write header and body to the stdin of `nc`.
    cat "${respf}" "${obf}"
    rm "${respf}" "${obf}"
    method=""
    fi
    done < "$1"
    done
    }


    # +---------------------------------------------------------------------------+
    # | WWW FILES |
    # +---------------------------------------------------------------------------+

    declare www_index_Content_Type="text/html; charset=utf-8"
    function www_index {
    cat <<EOF
    <!DOCTYPE html>
    <html>
    <head>
    <title>Hi!</title>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script type="text/javascript" src="/site.js"></script>
    <style type="text/css">@import url("/style.css");</style>
    </head>
    <body>
    <a href="https://gist.github.com/dfletcher/4763be3295bd5638b797" title="Fork me on GitHub"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/e7bbb0521b397edbd5fe43e7f760759336b5e05f/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677265656e5f3030373230302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png"></a>
    <img class="graphic" src="/graphic.jpg" />
    <h1>Totally Simple Web Server</h1>
    <b>&copy; 2015 Dave Fletcher</b><br>
    <em>All rights reserved</em><br><br>
    status: ${status}<br>
    statusmsg: ${statusmsg}<br>
    method: ${method}<br>
    path: ${path}<br>
    httpvers: ${httpvers}<br>
    callback: ${callback}<br>
    </body>
    </html>
    EOF
    }

    declare www_style_css_Content_Type="text/css"
    function www_style_css {
    cat <<\EOF
    @import url(//fonts.googleapis.com/css?family=Lato:400,700,400italic);
    BODY {
    font-family: 'Lato', sans-serif; margin: 10%;
    }
    .graphic {
    float: right; margin-left: 3em;
    }
    EOF
    }

    declare www_site_js_Content_Type="text/javascript"
    function www_site_js {
    cat <<\EOF
    (function ($) {
    //$(document).ready(function() { alert('hi!'); });
    }(jQuery));
    EOF
    }

    declare www_graphic_jpg_Content_Type="image/jpeg"
    function www_graphic_jpg {
    base64 -d <<\EOF
    /9j/4AAQSkZJRgABAQEASABIAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkz
    ODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2Nj
    Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCAFvAUoDAREA
    AhEBAxEB/8QAGwABAAIDAQEAAAAAAAAAAAAAAAECAwQFBgf/xAA9EAABAwIEBAMFBwMDBAMAAAAB
    AAIDBBEFEiExE0FRYQYicRQyUoGRFSNCYqGx0TNywSRDgiWS4fFjsvD/xAAaAQEAAwEBAQAAAAAA
    AAAAAAAAAQIDBAUG/8QAKxEBAAICAgIBBAEFAAMBAAAAAAECAxEhMQQSQRMiMlFhBRQjQnEzUoGR
    /9oADAMBAAIRAxEAPwD6AgICAgICAgICAgICAgICAgICAgICAghAQEEoCAgICAgICAgICAgICAgI
    CAgICAgICAgICAgICAgICAgICCEAkBBUutuQ0IKGaMfiJQV40R6oJytdqyRzT6/ygo6aWn1mbmj+
    NvL1CDYY9sjQ5hBadiEFkBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQQgxyyhml9f2Q
    cyvxiCiiL3PA7ncoOEcbmq7uBMbOXxH+FEphrvri534nnuSVSbRHa0RM9KiefdsL/UCyr9Sq3pZt
    U+KTRPGYvb2deymLwiaTD0FFiQmaBJzWkTtRSV5wyrY9p/0kxsR8B6qUOlNMI2ggsHdzrBBriokf
    7r7/ANkRI+qC2afrL/2NQY5Kmpi1yZx0dGR+ougpDjdI+YQzO4ErtAHnRx7FB0hqglAQEBAQEBAQ
    EBAQEBAQEBAQEBAQEBAQEBAQEGOaQRRlx+SDg4tiTKSmfNIb9BzJ6IPHDj4lUe0VJNifK0fsFEzq
    ExG2+3hRj7wFwbuxmw9SsZv/ADqHRXFMvQeH20dfDJkgMT4iA4HW/e6tSKzG4Z5Pes6mXYNBGBo0
    fRaM9tebDYXjVg+irNYntMWmOnPdROpJLxm7L7dFTU1nhbftGpbc7faMOkidqQLhbKIw14NHG51i
    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
    AgICCUBAQEBAQEBB/9k=
    EOF
    }


    # +---------------------------------------------------------------------------+
    # | Main |
    # +---------------------------------------------------------------------------+

    [ -n "$1" ] && addr="$1" || addr="127.0.0.1"
    [ -n "$2" ] && port="$2" || port=18080
    tsws "${addr}" "${port}"
  10. @dfletcher dfletcher created this gist Sep 5, 2015.
    687 changes: 687 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,687 @@
    #!/bin/bash

    # --------------------------------
    # Totally Simple Web Server (TSWS)
    # --------------------------------
    #
    # (c) 2015 Dave Fletcher
    # All Rights Reserved
    #
    # This is free and unencumbered software released into the public domain.
    #
    # Anyone is free to copy, modify, publish, use, compile, sell, or
    # distribute this software, either in source code form or as a compiled
    # binary, for any purpose, commercial or non-commercial, and by any
    # means.
    #
    # In jurisdictions that recognize copyright laws, the author or authors
    # of this software dedicate any and all copyright interest in the
    # software to the public domain. We make this dedication for the benefit
    # of the public at large and to the detriment of our heirs and
    # successors. We intend this dedication to be an overt act of
    # relinquishment in perpetuity of all present and future rights to this
    # software under copyright law.

    # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    # IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
    # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
    # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    # OTHER DEALINGS IN THE SOFTWARE.
    #
    # For more information, please refer to <http://unlicense.org>
    #

    declare -r TTY="$(tty)"
    declare ncpid reqfifo

    # ----------------
    # tsws(addr, port)
    # ----------------
    #
    # Totally Simple Web Server.
    #
    # Arguments: - addr: IP address (or hostname) to listen on.
    #
    # - port: Port to listen on.
    #
    # Exports: - reqfifo: A FIFO file pipe used while running.
    # Caller should remove when done.
    #
    # - ncpid: PID of the `nc` process that handles
    # http connections. Caller should kill when done.
    #
    #
    # Requires: - nc (netcat)
    #
    # Example usage:
    #
    # tsws 127.0.0.1 8080
    # trap 'kill ${ncpid}; rm ${reqfifo}' EXIT INT TERM HUP
    #
    function tsws {
    [ -z "$1" ] && local -r addr='127.0.0.1' || local -r addr="$1"
    [ -z "$2" ] && local -r port=18080 || local -r port="$2"
    export reqfifo="$(mktemp -u)"
    mkfifo -m 600 "${reqfifo}"
    nc -kl "${addr}" ${port} \
    0< <(_tsws_response "${reqfifo}") \
    1> >(while : ; do cat - > "${reqfifo}"; done) & # Loop keeps pipe open.
    export ncpid=$!
    }

    # --------------------
    # _tsws_response(fifo)
    # --------------------
    #
    # Internal workhorse function for handling requests and responses for tsws.
    # Do not call it directly.
    #
    function _tsws_response {
    local method path httpvers callback content_type
    local isfunc obf respf status msg
    method=""
    while : ; do # Run forever.
    while read -r line; do
    line="$(sed 's/\r//g' <<< "${line}")" # Replace CRLF with /n
    if [ -n "${line}" ]; then
    # ${line} is not empty, it is either a "Request-Line" or a header
    # line. If we have no 'method' yet we assume it is a Request-Line.
    # http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
    if [ -z "${method}" ]; then
    read -r method path httpvers <<< "${line}"
    continue
    fi
    # TODO: if we cared about any of the request headers, here is the
    # place to read them by parsing ${line}.
    else
    # ${line} is empty, so we received two consecutive CRLF.
    # Process the request.
    #
    # Currently all "files" served up by the server are functions in this
    # script that return content. This shows how dynamic content can be
    # served and keeps this example all in one single file. It should be
    # easy to adapt this to also read real files from disk Hint: obf below
    # and use `file` to get content_type.
    callback="www$(sed -e 's/\//_/g' -e 's/\./_/g' <<< "${path}")"
    [ "${callback}" = "www_" ] && callback="www_index"
    content_type="${callback}_Content_Type"
    content_type="${!content_type}"
    [ -z "${content_type}" ] && content_type="text/plain"
    obf="$(mktemp -u)"
    case "${method:?}" in
    GET)
    local -f "${callback}" > /dev/null
    isfunc=$(( ! $? ))
    if [ ${isfunc} = 1 ]; then
    status=200; msg="OK"
    ${callback} > "${obf}"
    else
    status=404; msg="Not Found"
    printf $'Not found: %s.' "${path}" > "${obf}"
    fi
    ;;
    *)
    status=500; msg="Internal Server Error"
    printf $'Server Error: unknown method %s.' "${method}" > "${obf}"
    ;;
    esac
    respf="$(mktemp)"
    # Output headers.
    printf $'HTTP/1.1 %s %s\r\n' "${status:?}" "${msg:?}" >> "${respf}"
    printf $'Content-Length: %s\r\n' "$(cat "${obf}" | wc -c)" >> "${respf}"
    printf $'Content-Type: %s\r\n' "${content_type}" >> "${respf}"
    printf $'Connection: close\r\n' >> "${respf}"
    printf $'\r\n' >> "${respf}"
    echo "${method} ${path}" > ${TTY} # Show request in term.
    cat "${respf}" > ${TTY} # Show response headers in term.
    # Write header and body to the stdin of `nc`.
    cat "${respf}" "${obf}"
    rm "${respf}" "${obf}"
    method=""
    fi
    done < "$1"
    done
    }


    # +---------------------------------------------------------------------------+
    # | WWW FILES |
    # +---------------------------------------------------------------------------+

    declare www_index_Content_Type="text/html; charset=utf-8"
    function www_index {
    cat <<EOF
    <!DOCTYPE html>
    <html>
    <head>
    <title>Hi!</title>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script type="text/javascript" src="/site.js"></script>
    <style type="text/css">@import url("/style.css");</style>
    </head>
    <body>
    status: ${status}<br>
    statusmsg: ${statusmsg}<br>
    method: ${method}<br>
    path: ${path}<br>
    httpvers: ${httpvers}<br>
    callback: ${callback}<br>
    <img src="/graphic.jpg" />
    </body>
    </html>
    EOF
    }

    declare www_style_css_Content_Type="text/css"
    function www_style_css {
    cat <<\EOF
    BODY { margin: 10%; }
    EOF
    }

    declare www_site_js_Content_Type="text/javascript"
    function www_site_js {
    cat <<\EOF
    (function ($) {
    //$(document).ready(function() { alert('hi!'); });
    }(jQuery));
    EOF
    }

    declare www_graphic_jpg_Content_Type="image/jpeg"
    function www_graphic_jpg {
    base64 -d <<\EOF
    /9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QNvaHR0cDov
    L25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENl
    aGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4
    OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjAtYzA2MCA2MS4xMzQ3NzcsIDIwMTAvMDIvMTItMTc6
    MzI6MDAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5
    OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHht
    bG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0i
    aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1w
    PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9
    InhtcC5kaWQ6RkY3RjExNzQwNzIwNjgxMTk3QTVDRDM0NzZENzAxMEEiIHhtcE1NOkRvY3VtZW50
    SUQ9InhtcC5kaWQ6MzkxMDQyNTI5RjE2MTFFMkJFQTVCNDNFN0U0RjgzNkMiIHhtcE1NOkluc3Rh
    bmNlSUQ9InhtcC5paWQ6MzkxMDQyNTE5RjE2MTFFMkJFQTVCNDNFN0U0RjgzNkMiIHhtcDpDcmVh
    dG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giPiA8eG1wTU06RGVyaXZlZEZy
    b20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozODhDQjhENTk1QjIxMUUyOUUyOEI1NDBEMDlE
    Q0U1MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozODhDQjhENjk1QjIxMUUyOUUyOEI1NDBE
    MDlEQ0U1MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94
    cGFja2V0IGVuZD0iciI/Pv/uAA5BZG9iZQBkwAAAAAH/2wCEAAYEBAQFBAYFBQYJBgUGCQsIBgYI
    CwwKCgsKCgwQDAwMDAwMEAwODxAPDgwTExQUExMcGxsbHB8fHx8fHx8fHx8BBwcHDQwNGBAQGBoV
    ERUaHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fH//AABEI
    AgwB2wMBEQACEQEDEQH/xACvAAEAAQUBAQAAAAAAAAAAAAAABAIDBQYHAQgBAQACAwEBAAAAAAAA
    AAAAAAABAgMEBQYHEAABAwMCAwUGBAMHAgcAAwABAAIDEQQFIRIxQQZRYSITB3GBoTJCFJFSIxWx
    YgjB0XKCM0MWkiTw4aKyU2Ml8cLSEQEAAgIBAgMFBwMDBAEFAAAAAQIRAwQhEjFBBVFhIjITcYGR
    obHRBkJSYsHhFPByIxUz8YKiUxb/2gAMAwEAAhEDEQA/APqlAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
    AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQKoFUBAQEBAQEBAQEBA
    QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECqC2Zq/IN1OLjo38UF
    iS9tmaSzgH8rUFl2Ux3Aucfef71GU4Gz4+cUDpGE8w57f4FTkwpfBk4hvsboXDR/sXFDX2SNAI96
    Ie4/OwXNw6zmY61yDBV9rJxI/Mw8HD2IMkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
    CAgICAgICAgICAgICAgICAgICAgpkkYxhe40aBUlBhMhnbWFu+Y+H6IRz73f3Ilyvqz1vgF8cXii
    Lq6B2v2H9KM9jnjie5vwUZIhrd71jevYXXF3I9zuLGO8qMdwDfF+JWKZ82TDGHOXcxrBZvl7w17q
    +9xWG3J1x5stdF58km16izlqa/b3MDe1hcKe4Ej4KscqntWnjX9jeulPUe7Lmxyy+YBo7dUOH+Jp
    /iFn17on3sFqTDe7+K16nxm6B/2+Utx5lpcN0cx414j6TzWdjXeiup5Mvj5or0CPKY95hvY+FSOD
    9fzURC/c594lMbJ7VjuUbPMupf8ApjDafiUFLbzLyt3Nfc07W2jY/hK6qDx91nI2lzXTkjX9S1Y/
    4RPaUGKufUKbFmuXsHmAfNNbtkY8AczBO1jj/kc9EZbF0/1RgOobL7zDX0V9ADteYnVcxw4te35m
    kdhCJyyiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDWuoMy1r
    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
    Bd/bYuxB7+3R/lQP29nYgft8fYg9+wj7EHn7fH2IH7fH2IH7fH2IH7ezsQP2+PsQejHx9iCoWEfY
    g9+xZ+VBULNg5IKhasHJB79s3sQVeS3sQeiIdiD3y0HoYgrAQehAQEBAQEBAQEBAQEBAQEBAQEBA
    QEBAQECgQKIFAgUQECgQKBAoECg7ECg7ECg7EDa3sCDza3sCBtb2BB7QdiBQIFAgUCBQIFAgUCBQ
    diBQdiBQdiBQdiBQdiBQIFAgUCBQIFAgUCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
    ICAgICAgICAgICAgIP/Z
    EOF
    }


    # +---------------------------------------------------------------------------+
    # | Main |
    # +---------------------------------------------------------------------------+

    [ -n "$1" ] && addr="$1" || addr="127.0.0.1"
    [ -n "$2" ] && port="$2" || port=18080
    tsws "${addr}" "${port}"
    trap 'kill ${ncpid}; rm ${reqfifo}' EXIT INT TERM HUP
    wait ${ncpid}