見習い魔法使いの日常

果たして魔法が使える日は訪れるのか!?

Goでファイルサーバ!!

背景

困ったことがおこりました。
Unityで作成したゲームを遠く離れた我が弟にやらせてみようと思った時です。
ファイルサイズが大きすぎて、弟に渡す手段がない!!
メールなどには容量の関係で添付できないし、Slackとかなら送れるかもしれないけど弟はPCに疎いので無理。
ということで、弟に渡すために配布サーバ(ファイルサーバ)を作りました。

※ 僕もPCに疎いので、1GBを超えるようなファイルをうまく送れる方法があったら教えて欲しいです。

実装

どうやってつくればいいのか...とググっているとhttp.FileServerなるものがあることを知りました。

package main

import (
	"flag"
	"log"
	"net/http"
	"path/filepath"
	"sync"
	"text/template"
)

type templateHandler struct {
	once     sync.Once
	filename string
	templ    *template.Template
}

func (t *templateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	t.once.Do(func() {
		t.templ = template.Must(template.ParseFiles(filepath.Join("templates", t.filename)))
	})

	t.templ.Execute(w, nil)
}

func main() {
	var addr = flag.String("addr", ":8000", "addres of Application")
	flag.Parse()
	// メインページ
	http.Handle("/", &templateHandler{filename: "main.html"})
	// ファイルサーバ
	http.Handle("/files/", http.StripPrefix("/files/", http.FileServer(http.Dir("./uploaded"))))

	log.Println("Start Web Server. Port", *addr)
	if err := http.ListenAndServe(*addr, nil); err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}

main.html

<!DOCTYPE html>
<html>
  <head>
    <title>配布用ページ</title>
  </head>
  <body>
    <p>好きに落としていいよ</p>
    <a href="/files/games.zip">作ったゲーム</a>
  </body>
</html>

構造

.
├── main.go
├── templates
│   └── main.html
└── uploaded
    └── games.zip  <- 渡したいファイル

確認

f:id:Nishisi:20180627040032p:plain

これで完了。
あとはVPSに持って行って動かせばOK。
全部http.FileServerのおかげですね。