### 概要 なんとなく作り始めてみました。
セキュリティホールがいっぱいあると思われるので、ローカルホストの外に出しちゃダメね。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 ```sh <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
11
```html
&lt;html>
    &lt;head>
        &lt;title>テスト&lt;/title>
    &lt;/head>
    &lt;body>
    &lt;p class="hoge">hello world&lt;/p>
    &lt;p>2014年 1月16日 木曜日 03時22分14秒 JST&lt;/p>
    &lt;/body>
&lt;/html> 

#### <Controller>
##### app/index.sh ```sh #!/bin/sh render OK HTML index.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
</div>
</div>
<div class="section">
    #### lib/render
    ```sh
#!/bin/sh

status=$1
content=$2
html=$3

cat lib/status/${status}
cat lib/contenttype/${content}
echo ""
printf "cat &lt;&lt;++EOF\n`cat app/html/${html}` \n++EOF\n" | sh

#### <基盤>
##### router.sh ```sh #!/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

 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
35
36
37
38
</div>
<div class="section">
    ##### bin/listen
    ```sh
#!/usr/local/bin/bash

LISTEN_PORT=8080

function server() {
    # request
    IFS=&#39; &#39;
    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}" >&amp;2
    else
        echo "process failed : ${HEADERS[Host]};`date`; ${method}; ${path}" >&amp;2
    fi
    unset HEADERS
}

PIPE_FILE=tmp/server.$$
if [ ! -e "${PIPE_FILE}" ];
then
    mkfifo "${PIPE_FILE}"
fi
exec {FD}&lt;>"${PIPE_FILE}"
trap "test -e ${PIPE_FILE} &amp;&amp; rm -f ${PIPE_FILE};exit" 0 HUP INT QUIT

server | nc -l ${LISTEN_PORT} >&amp;${FD}

### 参考URL