golangで書いたスクリプトまとめ
Golangの勉強で書いたコードについて挙げます。
これは画像アップローダーです。短いコードなのでガッと載せます。
package main import ( "crypto/rand" "encoding/base64" "io" "log" "net/http" "os" "path/filepath" "strings" "github.com/gin-gonic/gin" ) func main() { port := os.Getenv("PORT") if port == "" { log.Fatal("$PORT must be set") } router := gin.Default() router.Static("/", "./images") router.POST("/upload", func(c *gin.Context) { file, header, err := c.Request.FormFile("image") fileExt := filepath.Ext(header.Filename) b := make([]byte, 40) rand.Read(b) randomName := base64.URLEncoding.EncodeToString(b) out, err := os.Create("./images/" + randomName + strings.ToLower(fileExt)) if err != nil { log.Print(err) c.Err() } defer out.Close() _, err = io.Copy(out, file) if err != nil { log.Print(err) c.Err() } c.String(http.StatusOK, randomName+strings.ToLower(fileExt)) }) router.Run(":" + port) }
まず、 router
には2つのエンドポイントが設定されます。一つは /upload
です。これは名前の通りPOSTで画像を受けて実行しているサーバの ./images/
以下に適当なハッシュをつけて保存するエンドポイントです。 画像を見たいときはおもむろに /<hash>
でアクセスすると見れます。ここはStaticとして設定をして実現をしていますが、サーバが画像を返すのは現実的によろしくないので、今後の課題とさせていただきます。
これはwebsocketでいい感じにチャットできるgolang webアプリです。 実装は、
- 作者: Mat Ryer,鵜飼文敏,牧野聡
- 出版社/メーカー: オライリージャパン
- 発売日: 2016/01/22
- メディア: 大型本
- この商品を含むブログ (2件) を見る
これをパクって参考にしてやりました。
これはアクセス元IPを出すgolang webアプリです。 VPNなどを構築した後に本当にVPN越しに行けているのかの確認用に作りましたが、本当は 診断くん でなんとかしています。
package main import ( "fmt" "log" "net" "net/http" "os" ) func doko(w http.ResponseWriter, r *http.Request) { var ip string ip = r.Header.Get("X-Forwarded-For") if ip == "" { var err error ip, _, err = net.SplitHostPort(r.RemoteAddr) if err != nil { log.Println("SplitHostPort error: ", err) fmt.Fprint(w, "IP: ???\nHost: ???") return } } log.Println("IP: ", ip) host, err := net.LookupAddr(ip) if err != nil { log.Println("LookupAddr error: ", err) fmt.Fprintf(w, "IP: %s\nHost: ???", ip) return } log.Println("Host: ", host) fmt.Fprintf(w, "IP: %s\nHost: %s", ip, host[0]) } func main() { port := os.Getenv("PORT") if port == "" { log.Fatal("$PORT must be set") } http.HandleFunc("/", doko) err := http.ListenAndServe(":"+port, nil) if err != nil { log.Fatal("ListenAndServe: ", err) } }
func doko
内でアクセス元の情報をもとに返してあげる実装になっています。簡単でした。
まとめと感想
Webアプリをガッツリ書くよりもAPIのためとかコマンドとして書くみたいな方が書きやすかった。一時期RailsみたいなフルスタックWAFとして使おうとしたけどなんか違う気がする。