2014/06/19

Recent entries from same category

  1. Go 言語プログラミングエッセンスという本を書きました。
  2. errors.Join が入った。
  3. unsafe.StringData、unsafe.String、unsafe.SliceData が入った。
  4. Re: Go言語で画像ファイルか確認してみる
  5. net/url に JoinPath が入った。

golang で Web と言えば、net/http でハンドラ書いて http.ListenAndServe を呼び出すサーバ方式が思い浮かびますが、他にも選択はあるはずです。
mattn/go-cgi - GitHub
https://github.com/mattn/go-cgi
golang で CGI が書けます。

まず上記リポジトリを clone して go-cgi.exe を作ります。 git clone https://github.com/mattn/go-cgi
cd go-cgi
go build
次に「管理ツール」から「インターネットインフォメーションサービス」を起動し、サイトに仮想ディレクトリを足します。
IIS
「ハンドラーマッピング」を選び、一覧上を右クリックして「スクリプトマップの追加」を選択します。
スクリプトマップ
「要求パス」は *.go、「実行可能ファイル」に先程ビルドした go-cgi.exe へのパスを、「名前」に CGI-go を入力します。
要求の制限
「要求の制限」をクリックして、「要求のマップ先が次の場合のみハンドラーを呼び出す」にチェックを入れ、「ファイル」を選び、あとは「OK」をクリックします。

最後に画面左のツリーの最上部にあるPC名をクリックして「ISAPIおよびCGIの制限」を選び、一覧に表示される CGI-go を右クリックして「許可」に変更します。
ISAPIおよびCGIの制限

これで 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
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"))
    }))
}
簡単ですね。Windows の皆さんもぜひ golang で Web やりましょう。
Posted at by