3 ##########################################################################
6 # This is just a bit of fun. Please don't trust it for anything serious! #
7 ##########################################################################
11 SERVER_ROOT
="${SERVER_ROOT:-$PWD}"
23 print_log
"Server running on port $PORT in $SERVER_ROOT"
31 echo "$(date -Iseconds) $@"
34 function handle_connection
{
37 STATE_FUNC
="handle_read_request_status_line"
38 while [ -n "$STATE_FUNC" ]; do
45 function start_netcat
{
49 function close_request
{
51 kill "$COPROC_PID" &> /dev
/null || true
52 wait "$COPROC_PID" &> /dev
/null || true
55 function handle_read_request_status_line
{
57 print_log
"$REQUEST_LINE"
59 read method path ignored
< <(echo "$REQUEST_LINE")
62 check_valid_method ||
return 0
63 check_path_is_under_server_root ||
return 0
64 find_index_in_request_file
65 check_request_file_exists ||
return 0
67 STATE_FUNC
="handle_read_request_to_end"
70 function check_valid_method
{
71 if [ "$method" != "GET" ]; then
72 STATE_FUNC
="write_error_response_405"
77 function check_path_is_under_server_root
{
78 abspath
="$(cd "$
(dirname "$REQUEST_FILE")" && pwd)"
79 if ! echo "$abspath" |
grep -q "^$PWD"; then
80 STATE_FUNC
="write_error_response_400"
85 function find_index_in_request_file
{
86 if [ ! -d "$REQUEST_FILE" ]; then
90 for filename
in index.html index.txt
; do
91 if [ -f "${REQUEST_FILE}/${filename}" ]; then
92 REQUEST_FILE
="${REQUEST_FILE}/${filename}"
98 function check_request_file_exists
{
99 if [ ! -f "$REQUEST_FILE" ]; then
100 STATE_FUNC
="write_error_response_404"
105 function handle_read_request_to_end
{
108 if [ -z "$REQUEST_LINE" ]; then
109 STATE_FUNC
="write_response"
113 function read_request_line
{
115 REQUEST_LINE
="$(echo "$REQUEST_LINE" | tr -d '
')"
118 function write_response
{
120 cat <<EOT >&"${COPROC[1]}"
123 Content-Type: $(file -bi "$REQUEST_FILE")
126 $(cat "$REQUEST_FILE")
130 function write_error_response
{
134 cat <<EOT >&"${COPROC[1]}"
135 HTTP/1.0 $code $message
140 <title>$code $message</title>
143 <h1>$code $message</h1>
149 function write_error_response_400
{
150 write_error_response
400 "Bad Request"
153 function write_error_response_404
{
154 write_error_response
404 "File Not Found"
157 function write_error_response_405
{
158 write_error_response
405 "Unsupported method"
161 function check_dependencies
{
166 function check_bash
{
167 if [ "${BASH_VERSINFO[0]}" -lt 4 ]; then
168 echo "ERROR! Requires Bash 4+ for coproc support"
173 function check_netcat
{
174 if ! nc
-h 2>&1 |
head -n1 |
grep -q '^OpenBSD netcat'; then
175 echo "ERROR! Requires OpenBSD netcat to be installed"