Project

General

Profile

Actions

Defect #40208

closed

An ActionController::RespondToMismatchError occurred in welcome#robots

Added by Liane Hampe 3 months ago. Updated 3 months ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
SEO
Target version:
Start date:
Due date:
% Done:

0%

Estimated time:
Resolution:
Fixed
Affected version:

Description

Problem

Requesting the robots file via `https://<domain>.tld/robots` raises an error:

respond_to was called multiple times and matched with conflicting formats in this action. Please note that you may only call respond_to and match on a single format per action.
  app/controllers/application_controller.rb:592:in `render_error'

Requesting the robots file via `https://<domain>.tld/robots.txt` works as expected.

This behavior is the same for all Redmine versions.

Solution

In order to make the request of the robots file more stable we could slightly change the route definition to allow both the request with and without format :

# current definition
get 'robots', :to => 'welcome#robots'

# modified definition
get 'robots', :to => 'welcome#robots', :defaults => { format: 'txt' }

The attached patch file implements this change and considers testing too.


Files

fix_robots_route.patch (1.65 KB) fix_robots_route.patch Liane Hampe, 2024-02-07 13:21
40208-v2.patch (1.02 KB) 40208-v2.patch Go MAEDA, 2024-02-08 13:08
Actions #1

Updated by Go MAEDA 3 months ago

  • Status changed from New to Confirmed
  • Target version set to Candidate for next minor release

Thank you for identifying the issue and proposing a solution. I have verified that your patch successfully resolves the ActionController::RespondToMismatchError caused by a `GET /robots` request.

However, I found that with the patch applied, Redmine still responds to `GET /robots` alongside `GET /robots.txt`. Moreover, Redmine raises an ActionController::RespondToMismatchError when handling requests like `GET /robots.html` or `GET /robots.json`.

To refine the behavior further, I suggest a slight modification to your patch. With this adjustment, Redmine will respond only to GET /robots.txt and will return a 404 error for GET /robots, GET /robots.html, and GET /robots.json.

diff --git a/config/routes.rb b/config/routes.rb
index 540f3d0af..2db1a6abf 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -405,7 +405,7 @@ Rails.application.routes.draw do

   match 'uploads', :to => 'attachments#upload', :via => :post

-  get 'robots', :to => 'welcome#robots'
+  get 'robots.:format', :to => 'welcome#robots', :constraints => {format: 'txt'}

   Redmine::Plugin.directory.glob("*/config/routes.rb").sort.each do |plugin_routes_path|
     instance_eval(plugin_routes_path.read, plugin_routes_path.to_s)
Actions #2

Updated by Liane Hampe 3 months ago

When I try your changes with Redmine 5.1.1 I get errors:

# Format: html
Started GET "/robots.html" for 192.168.2.26 at 2024-02-07 15:04:16 +0100

ActionController::RoutingError (No route matches [GET] "/robots.html"):

# Format: json 
Started GET "/robots.json" for 192.168.2.26 at 2024-02-07 15:04:27 +0100

ActionController::RoutingError (No route matches [GET] "/robots.json"):

Started GET "/robots" for 192.168.2.26 at 2024-02-07 15:04:46 +0100

# Format: html
Processing by WelcomeController#robots as HTML

Completed 500 Internal Server Error in 29ms (ActiveRecord: 16.1ms | Allocations: 6204)

ActionController::RespondToMismatchError (respond_to was called multiple times and matched with conflicting formats in this action. Please note that you may only call respond_to and match on a single format per action.):

app/controllers/application_controller.rb:585:in `render_error'
app/controllers/application_controller.rb:573:in `render_404'
app/controllers/application_controller.rb:597:in `missing_template'

Did you test with the master branch?

Actions #3

Updated by Go MAEDA 3 months ago

In my environment, the stable-5.1 branch with the patch works as expected as well. It successfully returns 404 for "/robots.html", "/robots.json", and "/robots".

Started GET "/robots.html" for 127.0.0.1 at 2024-02-08 09:07:07 +0900

ActionController::RoutingError (No route matches [GET] "/robots.html"):

Started GET "/robots.json" for 127.0.0.1 at 2024-02-08 09:07:13 +0900

ActionController::RoutingError (No route matches [GET] "/robots.json"):

Started GET "/robots" for 127.0.0.1 at 2024-02-08 09:07:20 +0900

ActionController::RoutingError (No route matches [GET] "/robots")
Actions #4

Updated by Liane Hampe 3 months ago

I have made a fresh install of Redmine 5.1.1 and only changed the robots route according to your suggestion.

Then I have run the instance in development and production but it stays the same as above.

This is my (production) environment:

Environment:
  Redmine version                5.1.1.stable
  Ruby version                   3.1.4-p223 (2023-03-30) [x86_64-linux-musl]
  Rails version                  6.1.7.6
  Environment                    production
  Database adapter               Mysql2
  Mailer queue                   ActiveJob::QueueAdapters::AsyncAdapter
  Mailer delivery                smtp
Redmine settings:
  Redmine theme                  Default
SCM:
  Subversion                     1.14.2
  Mercurial                      6.6
  Git                            2.43.0
  Filesystem                     
Redmine plugins:
  no plugin installed
Actions #5

Updated by Go MAEDA 3 months ago

I have just installed Redmine 5.1.1 using tarball https://www.redmine.org/releases/redmine-5.1.1.tar.gz and applied the patch in #note-1.

I cannot reproduce the error you encountered when you accessed /robots. Everything looks working fine. Redmine returns 404 for "/robots.html", "/robots.json", and "/robots" as expected.

$ curl --head http://localhost:3000/robots.html
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=utf-8
X-Request-Id: ffb0a0ce-3672-4abc-8a90-017b0716f8df
X-Runtime: 0.099908
Content-Length: 252860

$ curl --head http://localhost:3000/robots.json
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=utf-8
X-Request-Id: 5899aa24-bfb2-4b0d-8b56-a1d9ea13957a
X-Runtime: 0.068502
Content-Length: 252860

$ curl --head http://localhost:3000/robots
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=utf-8
X-Request-Id: 8f8c654a-ecfc-471c-a13b-74b4d6c503eb
X-Runtime: 0.089086
Content-Length: 252855
Started HEAD "/robots.html" for ::1 at 2024-02-08 16:58:36 +0900

ActionController::RoutingError (No route matches [HEAD] "/robots.html"):

Started HEAD "/robots.json" for ::1 at 2024-02-08 16:58:38 +0900

ActionController::RoutingError (No route matches [HEAD] "/robots.json"):

Started HEAD "/robots" for ::1 at 2024-02-08 16:58:39 +0900

ActionController::RoutingError (No route matches [HEAD] "/robots"):
Environment:
  Redmine version                5.1.1.stable
  Ruby version                   3.1.4-p223 (2023-03-30) [arm64-darwin23]
  Rails version                  6.1.7.6
  Environment                    production
  Database adapter               SQLite
  Mailer queue                   ActiveJob::QueueAdapters::AsyncAdapter
  Mailer delivery                smtp
Redmine settings:
  Redmine theme                  Default
SCM:
  Subversion                     1.14.3
  Mercurial                      6.6.1
  Cvs                            1.12.13
  Bazaar                         3.3.4
  Git                            2.43.0
  Filesystem
Redmine plugins:
  no plugin installed
--- config/routes.rb.orig    2024-02-08 17:07:46
+++ config/routes.rb    2024-02-08 17:08:26
@@ -402,7 +402,7 @@

   match 'uploads', :to => 'attachments#upload', :via => :post

-  get 'robots', :to => 'welcome#robots'
+  get 'robots.:format', :to => 'welcome#robots', :constraints => {format: 'txt'}

   Redmine::Plugin.directory.glob("*/config/routes.rb").sort.each do |plugin_routes_path|
     instance_eval(plugin_routes_path.read, plugin_routes_path.to_s)
Actions #6

Updated by Liane Hampe 3 months ago

Update:

Tested also with 5.1-stable branch but the result is still the same with `GET /robots`:

Completed 500 Internal Server Error in 16ms (ActiveRecord: 3.0ms | Allocations: 4739)

ActionController::RespondToMismatchError (respond_to was called multiple times and matched with conflicting formats in this action. Please note that you may only call respond_to and match on a single format per action.):

app/controllers/application_controller.rb:585:in `render_error'
app/controllers/application_controller.rb:573:in `render_404'
app/controllers/application_controller.rb:597:in `missing_template'
Actions #7

Updated by Liane Hampe 3 months ago

Now I can confirm the behavior you described! :)

I missed the .:format in the fresh installs.

Your hint to test via curl was also insightful: Testing without .:format and via curl gives another result than testing via browser.

With .:format it is stable via both ways curl and browser. Therefore, I can fully agree to your solution.

Thank you very much for your help!

Actions #8

Updated by Go MAEDA 3 months ago

  • Target version changed from Candidate for next minor release to 5.0.8

Thank you for your feedback!

Setting the target version to 5.0.8.

Actions #9

Updated by Go MAEDA 3 months ago

Actions #10

Updated by Go MAEDA 3 months ago

  • Status changed from Confirmed to Resolved
  • Assignee set to Go MAEDA
  • Resolution set to Fixed

Committed the patch in r22698. Thank you for your contribution.

Actions #11

Updated by Go MAEDA 3 months ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF