CentOS6.4+nginx+go(FastCGI)+FileUpload
nginxのインストール
特に何もしていない
cat <<'EOF' > /etc/yum.repos.d/nginx.repo [nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/6/$basearch/ gpgcheck=0 enabled=1 EOF yum install nginx
Goのinstall
# Ver1.2 x64 wget https://go.googlecode.com/files/go1.2.linux-amd64.tar.gz # extract to /usr/local/go tar -C /usr/local -xzf go1.2.linux-amd64.tar.gz # add the path of go to PATH env var export PATH=$PATH:/usr/local/go/bin
nginxのGoファイルの設定
default.confで以下を追加
location ~ \.go$ { fastcgi_pass 127.0.0.1:13524; include fastcgi.conf; client_max_body_size 100M; }
Goのアプリは13524にListenし、ファイルの最大サイズは100MBとした。
GoAPPを作る
中身はpostでファイルを受け取って保存する。
基本的には↓のサイトを参考に作成。
http://sanatgersappa.blogspot.jp/2013/03/handling-multiple-file-uploads-in-go.html
FastCGIで動かすところは、以下を参考に作成
http://mwholt.blogspot.jp/2013/05/writing-go-golang-web-app-with-nginx.html
以下ソース
package main import ( "net" "net/http" "net/http/fcgi" "io" "os" ) type FastCGIServer struct{} func (s FastCGIServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) { switch req.Method { case "GET": resp.Write([]byte("<h1>Get method</h1>")) case "POST": reader, err := req.MultipartReader() if err != nil { http.Error(resp, err.Error(), http.StatusInternalServerError) return } //copy each part to destination. for { part, err := reader.NextPart() if err == io.EOF { break } //if part.FileName() is empty, skip this iteration. if part.FileName() == "" { continue } dst, err := os.Create("/usr/share/nginx/html/files/" + part.FileName()) defer dst.Close() if err != nil { http.Error(resp, err.Error(), http.StatusInternalServerError) return } if _, err := io.Copy(dst, part); err != nil { http.Error(resp, err.Error(), http.StatusInternalServerError) return } } resp.Write([]byte("<h1>Uploaded</h1>")) default: resp.WriteHeader(http.StatusMethodNotAllowed) } } func main() { listener, _ := net.Listen("tcp", "127.0.0.1:13524") srv := new(FastCGIServer) fcgi.Serve(listener, srv) }
GETでは基本的に何もしていない。
出力先のディレクトリ、この場合は「/usr/share/nginx/html/files/」は予め作成しておく。
GoAPPの起動
runコマンドでBuildして起動。
go run uploader.go
buildコマンドでnativeな実行ファイルを作ってから実行
go build uploader.go
ファイルをアップするテストフォーム
先ほどのサイトの例を参考に作る。
actionには、GoAPPのURLを指定。
<!DOCTYPE html> <html> <head> <title>File Upload Test</title> </head> <body> <div> <h1>File Upload Test</h1> <form class="form-signin" method="post" action="/uploader.go" enctype="multipart/form-data"> <fieldset> <input type="file" name="myfiles" id="myfiles" multiple="multiple"> <input type="submit" name="submit" value="Submit"> </fieldset> </form> </div> </body> </html>
cURLでファイルを送ってみる
"targetfile.txt"を送ってみる場合。
curl -F 'file=@targetfile.txt' http://localhost/uploader.go