cercxtrova
cercxtrova

Reputation: 1673

+ symbol within cookie value replaced by whitespace

I have a cookie with a + symbol. The value of the cookie is something like +33123456789. From my controller, if I do cookies[:phoneNumber], it returns 33123456789 (note the whitespace before 3).

I could replace the whitespace with a + but the value is correct within the cookie so I prefer to find a way to directly recover the good value of the cookie.

Why does rails removes the + symbol and how to avoid this?

Thanks

Upvotes: 2

Views: 799

Answers (1)

Stefan
Stefan

Reputation: 114178

I have a cookie with a + symbol […] the value is correct within the cookie

In a HTTP request / response, a + in a cookie value has special meaning: it represent a space.

The server sets cookies via a HTTP header:

Set-Cookie: NAME=VALUE

The client sends them back in a similar way:

Cookie: NAME=VALUE

According to the spec the NAME=VALUE sequence must not contain semi-colon, comma and white space. To add those characters, they must be encoded. The encoding will typically be percent-encoding which maps the 3 excluded characters to:

require 'rack/utils'

Rack::Utils.escape(';') #=> "%3B"
Rack::Utils.escape(',') #=> "%2C"
Rack::Utils.escape(' ') #=> "+"

So if your controller turns a literal + into space, it works as expected:

Rack::Utils.unescape('+33123456789')
#=> " 33123456789"

To correctly represent a +, it has to be sent as %2B:

Rack::Utils.escape('+33123456789')
#=> "%2B33123456789"

Decoding such value will give the expected result:

Rack::Utils.unescape('%2B33123456789')
#=> "+33123456789"

Note that Rails handles the escaping / unescaping automatically when accessing the cookies via ActionController#cookies.

Maybe you set the cookie manually or outside of the cookies helper. Or (quite unlikely) the client isn't encoding the cookie correctly.

Upvotes: 3

Related Questions