Question

What I want

I want to pass a URL segment with an encoded slash.


The Problem

  • Running locally on Thin, it works
  • Running on the server on Passenger/Nginx/Rack, it breaks
  • Something decodes the slash before it reaches Rails

My Question

  • What's the best way of allowing parameters to have slashes?

What I've Tried


The Detail

routes.rb

get '/api/shops/:city', to: 'shops#index', constraints: /[0-9A-Za-z\-\.\%\s]+/

Form

The user can select their area from a dropdown:

London/Dover
Glasgow/Edinburgh

On Submit

We hit the API with: /api/shops/London%2FDover

We encode the slash when building the url for obvious reasons.

This works...

Running locally on Rails on Thin.

The URL is recognised by the routes, the slash is decoded inside Rails and inside our application we have London/Dover as a parameter.

This breaks...

Running on the server on Nginx, Passenger and Rack.

The slash is decoded before it hits Rails.

/api/shops/London/Dover isn't a route so responds with a 404.

Versions

  • Passenger 3.0.2
  • Nginx 1.2.9
  • Rack 1.2 (Release 1.5)
  • Rails 3.2.17
Was it helpful?

Solution

We faced the same problem. We tried encoding the string using CGI::escape , URI::encode, ERB::Util::url_encode, but nothing worked on server with passenger and nginx. The solution that worked for us was to modify the route to use wild card character, known as "Route Globbing". Refer this link : http://guides.rubyonrails.org/routing.html#route-globbing-and-wildcard-segments

So, in your case, the route becomes

`get '/api/shops/*city', to: 'shops#index', constraints: /[0-9A-Za-z\-\.\%\s]+/ `

instead of get '/api/shops/:city', to: 'shops#index', constraints: /[0-9A-Za-z\-\.\%\s]+/.

Notice the wild card character in the route before parameter "city".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top