Content-EncodingはHTTP/1.1(RFC 2616)で導入された、ペイロードのエンコーディングを表現するヘッダで、主に圧縮転送時において gzip や deflate といった圧縮形式を表現するのに使われています
Amazon API GatewayはこのContent-Encodingをサポートしていることがわかったのですが、どの値(圧縮形式)をサポートしているのか調べてみました
結果
形式 | 結果 | ファイル作成コマンド |
---|---|---|
gzip | ok | gzip |
compress | NG | compress |
deflate | -- | (方法がわからん) |
identity | ok | - |
注意点
API Gatewayがデータの展開を行い、後続処理(Integration Request)にまわされます
そのため今回のS3オブジェクトや $input.body
には展開後のデータが入ってきます
処理はまずContent-Encodingに従った展開が行われ、次にContent-Typeによる検証が走るいう順番であろうかと推測されます
※API Gatewayのpayloadサイズ制限が10MBとありますが、受信時(圧縮済)なのか後続処理(展開後)なのかは調べてません、すいっっません
検証方法
- Amazon API Gatewayで受けたPOSTをS3(bucket: apigw-testing)に保存するようにセットアップ
- 下記 target.json をそれぞれの形式で圧縮
- curlを使って検証
Amazon API Gatewayのセットアップ
基本的にはチュートリアルに沿って作ります
下記はオリジナルです(設定方法は割愛で)
-
POST https://APIGATEWAY/STAGE/{type}
でS3に保存されるオブジェクト名をコントロールできるようにしています
あと、セットアップ中のテストではAPI GatewayのHTTP ProxyでTestでのみエラーが発生するといった罠が現在あるようですので、バケットを作るリージョンはお気をつけて
検証
{"k":1}
Content-Encoding: 指定しない (= identity)
$ curl -H "Content-Type: application/json" --data-binary @target.json -X POST https://${APIGATEWAY}.execute-api.ap-northeast-1.amazonaws.com/prod/raw
$ aws s3api get-object --bucket apigw-testing --key raw /dev/stderr 1> /dev/null
{"k":1}
Content-Encoding: identity
$ curl -H "Content-Encoding: identity" -H "Content-Type: application/json" --data-binary @target.json -X POST https://${APIGATEWAY}.execute-api.ap-northeast-1.amazonaws.com/prod/identity
$ aws s3api get-object --bucket apigw-testing --key identity /dev/stderr 1> /dev/null
{"k":1}
Content-Encoding: gzip
$ gzip -c target.json > target.json.gz
$ file target.json.gz
target.json.gz: gzip compressed data, was "target.json", last modified: Thu May 26 22:44:10 2016, from Unix
$ curl -H "Content-Encoding: gzip" -H "Content-Type: application/json" --data-binary @target.json.gz -X POST https://${APIGATEWAY}.execute-api.ap-northeast-1.amazonaws.com/prod/gzip
$ aws s3api get-object --bucket apigw-testing --key gzip /dev/stderr 1> /dev/null
{"k":1}
Content-Encoding: compress
$ compress -c target.json > target.json.Z
$ file target.json.Z
target.json.Z: compress'd data 16 bits
$ curl -H "Content-Encoding: compress" -H "Content-Type: application/json" --data-binary @target.json.Z -X POST https://${APIGATEWAY}.execute-api.ap-northeast-1.amazonaws.com/prod/compress
$ aws s3api get-object --bucket apigw-testing --key compress /dev/stderr 1> /dev/null
<binaryが表示される>
Content-Encodingと実際のpayloadが違う場合の挙動
例えば Content-Encoding: gzip をセットして、生でおくった場合です
HTTP 500 Internal Server Error が返ります
$ curl -v -H "Content-Encoding: gzip" -H "Content-Type: application/json" --data-binary @target.json -X POST https://${APIGATEWAY}.execute-api.ap-northeast-1.amazonaws.com/prod/error
< HTTP/1.1 500 Internal Server Error
あとがき
gzipサポートはありがたい
API Gatewayにおけるバイナリデータの扱いについても、そのうち書きます → 書きました