### 概要 なんとなく作り始めてみました。
セキュリティホールがいっぱいあると思われるので、ローカルホストの外に出しちゃダメね。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> ```※出力はこうなります ```html <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 ```sh #!/bin/sh render OK HTML index.html ```
#### lib/render ```sh #!/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 ```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 ```
##### bin/listen ```sh #!/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