Defect #40208
closedAn ActionController::RespondToMismatchError occurred in welcome#robots
0%
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
Updated by Go MAEDA 11 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)
Updated by Liane Hampe 11 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?
Updated by Go MAEDA 11 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")
Updated by Liane Hampe 11 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
Updated by Go MAEDA 11 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)
Updated by Liane Hampe 11 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'
Updated by Liane Hampe 11 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!