1

The rails application I'm currently running is running on a domain for a former wordpress site which has hacked. Every once and a while I'll receive an routing error notification for a PUT that the website does not and should not support. Obviously, I can't prevent these requests from being made but I would like to handle them gracefully.

In my routes file I already have all unknown paths redirect to the root_url as noted in this SO post on routing unknown requests with the code:

match '*path' => redirect('/'),via: [:get, :post]  unless Rails.env.development?

Even with that, I still receive errors, like the following:

ActionController::RoutingError: No route matches [PUT] "/cmyks42567.txt"

How do I redirect this in the routes file without writing a controller to pass the specific url and redirect?

Community
  • 1
  • 1
DogEatDog
  • 2,899
  • 2
  • 36
  • 65

2 Answers2

1

You got it, just change the :via option to [:put]:

match '*path' => redirect('/'), via: [:put] unless Rails.env.development?

According to the Rails Guide (http://guides.rubyonrails.org/routing.html#http-verb-constraints): "You can use the match method with the :via option to match multiple verbs at once:" The way yo wrote it you are only matching GET and POST requests.

After the change your code works as expected.

Leonel Galán
  • 6,993
  • 2
  • 41
  • 60
1

I would personally handle this with your webserver software.

If you're using Apache, you could use something like:

#public/htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^*.txt$ http://example.com/ [R=301,L]

If you wanted to handle it in the Rails routes, you'd be able to use a redirect:

#config/routes.rb
unless Rails.env.development?
   scope constraints: { format: 'txt' } do
      match '*path', to: redirect('/'), via: [:get, :post, :put]
   end
end

You'd have to make sure you are capturing only the routes you need to redirect, though.

The problem you have with your setup is that it will capture every route you send to your app, and redirect to root. In fact, this may end up causing an infinite recursion error.

My code above works only in production / staging (as yours).

It takes any .txt route passed through the GET, POST or PUT HTTP verbs, redirecting to the root path.

Richard Peck
  • 76,116
  • 9
  • 93
  • 147