From 0db20e0cabfffe4d1b0730dd67728bf9dbe617a5 Mon Sep 17 00:00:00 2001 From: evazion Date: Wed, 19 Jan 2022 21:44:40 -0600 Subject: [PATCH] Fix #4591: Wiki pages with filename-like name are broken by default. Fix wiki pages like this returning 406 errors: * https://danbooru.donmai.us/wiki_pages/rnd.jpg Caused by Rails parsing the .jpg part as a file extension and trying to return a JPEG in response. This happens deep in Rails' MIME negotiation code, so it's hard to override. The fix is to pass `format: false` in the route to disable all special handling of file extensions by Rails, and then handle it ourselves in the controller. Ugly. This only affected two tags: `rnd.jpg` and `haru.jpg`. --- app/controllers/wiki_pages_controller.rb | 9 ++++++ config/routes.rb | 2 +- test/functional/wiki_pages_controller_test.rb | 29 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/app/controllers/wiki_pages_controller.rb b/app/controllers/wiki_pages_controller.rb index 7386018b1..f9f6ece3f 100644 --- a/app/controllers/wiki_pages_controller.rb +++ b/app/controllers/wiki_pages_controller.rb @@ -30,6 +30,15 @@ class WikiPagesController < ApplicationController end def show + if params[:format].present? + request.format = params[:format] + elsif params[:id].ends_with?(".html", ".json", ".xml") + request.format = params[:id].split(".").last + params[:id].delete_suffix!(".#{request.format.symbol}") + else + request.format = "html" + end + @wiki_page, found_by = WikiPage.find_by_id_or_title(params[:id]) if request.format.html? && @wiki_page.blank? && found_by == :title diff --git a/config/routes.rb b/config/routes.rb index bcc8cfa72..24b79b6b9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -280,7 +280,7 @@ Rails.application.routes.draw do resources :webhooks do post :receive, on: :collection end - resources :wiki_pages, id: /.+?(?=\.json|\.xml|\.html)|.+/ do + resources :wiki_pages, id: /.+/, format: false do put :revert, on: :member get :search, on: :collection get :show_or_new, on: :collection diff --git a/test/functional/wiki_pages_controller_test.rb b/test/functional/wiki_pages_controller_test.rb index 41d378c9a..92f7f1135 100644 --- a/test/functional/wiki_pages_controller_test.rb +++ b/test/functional/wiki_pages_controller_test.rb @@ -122,6 +122,35 @@ class WikiPagesControllerTest < ActionDispatch::IntegrationTest assert_response :success end + should "work for a title containing a file extension" do + as(@user) { create(:wiki_page, title: "rnd.jpg") } + as(@user) { create(:wiki_page, title: "touhou") } + + get wiki_page_path("rnd.jpg") + assert_response :success + assert_equal("text/html", response.media_type) + + get wiki_page_path("rnd.jpg.json") + assert_response :success + assert_equal("application/json", response.media_type) + + get wiki_page_path("rnd.jpg.xml") + assert_response :success + assert_equal("application/xml", response.media_type) + + get wiki_page_path("rnd.jpg.html") + assert_response :success + assert_equal("text/html", response.media_type) + + get wiki_page_path("rnd.jpg", format: "json") + assert_response :success + assert_equal("application/json", response.media_type) + + get wiki_page_path("touhou.json") + assert_response :success + assert_equal("application/json", response.media_type) + end + should "mark banned artists as noindex" do @artist = create(:artist, name: @wiki_page.title, is_banned: true) get wiki_page_path(@wiki_page.title)