ファイルアップロード時にnginxで発生する413 Request Entity Too LargeをWebApp側でハンドリング

概要

  • 標準的な WEB(nginx) + AP(php-fpm, passenger等) 構成のWebアプリケーション
  • nginxのclient_max_body_sizeを超えるファイルがアップロードされた場合に、nginxのエラーページではなく、Webアプリケーション側のエラーページを出したい
    • エラーページのデザイン(header, footer等)をWebアプリ側と共通化したいとか、APサーバ側でエラーログを取りたいとか、そういう理由

対応

  • Webアプリ側はGET http(s)://{host}/413で、エラーページを表示できるようにしておく
  • nginx側で413エラーが発生したら(error_page)、上記にリダイレクト
    • リダイレクトには303を使い、ファイルアップロードで使われるPOST(multipart/form-data)、GETへ変換
    • モダンなFWだとPOSTにcsrf_token対策が入ってたりするので、それを回避するため

例:

default.conf
server {
    index index.php index.html;
    client_max_body_size 100M;

    location / {
        error_page 413 @413;
        try_files $uri $uri/ /index.php?$query_string;
    }

    # (e.g.) laravel settings
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php-fpm/www.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location @413 {
        return 303 https://$host/413;
    }
}

上記の場合、100MB以上のファイルがアップロードされた場合に、リダイレクトされてGET https://$host/413 のエラーページが表示されます。

参考:

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.