負荷テストツール vegeta で multipart/form-data で画像を送る


想定読者

  • 画像を送りつける負荷テストをしたい人
  • vegeta でもっと遊びたい人
  • multipart/form-data についてちょっと復習したい人

一言でいうと

  1. 下のような targets.txt, body.txt を準備
    • {その他必要なリクエストヘッダ}{画像のバイナリ} は適宜いれてください
  2. 以下のコマンドを打つ!
// 3分間、1秒間に2リクエストの頻度でattack!する場合の例
vegeta attack -rate 2 -duration 3m -targets targets.txt |tee result
targets.txt
POST http://sample.example.com/images
{その他必要なリクエストヘッダ}
Content-Type: multipart/form-data; boundary=----BoundaryPKp7MX1veAsGyi0A
@body.txt

body.txt
------BoundaryPKp7MX1veAsGyi0A
Content-Disposition: form-data; name="attachment"; filename="dummy"
Content-Type: image/jpeg

{画像のバイナリ}
------BoundaryPKp7MX1veAsGyi0A
Content-Disposition: form-data; name="other-key1"

other-value1
------BoundaryPKp7MX1veAsGyi0A
Content-Disposition: form-data; name="ohter-key2"

other-value2
------BoundaryPKp7MX1veAsGyi0A--

もう一言

  • body.txt 内の name= に続く部分(attachmentなど)も適宜変えてください
  • 画像だけなら body.txt の最初のブロックだけで良いです

まずは curl でやってみる

ググれば結構情報が多いです。以下のような感じでOKです。
{path/to/img.jpg} は画像へのパスです。簡単!

curl -X POST http://sample.example.com/images \
  -F other-key1=other-value1 \
  -F other-key2=other-value2 \
  -F "file=@{path/to/img.jpg};type=image/jpg"

vegeta ではこうする

上の curl のサンプルを見るとこんな感じで良いかなと思ってしまいますが、全然ダメでした

wrong_targets.txt(雰囲気だけ書いたダメな例)
POST http://sample.example.com/images
{その他必要なリクエストヘッダ}
Content-Type: multipart/form-data
Content-Disposition: form-data; name="attachment"; filename="path/to/img.jpg"

other-key1=other-value1
other-key2=other-value2

正しくは以下のように boundary を使って書く必要があります。ファイルの分割は必須ではありませんが、そうした方がわかりやすいかと思います。
画像でない他の multipart/form-data と同じような感じになりますが、画像の場合はボディに 画像のバイナリ を直接入れる必要があるのが特徴です。

targets.txt
POST http://sample.example.com/images
{その他必要なリクエストヘッダ}
Content-Type: multipart/form-data; boundary=----BoundaryPKp7MX1veAsGyi0A
@body.txt

body.txt
------BoundaryPKp7MX1veAsGyi0A
Content-Disposition: form-data; name="attachment"; filename="dummy"
Content-Type: image/jpeg

{画像のバイナリ}
------BoundaryPKp7MX1veAsGyi0A
Content-Disposition: form-data; name="other-key1"

other-value1
------BoundaryPKp7MX1veAsGyi0A
Content-Disposition: form-data; name="ohter-key2"

other-value2
------BoundaryPKp7MX1veAsGyi0A--

注意点

  • HTTP のリクエストでは 改行などが比較的細かく仕様で決まっている のでご注意ください
  • 画像のバイナリ直接 入れ込む必要があります
    • ファイル指定はできません(やり方わかりません)でした
    • cat body_before.txt img.jpg body_after.txt > body.txt のようにしてバイナリを入れるとうまく行きました。
  • 最後の -- 忘れずに

あとがき

vegetamultipart/form-data に関する記事はちらほらありましたが、画像に特化して丁寧に書いたものがなかったので書いてみました。

参考文献

以下の記事など参考にして試行錯誤しました。