Amazon API GatewayがContent-Encoding: gzipをサポートをしていた件

Content-EncodingはHTTP/1.1([RFC 2616](https://www.ietf.org/rfc/rfc2616.txt))で導入された、ペイロードのエンコーディングを表現するヘッダで、主に圧縮転送時において gzip や deflate といった圧縮形式を表現するのに使われています

Amazon API GatewayはこのContent-Encodingをサポートしていることがわかったのですが、どの値(圧縮形式)をサポートしているのか調べてみました

結果
----

[Content-Encodingに設定できる値](https://tools.ietf.org/html/rfc2616#section-3.5)と結果

| 形式     | 結果 | ファイル作成コマンド |
|----------|------|----------------------|
| gzip     |  ok  | gzip                 |
| compress |  NG  | compress             |
| deflate  |  --  | (方法がわからん)     |
| identity |  ok  | -                    |

### 注意点 ###

API Gatewayがデータの展開を行い、後続処理(Integration Request)にまわされます
そのため今回のS3オブジェクトや `$input.body` には展開後のデータが入ってきます

処理はまずContent-Encodingに従った展開が行われ、次にContent-Typeによる検証が走るいう順番であろうかと推測されます

※API Gatewayの[payloadサイズ制限が10MB](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-limits.html)とありますが、受信時(圧縮済)なのか後続処理(展開後)なのかは調べてません、すいっっません

検証方法
--------

1. Amazon API Gatewayで受けたPOSTをS3(bucket: apigw-testing)に保存するようにセットアップ
2. 下記 target.json をそれぞれの形式で圧縮
3. curlを使って検証

### Amazon API Gatewayのセットアップ ###

基本的には[チュートリアル](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html)に沿って作ります

下記はオリジナルです（設定方法は割愛で）

- `POST https://APIGATEWAY/STAGE/{type}` でS3に保存されるオブジェクト名をコントロールできるようにしています

あと、セットアップ中のテストでは[API GatewayのHTTP ProxyでTestでのみエラーが発生する](http://qiita.com/yoshidasts/items/669aa4375447bd2a2645)といった罠が現在あるようですので、バケットを作るリージョンはお気をつけて

検証
----

```target.json
{"k":1}
```

Content-Encoding: 指定しない (= identity)

```console
$ 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

```console
$ 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

```console
$ 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

```console
$ 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 が返ります

```console
$ 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におけるバイナリデータの扱いについても、そのうち書きます → [書きました](http://qiita.com/ma2shita/items/ea96fbb73b7095413d3f)