I find this behavior a bit strange, I'm using 'net\http' to do some restful communication to an internal API. For this I need to send a multipart/form-data request to our server. In my code I have this:
request["Content-Type"] = "multipart/form-data, boundary=AbCdE1"
The request created then looks like this:
"multipart/form-data, boundary=abcde1"
The problem is the body itself is using AbCdE1 for its boundaries and it fails. Obviously I could use just lowercase letters, but for a more reliably unique boundary, having capitals is helpful. I have seen comments that rails makes headers lowercase, is there a good reason why it does this without my intervention?
The correct delimiter for the Content-Type and the boundary is a semicolon... Have you tried to use a semicolon instead of the comma, to see if Rails still translate it to lowercase?
BTW check http://httparty.rubyforge.org/ for consuming RESTful webservices, the result is more elegant than writing net/http code.
Related
First you must know I'm a total beginner, I'm trying to learn so I almost don't know anything.
On the basic page of the API, there is a curl command used as an example to show us how to make requests.
I'm using Ruby on Rails so I used "curl-to-ruby" website to translate it, but it did not work as expected.
I wanted it to show me this :
uri = URI.parse("REQUEST_URL")
response = JSON.parse(Net::HTTP.get(uri))
Instead I got this :
uri = URI.parse("REQUEST_URL")
response = Net:HTTP.get_response(uri)
I don't understand any of this, I thought I wouldn't need to and just use "curl-to-ruby", but apparently I really need to get this.
Would you please try to explain me ?
Or give me links ?
Or matters to read (curl, API, http) ?
Thank you very much, have a nice day.
It's because that command doesn't return just the content, it returns the whole HTTP response object including headers and body. You need to extract the response body and parse that using JSON.parse(), e.g.
JSON.parse(response.body)
See documentation here: https://docs.ruby-lang.org/en/2.0.0/Net/HTTP.html#method-c-get_response
(Also, there is nothing in the cURL command which would hint to the converter that the content-type of the response was expected to be JSON (e.g. perhaps an "accepts" header or something), so even if it were able to produce extra code adding the JSON.parse part, it has no way of knowing that it would be appropriate to do so in this case.)
I'm reading the book, HTTP - The Definitive Guide, from which I get the URL general format:
<scheme>://<user>:<password>#<host>:<port>/<path>;<params>?<query>#<frag>
The <params> part said,
The path component for HTTP URLs can be broken into path segments. Each segment can have its own params. For example:
http://www.joes-hardware.com/hammers;sale=false/index.html;graphics=true
In my opinion, path params can also be used to query resources like query strings, but why it's barely seen?
And I'm a Rails developer, and I haven't seen its usage or specification in Rails. Does Rails not support it?
You ask several questions
Why do we not see ;params=value much?
Because query parameters using ?=& are widely supported, like in PHP, .net, ruby etc.. with convenient functions like $_GET[].
While params delimited by ; or , do not have these convenient helper functions. You do encounter them at Rest api's, where they are used in the htaccess or the controller to get relevant parameters.
Does Ruby support params delimited with ;?
Once you obtain the current url, you can get all parameters with a simple regex call. This is also why they are used in htaccess files, because they are easily regexed (is that a word?).
Both parameter passing structures are valid and can be used, the only clear reason why one is used more often than the other is because of preference and support in the different languages.
I'm busy with web service and an iOS app. So far I haven't had that many issues. However, there is a web service that needs the final URL request to be in a certain format. Something along the lines of:
...?IncludedUserIds[]=1357213,286476&..
These parameters are constructed from an NSDictionary and NSString. Now when I add the comma - the end URL that makes the request ends up like this:
..?IncludedUserIds=%5B%5D1357213%2C286476&...
It seems that AFNetworking 2.0 has converted the square brackets into =%5B%5D and the comma into: %2C
Obviously, the web service has no idea what this means and fails.
Is there a way to keep the final Url as I need it to be? Why do these conversions happen and where can I learn more about this sort of thing?
AFNetworking keep the final url encoded, that is the best way, since you could have special characters in you query string that could break all. Instead, you should decode the url server side, for example in PHP you have methods, like urldecode or rawurldecode (eg: 'foo%20bar%40baz' ->'foo bar#baz'), or in ASP it should be kept automatically.
Hope it helps
I have developed a ASP.NET MVC application. I have a conroller with the name EmployeeController and it got a method called GetEmployeeByName. GetEmployeeByName() takes a name of type string as parameter.
So When I send a request like this, i get the data back :
someDomain:9999/Employee/GetEmployeeByName/Roger Federer
But if the name contains an '&' (you & me), I get a '400 Bad Request' as response from server.
someDomain:9999/Employee/GetEmployeeByName/you%20&%20me
Even if i encode it dont get a reposne back
someDomain:9999/Employee/GetEmployeeByName/you%20&%20me
What is the right way to encode such (data with special character) data?
What is the right way to encode such (data with special character) data?
The right way is to use a query string parameter and not be putting those things as part of the uri portion. Read the following blog post from Scott Hansleman. I will only quote hos conclusion:
After ALL this effort to get crazy stuff in the Request Path, it's
worth mentioning that simply keeping the values as a part of the Query
String (remember WAY back at the beginning of this post?) is easier,
cleaner, more flexible, and more secure.
As you can see in the blog post there are some hacky ways to make it work and circumvent IIS handling but it simply is not something that I would recommend you venturing into. Just put this name in the query string.
Do I need to encode strings (eg URL) I pass as a POST form parameter?
Ie I want to pass a URL I have to my web application (ruby on rails) as one of the form parameters. So are there any potential characters in a URL/URI that would need to be encoded? Or perhaps rails would handle this anyway?
Do I need to encode strings (eg URL) I pass as a POST form parameter?
That depends on what you're using to create/send your POST request. If you're directly creating the request body yourself, then yes you would have to URL-encode each parameter:
POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
foo=bar&url=http://www.example.com/url?innerparameter1=1&innerparameter2=2
this is no good:innerparameter2 is actually a parameter of the outer form-encoded string. It would need encoding, which would look like:
foo=bar&url=http%3A//www.example.com/url%3Finnerparameter1%3D1%26innerparameter2%3D2
If, however, you are using something higher-level to make the POST request, and passing in some kind of mapping of parameter strings, I would expect that component to take care of the URL-encoding for you.
Code?
As bobince mentions, you need to encode any data that you're passing as URL parameters. Often whatever library you're using will take care of this. This applies to all HTTP requests BTW.
For example, an API has an endpoint GET /sites/:name.
Using cURL it should look like
curl http://example.com/sites/google%2Ecom
In Ruby/Rails, you can use URI.encode and URI.decode:
>> URI.encode('google.com', /\W/)
"google%2Ecom"
>> URI.decode('google%2Ecom')
"google.com"
As a general statement, if you emit programmatic or user input data to an HTML page, you should encode it for HTML. Bear in mind that URLs often have the & character and that should be encoded, even if browsers appear to handle it okay.
I'm not a Ruby guy, so I don't know how you do that in Ruby, nor am I familiar with Ruby on Rails to say if it will do it (though I would be a little surprised by that), but the guideline I suggest isn't language specific.