hn-classics/_stories/2007/6222215.md

12 KiB

created_at title url author points story_text comment_text num_comments story_id story_title story_url parent_id created_at_i _tags objectID year
2013-08-16T04:46:04.000Z Webserver in bash (2007) http://paulbuchheit.blogspot.ca/2007/04/webserver-in-bash.html soundsop 53 14 1376628364
story
author_soundsop
story_6222215
6222215 2007

Source

Paul Buchheit: Webserver in bash

Paul Buchheit

Friday, April 13, 2007

Webserver in bash

And not using perl or any of that fancy stuff. It's the inane things that keep me awake at night.

Getting nc to behave turned out to be the most difficult part. It won't exit until both ends of the connection are closed. Correction, making blogger not mangle this code was the most difficult part.

#!/bin/bash

web.sh -- http://localhost:9000/hello?world

RESP=/tmp/webresp
[ -p $RESP ] || mkfifo $RESP

while true ; do
( cat $RESP ) | nc -l -p 9000 | (
REQ=while read L && [ " " "<" "$L" ] ; do echo "$L" ; done
echo "[date '+%Y-%m-%d %H:%M:%S'] $REQ" | head -1
cat >$RESP <<EOF
HTTP/1.0 200 OK
Cache-Control: private
Content-Type: text/plain
Server: bash/2.0
Connection: Close
Content-Length: ${#REQ}

$REQ
EOF
)
done

Update: Fixed script so that it also work in Linux, where tr lacks the -u option.

Posted by Paul Buchheit at 5:53 PM

6 comments:

abbot said...
It should be like this to behave with both gnu and bsd utils:
( cat $RESP ) | nc -l 9000 | sed -ue 's/r//g' | (

2:29 PM

Paul Buchheit said...
Thanks abbot, but OSX sed doesn't support -u. I found a way to get rid of tr instead.

3:53 PM

brett said...

well that wasted a bit of my day.
how about a version that takes a document root and serves html files:

#!/bin/bash

pass in document root as first arg

web.sh ~/Sites/test

DOC_ROOT=$1
RESP=/tmp/webresp
[ -p $RESP ] || mkfifo $RESP

while true ; do
( cat $RESP ) | nc -l -p 9000 | tr -ud 'r' | (
REQ=while read L && [ -n "$L" ] ; do echo "$L" ; done
SERV_PATH=echo "$REQ" | head -1 | cut -f2 -d" "
FULL_PATH="$DOC_ROOT$SERV_PATH"
echo $FULL_PATH
if [ -f "$FULL_PATH" ]; then
RESP_BODY=cat $FULL_PATH
RESP_CODE="200 OK"
else
RESP_BODY="not found

$REQ"
RESP_CODE="404 NOT FOUND"
fi
echo "[date '+%Y-%m-%d %H:%M:%S'] $REQ" | head -1
cat >$RESP <<EOF
HTTP/1.0 $RESP_CODE
Cache-Control: private
Content-Type: text/html
Server: bash/2.0
Connection: Close
Content-Length: ${#RESP_BODY}

$RESP_BODY
EOF
)
done

11:00 PM

andreas said...
Another web server written in bash: http://sourceforge.net/projects/mws/

6:23 AM

Bill Blum said...
This both intrigues me and scares me...

7:34 AM

ralph said...

Does the HTTP spec. say the time must be GMT rather than your local timezone, e.g. "TZ=GMT date ...".

Cheers, Ralph Corderoy.

9:46 AM

Post a Comment

Newer Post Older Post Home

Subscribe to: Post Comments (Atom)

About Me

Paul Buchheit
http://en.wikipedia.org/wiki/Paul_Buchheit https://twitter.com/paultoo

View my complete profile

Blog Archive

| -----|
|

|

|

Awesome Inc. theme. Powered by Blogger.

[*[5:53 PM]: 2007-04-13T17:53:00-07:00