API Managementを使ってbodyサイズの制限をする

API Managementを使ってbodyサイズの制限をする方法が分からなかったので調べてみました。

設定するポリシー

|      | 設定                                                         | 設定の意味                                                   |
| :--- | :----------------------------------------------------------- | :----------------------------------------------------------- |
| 1    | unspecified-content-type-action="prevent"                    | コンテンツタイプが指定されていない場合は弾くという設定       |
| 2    | max-size="15"                                                | バイト数を指定する。Content-LengthがあればContent-Lengthが利用され、chunkedされていた場合はBodyの実際の長さが評価される |
| 3    | size-exceeded-action="prevent"                               | サイズ上限を超えた場合は弾く                                 |
| 4    | errors-variable-name="requestBodyValidation"                 | エラー情報の書き出し先変数                                   |
| 5    | `<content type="application/json" validate-as="json" action="ignore" />` | コンテンツタイプが「application/json」であれば許可する       |


```xml
<policies>
    <inbound>
        <base />
        <validate-content unspecified-content-type-action="prevent" max-size="15" size-exceeded-action="prevent" errors-variable-name="requestBodyValidation">
            <content type="application/json" validate-as="json" action="ignore" />
        </validate-content>
        <return-response>
            <set-status code="200" />
            <set-header name="Content-Type" exists-action="override">
                <value>application/json</value>
            </set-header>
            <set-body template="none">{"status": "OK"}</set-body>
        </return-response>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>
```

上記設定のうち、以下の部分はMockレスポンスを返すためだけに存在するのでなくても動く。

```xml
<return-response>
    <set-status code="200" />
    <set-header name="Content-Type" exists-action="override">
        <value>application/json</value>
    </set-header>
    <set-body template="none">{"status": "OK"}</set-body>
</return-response>
```

Content-Lengthを指定して呼び出した場合　サイズ上限に触れていない

```xml
$ curl -X POST -H "Content-Length: 11" -H "Content-type: application/json" -d '{ "a": "b" }' https://apim-122354.azure-api.net/hello/post
{"status": "OK"}
```

Content-Lengthを指定して呼び出した場合　サイズ上限に触れている

```xml
$ curl -X POST -H "Content-Length: 17" -H "Content-type: application/json" -d '{ "a": "bbbbbb" }' https://apim-122354.azure-api.net/hello/post
{ "statusCode": 400, "message": "Request's body is 17 bytes long and it exceeds the configured limit of 15 bytes." }
```

Transfer-Encoding: chunkedを指定して呼び出した場合　サイズ上限に触れていない

```xml
$ curl -X POST -H "Transfer-Encoding: chunked" -H "Content-type: application/json" - H "Connection: Keep-Alive" -d '{ "a": "b" }' https://apim-122354.azure-api.net/hello/post
{"status": "OK"}
```

Transfer-Encoding: chunkedを指定して呼び出した場合　サイズ上限に触れている

```xml
$ curl -X POST -H "Transfer-Encoding: chunked" -H "Content-type: application/json" -H "Connection: Keep-Alive" -d '{ "a": "bbbbbb" }' https://apim-122354.azure-api.net/hello/post
{ "statusCode": 400, "message": "Request's body is 17 bytes long and it exceeds the configured limit of 15 bytes." }
```