Go言語 Gin でCGIするには?
カテゴリー: レンタルサーバーやcgi
2024-08-07
タイトル
執筆:2024.08.07
編集:2024.08.07
編集:2024.08.07
スクリプト言語で書くのが定番なんでしょうが、
バイナリスクリプトなら1個や数個で済むようなことが
スクリプト言語のフレームワーク使うと数千から数万個のファイルになるので嫌なんですね。
rustはCGIライブラリが貧弱で切り替え無理と判断しました。
CGIで運用するにはCGI全盛期に存在した言語でないと無理のようです。(1からごろごりかくならできますけどね)
Go言語は切り替えできるのとGoはrustより格段にコードが読みやすいのでGoで書いたほうがバグがなくメンテナンスしやすいように思います。
いくつかフレームワークのソースを確認しましたが
Ginは、動作できることをローカルサーバーで確認しました
他のフレームワークはできそうもない。
Gin でCGIするには?
本番運用はしていないので、非公式方法なのでなんらかの不具合がでるかもですが・・・、
その時は、素の http.cgi使うしかないですね。
DebugモードだとGinが余計な情報を出すので、インターナルサーバーエラーになる
対策
リリースモードフラグを立てておく。
デバッグは、CGIではなくセルフサーバーモード(デフォルト)で行う
gin.SetMode(gin.ReleaseMode) // リリースモードに設定
CGI環境かどうかを判定するには
対策
CGI環境かどうかをCGI環境変数の有無で判定してコードを切り替える
独自の判定ルールを追加する。本番でCGIで実行したいのにセルフサーバーモード(デフォルト)になると困りますからね。
CGI環境変数は規格で決まっています。なので判定は簡単です。仕様書に記載の変数を全部定義されているのかを確認するのが確実ですが
代表的なものだけでたいていは問題ないかと思います。
func main() {
// CGI環境変数が設定されているかで分岐する
if strings.HasPrefix(strings.ToUpper(os.Getenv("GATEWAY_INTERFACE")), "CGI/") {
// main_cgi() // 標準機能
main_cgi_gin() // 外部ライブラリ
} else {
// command line
if os.Getenv("REQUEST_METHOD") == "" {
main_serve_gin() // 外部ライブラリ
}
}
}
func main_cgi_gin() {
//pre_startup()
gin.SetMode(gin.ReleaseMode) // リリースモードに設定
// r := gin.Default()
r := gin.New()
setup_route_gin(r)
if err := cgi.Serve(r); err != nil {
fmt.Println("Content-Type: text/plain")
fmt.Println("")
fmt.Println(err) // エラーの内容を表示する
//dumpEnv() // 環境変数を全部表示する
}
}
func main_serve_gin() {
//pre_startup()
r := gin.Default()
setup_route_gin(r)
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
func setup_route_gin(r *gin.Engine) {
r.GET("/", func(c *gin.Context) { c.String(200, "Hello, World!") })
r.NoRoute(func(c *gin.Context) {
contents := "Hello, World!"
c.String(200, contents)
})
}