Rails: Plus sign in GET-Request replaced by space - ruby-on-rails

In Rails 3 (Ruby 1.9.2) I send an request
Started GET "/controller/action?path=/41_+"
But the parameter list looks like this:
{"path"=>"/41_ ",
"controller"=>"controller",
"action"=>"action"}
Whats going wrong here? The -, * or . sign works fine, its just the +which will be replaced by a space.

That's normal URL encoding, the plus sign is a shorthand for a space:
Within the query string, the plus sign is reserved as shorthand notation for a space. Therefore, real plus signs must be encoded. This method was used to make query URIs easier to pass in systems which did not allow spaces.
And from the HTML5 standard:
The character is a U+0020 SPACE character
Replace the character with a single U+002B PLUS SIGN character (+).

For POST-requests, (in case that's how some of you stumbled upon this question, like me) one might encounter this problem because one has encoded the data in the wrong way on the client side. Encoding the data as application/x-www-form-urlencoded will tell rails to decode the data as it decodes a URL, and hence replace + signs with whitespace, according to the standard RFC1738 as explained by #mu is too short
The solution is to encode the data on the client side as multipart/form-data.
In PHP, using cURL, this is done by taking into consideration the following gotcha:
Passing an array to CURLOPT_POSTFIELDS will encode the data as
multipart/form-data, while passing a URL-encoded string will encode
the data as application/x-www-form-urlencoded. http://php.net/manual/en/function.curl-setopt.php
You might wonder why I was using PHP on the client side (that's because the client in my example was another webserver, since I'm working on an API connection.)

Related

Passing "%20" into a string to be encoded as a URL without it converting to a space?

I have the following code to post data to a site: https://play.golang.org/p/e1g0Nd1kDh0
When I view the request in Fiddler, it shows as:
"jobTitle=Area Manager"
What I want it to do is send the string exactly as it is in the code (i.e. not encode the %20 to spaces), as it seems to be causing some confusion on the other side? An identical request made using a Python program works fine where the spaces are not added.
I've tried escaping it by doubling the % signs, but it doesn't seem to work. Any help would be great.
Thanks.
If you're trying to receive a literal %20 on the server side, then encode the % sign. It encodes to %25. So your postdata becomes:
data := "&jobTitle=Area%25%20Manager"
But if this is happening, there is probably a problem on the server side where the postdata is being decoded twice.
You can also pass the URL encode characters individually. In this case %25%32%30 = "%20"

International characters resulting in bad OAuth 1.0 body hash

I'm getting a body hash mismatch when the POST body of an XML web service request contains international characters.
From what I've read, it sounds like international characters in a POST body have to be encoded before calculating the OAuth body hash. UTF-8 for CAFÉ of "CAF%c3%89" doesn't seem to work with the MasterCard Match web service. I'm having trouble with the tool we're using (iWay Service Manager) re-interpreting "CAFÉ" back to "CAFÉ". Before I figure out how to squeeze an encoder in before the OAuth step, I was hoping to confirm with someone who had dealt with this issue. What is the proper encoding to use on a POST body with international characters (or is my problem likely to be something else)?
For calculating MasterCard OAuth body hash, the recommended encoding is UTF-8. Also the Core SDK made available by MasterCard uses UTF-8 encoder to encode oauth_body_hash.

Should I url encode a query string parameter that's a URL?

Just say I have the following url that has a query string parameter that's an url:
http://www.someSite.com?next=http://www.anotherSite.com?test=1&test=2
Should I url encode the next parameter? If I do, who's responsible for decoding it - the web browser, or my web app?
The reason I ask is I see lots of big sites that do things like the following
http://www.someSite.com?next=http://www.anotherSite.com/another/url
In the above, they don't bother encoding the next parameter because I'm guessing, they know it doesn't have any query string parameters itself. Is this ok to do if my next url doesn't include any query string parameters as well?
RFC 2396 sec. 2.2 says that you should URL-encode those symbols anywhere where they're not used for their explicit meanings; i.e. you should always form targetUrl + '?next=' + urlencode(nextURL).
The web browser does not 'decode' those parameters at all; the browser doesn't know anything about the parameters but just passes along the string. A query string of the form http://www.example.com/path/to/query?param1=value&param2=value2 is GET-requested by the browser as:
GET /path/to/query?param1=value&param2=value2 HTTP/1.1
Host: www.example.com
(other headers follow)
On the backend, you'll need to parse the results. I think PHP's $_REQUEST array will have already done this for you; in other languages you'll want to split over the first ? character, then split over the & characters, then split over the first = character, then urldecode both the name and the value.
According to RFC 3986:
The query component is indicated by the first question mark ("?")
character and terminated by a number sign ("#") character or by the
end of the URI.
So the following URI is valid:
http://www.example.com?next=http://www.example.com
The following excerpt from the RFC makes this clear:
... as query components are often used to carry identifying
information in the form of "key=value" pairs and one frequently used
value is a reference to another URI, it is sometimes better for
usability to avoid percent-encoding those characters.
It is worth noting that RFC 3986 makes RFC 2396 obsolete.

Datausingencoding that doesn't replace plus signs

I'm looking for a datausingencoding parameter that doesn't swallow up plus signs. I was using NSASCIIENCODING but since I'm trying to send a uiimage to the server and the base64 string had plus signs in them, it seems like that form of encoding takes out the plus sign sending a modified encoded string to the server thereby not allowing the image to be decoded server side. I'm looking for something that won't alter the base64 string.
Nevermind guys, here is the solution I found on stackoverflow
thanks, now I figured it out. It seems I needed to run my string through the stringByAddingPercentEscapesUsingEncoding: first, then I needed to run it through replaceOccurrencesOfString:#"+" withString:#"%2B" and several more of those replaces for different characters, because stringByAddingPercentEscapesUsingEncoding: doesn't escape them all

browser url encoding different that java's URLEncoder.encode

I have a url like this:
product//excerpts?feature=picture+modes
when i access this url from browser, the backend receives the request as:
"product//excerpts?feature=picture+modes"
At the web server end, i am using + as a separator. so feature=picture+modes means there are 2 features: picture and modes
I have created and automated script(Java) which goes to the url and retrieves its content.
When i run this script, the backend receives the request as:
"product/B000NK6J6Q/excerpts/feature=picture%2Bmodes"
This is because inside my script(Java) i use URLEncoder.encode which converts + to %2B and send this encoded url to the server.
Why are the urlEncoders provided by Java and those present with browsers(FF/IE) different.
how do i make them same? How do i decode them? ('+' on URLDecoder.decode gives space)
Also, is using '+' as a separator according to conventions (and specifications?) ?
Prac
What you are seeing is actually correct. See Percent encoding on Wikipedia. The + character is a reserved character and therefore needs to be encoded as %2B. Furthermore, historically browsers use a different form of percent encoding for forms that are submitted with the MIME type application/x-www-form-urlencoded where spaces become + instead of %20.
If you want to use a + in the URL then your separator should be a space in the backend. If you want to use + in the backend, then you will have %2B in the URL.

Resources