サブリクエスト内部のコンテキストに注意

アップローダの認証を API に行わせる、という設定をしていて、少しハマった。

こんな設定を入れてみたところ、クライアントからの POST リクエストが返ってこない。

location /api {
    proxy_pass http://backend-api;
}

location /uploader {
    auth_request /api/authn;
    client_max_body_size 0;

    proxy_buffering off;
    proxy_request_buffering off;
    proxy_pass http://backend-uploader;
}

ちょっと調べてみると、 auth_request によるサブリクエストをプロキシするときは、ボディを空にしないと行けないらしい。
これは 公式の例 にも書いてある。

そこで、下記の設定を入れると、今度は 500 が返るようになった。

location /api {
    proxy_pass http://backend-api;
}

location = /_api_authn {
    internal;
    proxy_set_header Content-Length "";
    proxy_pass_request_body off;
    proxy_pass http://backend-api/api/authn;
}

location /uploader {
    auth_request /_api_authn;
    client_max_body_size 0;

    proxy_buffering off;
    proxy_request_buffering off;
    proxy_pass http://backend-uploader;
}

エラーログにボディが大きすぎると出ていたので、下記のように client_max_body_size を入れたところ、望む動きになった。

location /api {
    proxy_pass http://backend-api;
}

location = /_api_authn {
    internal;
    client_max_body_size 0;   ### これを忘れていた!
    proxy_set_header Content-Length "";
    proxy_pass_request_body off;
    proxy_pass http://backend-api/api/authn;
}

location /uploader {
    auth_request /_api_authn;
    client_max_body_size 0;

    proxy_buffering off;
    proxy_request_buffering off;
    proxy_pass http://backend-uploader;
}

ボディを空にするために location を分けたので、当然内部のコンテキストも別になったのが原因。
考えてみるとそりゃそうだなんだけど、気づきにくいと思ったので、メモでした。