6
1

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 1 year has passed since last update.

WebAssembly Gateway Interface (WAGI) を試す

Last updated at Posted at 2021-12-17

はじめに

WebAssembly Gateway Interface (WAGI) を試しに動かしてみました。

WAGIとは

WAGIは、Common Gateway Interface (CGI) のWebAssembly版の実装です。

ただし、いくつかCGIと異なる部分があります1
2つほど抜粋すると、WAGIには次のような特徴があります。

  • CGIではリクエストを受け取るたびに子プロセスを起動して処理をするが、WAGIではマルチスレッドで処理される
  • ファイルシステムへのアクセスが制限される
    • (これは、後述するmodules.toml で指定することでそのファイルへのアクセスが許されるようになります。)

インストール

今回は、Ubuntu20.04環境にビルド済みのバイナリをインストールします。
レポジトリのリリースぺ-ジからダウンロードして、/usr/local/binに配置します。

bash
$ wget https://github.com/deislabs/wagi/releases/download/v0.4.0/wagi-v0.4.0-linux-amd64.tar.gz
$ tar -xvf wagi-v0.4.0-linux-amd64.tar.gz
$ sudo mv wagi /usr/local/bin

インストールができていることを確認します。

bash
$ wagi --version
WAGI Server 0.4.0

とりあえず動かしてみる

WAGIのレポジトリにはexamplesフォルダがあり、WAGIを試しに実行できます。

bash
$ git clone https://github.com/deislabs/wagi.git
$ cd wagi
$ wagi -c examples/modules.toml

デフォルトの場合、localhost:3000がリッスンされます。
外部からのリクエストを受け付けたい場合やポートを変更したい場合は-l オプションを利用します。
例えば、次のようにして外部からのリクエストを3333ポートで受け付けるようにします。

bash

$ wagi -c examples/modules.toml -l 0.0.0.0:3333


別のターミナルからHTTPリクエストを送信して、レスポンスが返ってくることを確認します。

```shell-session:bash
$ curl -v localhost:3000
*   Trying 127.0.0.1:3000...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: text/html;charset=UTF-8
< content-length: 12
< date: Fri, 17 Dec 2021 05:43:49 GMT
<
Oh hi world
* Connection #0 to host localhost left intact

Oh hi worldとレスポンスが返って来ました!

modules.toml

WAGIを起動した際に -c examples/modules.tomlとオプションを指定しました。
このmodules.tomlがWAGIのコンフィグファイルです。これに従って、WAGIはURIと対応するWebAssemblyモジュールを決定します。オプションで指定をしなかった場合は、CWDのmodules.tomlが読み込まれます。

examples/modules.tomlでは、からエンドポイントが/の部分を抜粋すると、次のようになっています。

examples/modules.toml
[[module]]
# Example executing a Web Assembly Text file
route = "/"
module = "examples/hello.wat"

ここでは、routemoduleが指定されています。
WAGIは/にアクセスが来たら、examples/hello.watを用いてHTTPレスポンスを作って返します。

examples/hello.watを確認すると10行目にHTTPレスポンスがハードコードされていることが確認できます。

(module
    ;; This is the example Hello World WAT from the documentation at
    ;; https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-tutorial.md
    ;;
    ;; It has been adapted to send CGI headers.
    (import "wasi_snapshot_preview1" "fd_write" (func $fd_write (param i32 i32 i32 i32) (result i32)))
    (memory 1)
    (export "memory" (memory 0))

    (data (i32.const 8) "content-type: text/html;charset=UTF-8\n\nOh hi world\n")

    (func $main (export "_start")
        (i32.store (i32.const 0) (i32.const 8))
        (i32.store (i32.const 4) (i32.const 51))

        (call $fd_write
            (i32.const 1)
            (i32.const 0)
            (i32.const 1)
            (i32.const 20)
        )
        drop
    )
)

エンドポイントを追加する

最後に、適当なWebAssemblyモジュールを作成して、WAGIのエンドポイントに追加します。
HTMLファイルを読んで、HTTPヘッダをつけてレスポンスを作成するようにします。

今回は以下のcat.rscat.htmlを用意しました。

examples/cat.rs
fn main() {
    println!("Content-Type: text/html; charset=UTF-8");
    println!();
    let html = std::fs::read_to_string("cat.html").unwrap_or(String::from("にゃー"));
    println!("{}", html);
}
examples/cat.html
<!DOCTYPE html>
<html>

<head>
    <meta charset='utf-8'>
    <title>CAT</title>
</head>

<body>
    <pre>
                       _,,...='~1
               _,.、='"~~,才</彡  }
             ,.=゙ー-  ▼  ````.X彡-ナ
         _,,.::=7;;;.〃    人  .〟二二キ二  
      _,..='´~こ/;;;´,,..   -イ .`'''´      Y
    .< 二二;;,,..-´             }
      .二=壬  /            /
       、,,,,,..;/         ,..--./
          ゞi         ,/     
            \    _,,,,,__.レ         i
             \,./    ゝ_r_,.イ゙   !
               /     ¦       \     ,. 
               {    ゝJ┘         .>-、, /6 6∂
               \                 ゙'i .ω }
                ゙キ               i   /
                 キ               i    /
                  キ;;                /
                  メ゙゙               ,,ノ
                 {キ;.              ノ
                 キ≠         r=ォ'匕ゝ、_  ,,....,
                  Y.--''''''''     ノ弋≠ ≠;≠キ千;;彡゙
                  i゙ o 3    ,.)   `'''…ー'''''´´
                 (__ 8 ,..〟'''´´
                  ゝ-'''´
</pre>
</body>

</html>

cat.rsをコンパイルして、cat.wasmを作成します。

bash
$ rustc --target=wasm32-wasi examples/cat.rs -o examples/cat.wasm

modules.tomlには、次のように追記します。

examples/modules.toml
# 省略

[[module]]
route = "/cat"
module = "examples/cat.wasm"
volumes = {"." = "examples"}

WebAssemblyモジュールにファイルへのアクセスを許可するため、volumesディレクティブを利用します。
今回は、examplesフォルダをモジュールの.にマウントしています。
(Toml Parserが Expected "}", [ \t] or [A-Za-z0-9_\-] but "\"" found.と警告してくるように、本来のTomlの構文に違反しているのはちょっと気になりますね。)

これで準備が整ったので、WAGIを再起動します。

bash
$ wagi -c examples/modules.toml
No log_dir specified, using temporary directory /tmp/.tmpsPMv9G for logs

別のターミナルから、/catにアクセスしてみます。

bash
$ curl -v localhost:3000/cat
*   Trying 127.0.0.1:3000...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /cat HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: text/html; charset=UTF-8
< content-length: 2140
< date: Fri, 17 Dec 2021 07:33:58 GMT
<
<!DOCTYPE html>
<html>

<head>
    <meta charset='utf-8'>
    <title>CAT</title>
</head>

<body>
    <pre>
                       _,,...='~1
               _,.、='"~~,才</彡  }
             ,.=゙ー-  ▼  ````.X彡-ナ
         _,,.::=7;;;.〃    人  .〟二二キ二  
      _,..='´~こ/;;;´,,..   -イ .`'''´      Y
    .< 二二=オ;;,,..-´             }
     乂 .二=壬  /            /
       ゝ、,,,,,..キ;/         ,..--./
          ゞi         ,/     \
            \    _,,,,,__.レ         i
             \,./    ゝ_r_,.イ゙   !
               /     ¦       \     ,. 、
               {    ゝJ┘         .>-、, /6 6∂
               \                 ゙'i .ω }
                ゙キ               i   /
                 キ               i    /
                  キ;;                /
                  メ゙゙               ,,ノ
                 {キ;.              ノ
                 キ≠         r=ォ'匕ゝ、_  ,,....,
                  Y.--''''''''     ノ弋≠ ≠;≠キ千;;彡゙
                  i゙ o 3    ,.)   `'''…ー'''''´´
                 (__ 8 ,..〟'''´´
                  ゝ-'''´
</pre>
</body>

</html>
* Connection #0 to host localhost left intact

かわいいですね🐈

  1. https://github.com/deislabs/wagi/blob/main/docs/architecture.md#differences-from-cgi-11

6
1
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
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?