概要
なんとなく作り始めてみました。
セキュリティホールがいっぱいあると思われるので、ローカルホストの外に出しちゃダメね。GItHubのリポジトリはこちら → https://github.com/kunst1080/shwaf/
ざっくりとした仕様など
動作確認はFreeBSD 8.3でのみ実施。
最近Play Frameworkを使ってるので、だいたいそんなかんじ。
- httpサーバはNetCatにおまかせ
- ルーティングは「router.sh」に書く
- modelはひとまずなし。
- viewはhtml。バッククォートでシェルスクリプトが書ける
- htmlの内容がヒアドキュメントとしてcatコマンドに埋め込まれます
- controllerは普通のシェルスクリプト
最低限必要なports
/usr/local/bin/bash
設計
- bin/start が bin/listen を無限ループで呼び出す
- bin/listen は、1回のリクエスト毎にリクエストヘッダを解析し、メソッド名とurlを引数にrouter.shを呼び出す
- router.sh はシェル内の記述に則り、controller(app/*.sh)を呼び出す
- controller(app/*.sh)はいろいろ処理した後、renderコマンドでhtml(app/html/*.html)を出力する
- renderコマンドにはレスポンスコード(OK|BAD_REQUEST)・コンテキストタイプ・出力するhtmlファイルのファイル名を渡す
ソースコード一部抜粋
<View>
app/html/index.html
1
2
3
4
5
6
7
8
9
10
|
<html>
<head>
<title>テスト</title>
</head>
<body>
<p class="hoge">hello world</p>
<p>`date`</p>
</body>
</html>
|
※出力はこうなります
1
2
3
4
5
6
7
8
9
10
|
<html>
<head>
<title>テスト</title>
</head>
<body>
<p class="hoge">hello world</p>
<p>2014年 1月16日 木曜日 03時22分14秒 JST</p>
</body>
</html>
|
<Controller>
app/index.sh
1
2
3
|
#!/bin/sh
render OK HTML index.html
|
lib/render
1
2
3
4
5
6
7
8
9
10
11
|
#!/bin/sh
status=$1
content=$2
html=$3
cat lib/status/${status}
cat lib/contenttype/${content}
echo ""
printf "cat <<++EOF\n`cat app/html/${html}` \n++EOF\n" | sh
|
<基盤>
router.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#!/bin/sh
PATH=$PATH:lib
method=$1
url=$2
case "${url}" in
"/" | "/index.html")
app/index.sh
return $?
;;
*)
render BAD_REQUEST PLAIN error.txt
return 9
;;
esac
|
bin/listen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#!/usr/local/bin/bash
LISTEN_PORT=8080
function server() {
# request
IFS=' '
read -u ${FD} "method" "path" "protocol"
# header
# TODO:後で実装。awk使ったほうがいいかも。
declare -A HEADERS
HEADERS[Host]="ServerName"
./router.sh "${method}" "${path}"
# status
if [ $? -eq 0 ] ; then
echo "${HEADERS[Host]};`date`; ${method}; ${path}" >&2
else
echo "process failed : ${HEADERS[Host]};`date`; ${method}; ${path}" >&2
fi
unset HEADERS
}
PIPE_FILE=tmp/server.$$
if [ ! -e "${PIPE_FILE}" ];
then
mkfifo "${PIPE_FILE}"
fi
exec {FD}<>"${PIPE_FILE}"
trap "test -e ${PIPE_FILE} && rm -f ${PIPE_FILE};exit" 0 HUP INT QUIT
server | nc -l ${LISTEN_PORT} >&${FD}
|
参考URL
- NetCatのwikipedia
- パラメータの読み込みなどについては、ここを参考にさせて頂きました