golang で Web と言えば、net/http でハンドラ書いて http.ListenAndServe を呼び出すサーバ方式が思い浮かびますが、他にも選択はあるはずです。
まず上記リポジトリを clone して go-cgi.exe を作ります。
「ハンドラーマッピング」を選び、一覧上を右クリックして「スクリプトマップの追加」を選択します。 「要求パス」は
最後に画面左のツリーの最上部にあるPC名をクリックして「ISAPIおよびCGIの制限」を選び、一覧に表示される CGI-go を右クリックして「許可」に変更します。
これで IIS 上で拡張子
Apache/nginx で動作させる場合は、これから作る CGI の拡張子を
なお、go コマンドへパスを通していない場合は、これから説明する CGI を置くディレクトリに
さて CGI を書きましょう。上記で仮想ディレクトリをマッピングしたディレクトリに移動し、例として
go-cgi は /tmp/go-cgi(Windows だと %TEMP%\go-cgi)、もしくは CGI ファイルと同じディレクトリに .go-cgi というディレクトリを作り、そこにハッシュ値で管理された go ファイルを生成すると同時にコンパイルして実行しています。
なお、golang の net/http は CGI を書く場合でも http.Handler を使う事が出来ます。
mattn/go-cgi - GitHubgolang で CGI が書けます。
https://github.com/mattn/go-cgi
まず上記リポジトリを clone して go-cgi.exe を作ります。
git clone https://github.com/mattn/go-cgi次に「管理ツール」から「インターネットインフォメーションサービス」を起動し、サイトに仮想ディレクトリを足します。
cd go-cgi
go build
「ハンドラーマッピング」を選び、一覧上を右クリックして「スクリプトマップの追加」を選択します。 「要求パス」は
*.go
、「実行可能ファイル」に先程ビルドした go-cgi.exe へのパスを、「名前」に CGI-go
を入力します。
「要求の制限」をクリックして、「要求のマップ先が次の場合のみハンドラーを呼び出す」にチェックを入れ、「ファイル」を選び、あとは「OK」をクリックします。最後に画面左のツリーの最上部にあるPC名をクリックして「ISAPIおよびCGIの制限」を選び、一覧に表示される CGI-go を右クリックして「許可」に変更します。
これで IIS 上で拡張子
go
のファイルが CGI として実行出来る準備が整いました。Apache/nginx で動作させる場合は、これから作る CGI の拡張子を
cgi
にしてファイルの先頭行に #!/usr/local/bin/go-cgi
といった感じに shebang を書くと動きます。なお、go コマンドへパスを通していない場合は、これから説明する CGI を置くディレクトリに
.go-cgi
というフォルダを作り、そこに env
というファイルを作成します。そこに GOROOT=c:/go
といった感じに GOROOT を教えてあげるおまじないを書くと動く様になると思います。さて CGI を書きましょう。上記で仮想ディレクトリをマッピングしたディレクトリに移動し、例として
foo.go
というファイルを以下の様に作ります。package mainブラウザから
import (
"fmt"
)
func main() {
fmt.Print("Content-Type: text/html;\r\n\r\n")
fmt.Println("Hello World")
}
http://localhost/mattn/foo.go
を開くと Hello World
が表示されるかと思います。go-cgi は /tmp/go-cgi(Windows だと %TEMP%\go-cgi)、もしくは CGI ファイルと同じディレクトリに .go-cgi というディレクトリを作り、そこにハッシュ値で管理された go ファイルを生成すると同時にコンパイルして実行しています。
なお、golang の net/http は CGI を書く場合でも http.Handler を使う事が出来ます。
#! go-cgi簡単ですね。Windows の皆さんもぜひ golang で Web やりましょう。
package main
import (
"fmt"
"net/http"
"net/http/cgi"
)
func main() {
cgi.Serve(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
fmt.Fprintf(w, "Hello %s", r.FormValue("name"))
}))
}