1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Goで外部コマンドを呼び出すのをHTTPリクエスト越しに実行してみる(Ginを使って)

Last updated at Posted at 2019-07-16

概要

このエントリは、Goを使い、外部コマンドを呼び出すこと、それをHTTPリクエスト越しに実行してみることをやってみたので、メモとして残すものです。コンテナにもできます。
表題のことをやってみようかなと思った方への参考の一つとして紹介します。

前提

想定読者

  • Go言語で、"A tour of Go"を少しやったことがある人

利用するもの

以下を利用します

  • HTTPサーバとして、gin
  • 動作環境は*nix系(コマンド実行)

ソース

リリースv0.1.0がGitHubにあります。
https://github.com/hrkt/cmd-exec-server/releases/tag/0.1.0

ベースとなるもの

以前書いたQiitaのエントリ「Go-lang+GinでAPIサーバを作る一歩目~EHW2018「アプリ②」」で作ってあったものをforkしました。

今できること

  1. app-settings.jsonを編集して

see: "app-settings.json" paragraph in this README.

  1. サーバを実行して
$ make run
  1. サーバ側でコマンドを実行するため、ボディに標準入力を渡し、HTTP POST リクエストを飛ばすと、標準出力がJSONファイルの中の文字列として返ってきます。
    (バッファサイズは2048byteに絞ってあります)
$ curl -X POST localhost:8080/api/exec -d "some input"
{"result":"SOME INPUT"}

(で、README.mdにあるように"make build-container"すると、コンテナになります)

書いたもの

Router

"/api/exec"でコマンドを実行できるように指定しています。

POSTリクエストを受け取り、リクエストのボディ部をstringとして格納しています。
(ここのバッファは今は固定長。2048byte。)


func setupRouter() *gin.Engine {
	router := gin.Default()

	// Global middleware
	router.Use(gin.Logger())

	// Routing
	router.StaticFile("/", "./index.html")

	router.POST("/api/exec", func(ctx *gin.Context) {
		buf := make([]byte, RequestBodyBufferSize)
		n, _ := ctx.Request.Body.Read(buf)
		body := string(buf[0:n])

		res := executeIt(body)

		ctx.JSON(200, gin.H{
			"result": res,
		})
	})

	return router
}

外部コマンドの実行

app-config.jsonで指定したコマンドを実行します。

Go-langのos/execを使います。

(今の実装では出力を区切っていないため、出力が多いコマンドだとサーバが止まるでしょう)

func executeIt(requestBody string) string {
	cmd := exec.Command(appConfig.Command, appConfig.Arguments[:]...)
	cmd.Stdin = strings.NewReader(requestBody)
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()
	if err != nil {
		log.Fatal(err)
	}
	return out.String()
}

おわりに

このエントリでは、Goで外部コマンドを呼び出すのをHTTPリクエスト越しに実行してみることを紹介しました。何かのご参考になれば幸いです。

補足:エントリを書くきっかけ

Pythonで、"$ python -m CGIHTTPServer"などでお手軽サーバを作るような感じをGoでやったらどうなるかなと思って書いてみました。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?