diff --git a/lib/controllers/page_controller.rb b/lib/controllers/page_controller.rb index 854cfc51..a107d228 100644 --- a/lib/controllers/page_controller.rb +++ b/lib/controllers/page_controller.rb @@ -2,6 +2,8 @@ class PageController < BaseController + MAX_UPLOAD_SIZE = 25 * 1024 * 1024 + helpers do def slug Slug.slugify(params[:slug]) if params[:slug] @@ -238,6 +240,7 @@ def cache_for_audience file = params[:file] halt 400, "No file provided" unless file && file[:tempfile] + halt 413, "File too large" if file[:tempfile].size > MAX_UPLOAD_SIZE upload = Upload.new( page: page, diff --git a/test/integration/app_page_uploads_test.rb b/test/integration/app_page_uploads_test.rb index a7632b9e..16bbcf8a 100644 --- a/test/integration/app_page_uploads_test.rb +++ b/test/integration/app_page_uploads_test.rb @@ -129,6 +129,31 @@ def test_delete_upload assert_nil Upload[upload.id] end + def test_upload_rejects_files_over_the_size_limit + with_max_upload_size(10) do + oversized = Rack::Test::UploadedFile.new( + StringIO.new("x" * 11), + "text/plain", + original_filename: "big.txt" + ) + + post "/#{CGI.escape(@page.slug)}/uploads", file: oversized + end + + assert_equal 413, last_response.status + assert Upload.where(page_id: @page.id).empty? + end + + def with_max_upload_size(bytes) + original = PageController::MAX_UPLOAD_SIZE + PageController.send(:remove_const, :MAX_UPLOAD_SIZE) + PageController.const_set(:MAX_UPLOAD_SIZE, bytes) + yield + ensure + PageController.send(:remove_const, :MAX_UPLOAD_SIZE) + PageController.const_set(:MAX_UPLOAD_SIZE, original) + end + def test_upload_requires_login env "rack.session", {}