2014/06/19


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 やりましょう。

2014/06/18


GitHub で一番お星さまを貰ったリポジトリを調べてみた。
stars:>1 user:mattn
で GitHub 検索する。(参考URL)
ユーザ名の所はご自分のIDをお使い下さい。ちなみに僕のリポジトリのトップ10は...
リポジトリStar数Fork数
mattn/emmet-vim1854149
mattn/gist-vim88498
mattn/go-gtk48480
mattn/gom43318
mattn/go-sqlite3414108
mattn/webapi-vim20323
mattn/go-xmpp15457
mattn/growl-for-linux15316
mattn/go-webkit13718
mattn/go-v813319
こんな感じでした。vim 物が多いですね。star ありがとうございました。


前回の記事で「peco の使い方が分からない」という意見を幾らか頂いたのでサンプルを。
例えば、Qiita の「Go」タグのRSSを取ってきて、タイトルを一覧して選んだらブラウザが起動するスクリプトを書きたいとする。
@echo off

for /f %%i in ('more +8 %~f0 ^| perl -S - ^| peco --null') do (
  start %%i
  break
)
exit /b 0
use strict;
use warnings;

use XML::Feed;
use YAML::Syck;

my $feed = XML::Feed->parse(URI->new('http://qiita.com/tags/go/feed'))
  or die XML::Feed->errstr;
for my $entry ($feed->entries) {
  print $entry->title . "\0" . $entry->link . "\n";
}
これを peco-feed.bat というファイルに保存して実行すると
peco-feed
タイトルが表示され、選ぶとブラウザが起動して記事を表示してくれます。便利ですね。
※ 実行には perl が必要です。