NginxでURLエンコードされたパスを含むURLをデコードしないでバックエンドのAPIサーバーにプロキシする話。デコードしないままパスの一部を書き換えてプロキシする方法の解説。
背景
NginxでReactのページを返しつつAPIへのリクエストはhttp://172.17.0.1:8080
で動くAPIサーバーにプロキシしたいという状況で、/api/~~~
というフロントからのリクエストをNginxで受けて/~~~
のように先頭の/api
を削除してプロキシしたいという状況です。
今回、URLは/api/aaa/bbb%2Fccc/ddd
のようにURLエンコードされたパスを含むことがあります。この場合、
server {
# HTTPSを利用する設定
listen 80;
server_name localhost;
location / {
# Reactを返す方の処理
root /usr/share/nginx/html;
}
location /api/ {
# APIサーバーにプロキシする処理
proxy_pass http://172.17.0.1:8080;
}
}
のように普通にプロキシした場合Nginxにデコードされ/aaa/bbb/ccc/ddd
のように%2F
をデコードした状態でAPIサーバーに送られてしまいます。
今回はこのデコードされる処理を回避する方法を紹介します。
デコードしない方法
$request_uri
にはデコードする前のクエリパラメータ付きのオリジナルのURIが入っています。今回は先頭の/api
を削除したいので$request_uri
から先頭の/api
を削除し$stripped_uri
に格納しproxy_passに渡しています。
server {
# HTTPSを利用する設定
listen 80;
server_name localhost;
location / {
# Reactを返す方の処理
root /usr/share/nginx/html;
}
location /api/ {
# APIサーバーにプロキシする処理
set $proxy_uri $request_uri;
if ($request_uri ~ ^/api(.*)$) {
set $proxy_uri $1;
}
proxy_pass http://172.17.0.1:8080$proxy_uri;
}
}
これで/api/aaa/bbb%2Fccc/ddd
はhttp://172.17.0.1:8080/aaa/bbb%2Fccc/ddd
にプロキシされます。
終わり。