Can query string escaping be switched from + to %20?

Hi, I am investigating the possibility of switching the escaping of query strings from + to %20. I have developed a simple library search interface. When submitting my query to the controller and receiving the answer, the query string is + escaped. I catch the query string and copy it to the result webpage by replacing all escaped characters. This precludes currently the usage of + in search strings. It wanted to try out, how a more modern percentage escaping solution would work, but was unable to find any documentation of such a feature.

Does Rails provide a way to implement percentage escaping? If not, it would be great to implement a way where you could switch between them … maybe in the config file …

You may find that this happens in the browser or at your Web server layer, not the application server or Rails. The conversion of illegal URLs (containing spaces) happens at a very low level, since without that conversion, the URL won’t even route to your server.

Walter

1 Like

I found this interesting entry on SO: ruby - What's the difference between URI.escape and CGI.escape? - Stack Overflow, which discusses the question for ruby. I thought it would fall to Rails’s input view helper method to send my search string from the client to the server and maybe to the router to produce the url, which is returned to my client.

protocol://subdomain.domain.tld/subdirectory/action?searchAny=Eureka+More

where “?searchAny=Eureka+More” would be the search string.

Am I wrong?

In my case I have:

<%= text_field_tag :searchAny, params[:searchAny_params], placeholder: "Search", id: "search_input", class: "search-field", required: true %>
<%= submit_tag "Search", name: nil, id: "search-button", class: "search-button" %>

In fact my params is currently:

#<ActionController::Parameters {"searchAny"=>"house house", "controller"=>"collection/opac", "action"=>"opac"} permitted: false>

So it arrives to the controller unescaped, but it is returned in the query string part of the url escaped with +.

You mean the query string part is not governed by Rails or Passenger/Puma, but by Nginx or Apache?

I would rule out the browser. I tried 3 and all produce +.

The query string takes also care of pagination info. I suspect that the query string is all carried by Rails. Though I will take a look at the web server.

1 Like

I was aiming at:

rails/actionpack/lib/action_dispatch/journey/router.utils.rb

 class UriEncoder # :nodoc:
          ENCODE   = "%%%02X"
          US_ASCII = Encoding::US_ASCII
          UTF_8    = Encoding::UTF_8
          EMPTY    = (+"").force_encoding(US_ASCII).freeze
          DEC2HEX  = (0..255).map { |i| (ENCODE % i).force_encoding(US_ASCII) }

          ALPHA = "a-zA-Z"
          DIGIT = "0-9"
          UNRESERVED = "#{ALPHA}#{DIGIT}\\-\\._~"
          SUB_DELIMS = "!\\$&'\\(\\)\\*\\+,;="

          ESCAPED  = /%[a-zA-Z0-9]{2}/.freeze

          FRAGMENT = /[^#{UNRESERVED}#{SUB_DELIMS}:@\/?]/.freeze
          SEGMENT  = /[^#{UNRESERVED}#{SUB_DELIMS}:@]/.freeze
          PATH     = /[^#{UNRESERVED}#{SUB_DELIMS}:@\/]/.freeze