shithub: riscv

ref: fc1ff7705b339d480f15fa934c7df215158c1901
dir: /rc/bin/rc-httpd/rc-httpd/

View raw version
#!/bin/rc
rc_httpd_dir=/rc/bin/rc-httpd
path=(/bin $rc_httpd_dir/handlers)
cgi_path=/bin
SERVER_PORT=80 # default for CGI scripts, may be overridden by the Host header
extra_headers='Server: rc-httpd'
cr=

fn do_log{
	echo `{date} :: $SERVER_NAME :: $request :: \
	$HTTP_USER_AGENT :: $1 :: $HTTP_REFERER >[1=2]
}

fn emit_extra_headers{
	for(header in $extra_headers)
		echo $"header^$cr
}

fn getline{ read | sed 's/'^$"cr^'$//g' }

fn terminate{
	echo `{date} connection terminated >[1=2]
	exit terminate
}

fn trim_input{ read -c $CONTENT_LENGTH }

request=`{getline}
if(~ $#request 0)
	terminate
REQUEST_METHOD=$request(1)
REQUEST_URI=$request(2)
reqlines=''
HTTP_COOKIE=''
done=false
while(~ $"done false){
	line=`{getline}
	if(~ $#line 0)
		done=true
	reqlines=$"reqlines$"line'
'
	h=`{echo $line | awk '{print tolower($1)}'}
	switch($h){
	case ''
		done=true
	case host:
		tmp=`{echo $line(2) | sed 's/:/ /'}
		SERVER_NAME=$tmp(1)
		if(! ~ $#tmp 1)
			SERVER_PORT=$tmp(2)
	case referer:
		HTTP_REFERER=$line(2)
	case user-agent:
		HTTP_USER_AGENT=`{echo $line | sed 's;[^:]+:[ 	]+;;'}
	case content-length:
		CONTENT_LENGTH=$line(2)
	case cookie:
		cookie=`{echo $line | sed 's;^[^:]+:[ 	]*;;'}
		HTTP_COOKIE=$"HTTP_COOKIE^$"cookie^'; '
	}
}
if(~ $REQUEST_URI http://*){
	SERVER_NAME=`{echo $REQUEST_URI | sed '
		s;^http://;;
		s;/.*;;
	'}
	REQUEST_URI=`{echo $REQUEST_URI | sed 's;^http://[^/]+/?;/;'}
}
QUERY_STRING=`{echo $REQUEST_URI | sed 's;[^?]*\??;;'}
params=`{echo $QUERY_STRING | sed 's;\+; ;g'}
location=`{echo $REQUEST_URI | sed 's;\?.*;;'}
location=`{echo $location | sed '
	s;[^/]+/\.\./;/;g
	s;/\./;/;g
	s;//+;/;g
'}
if(~ $REQUEST_METHOD POST){
	if(! ~ $"CONTENT_LENGTH '')
		trim_input | exec $rc_httpd_dir/select-handler
	if not{
		echo 'POST without content-length, assuming no keep-alive.' >[1=2]
		exec $rc_httpd_dir/select-handler
	}
}
if not
	. $rc_httpd_dir/select-handler