Is there any way to log the raw http requests/responses in rails?
that is, the plain text http message, including the body, even if the body is binary
It depends a bit on what exactly you want to log. But I believe raw_post is what you are looking for. This will return the raw POST body. You can call this method in any of your methods in the controller.
A similar method exist for getting the GET params: raw_params
If that isn't good enough then a middleware layer might help.
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.)
Im trying to figure out what is wrong with my POST data, or Ajax call.
Im using Symfony to create a form, and Ajax to collect and pass the data. Each time I do a POST request I use Firebug's Net panel to look at my POST data. My POST is breaking somewhere, but I can't tell where. The only thing I can see here is when I look at Firebug I am seeing the POST looks different there for each example (the parameters are present in one, and not present in the other), but they should be identical, right? Is this a clue? I don't know how to interpret this, I don't know enough about Firebug, and its obviously not intuitive enough here for this particular issue.
Is this telling me my data isn't encoded correctly?
Here is a non-working example. Notice, "Parameters" is missing. All I see is the "Source" serialized/encoded data:
Now, in the example below, this is what I expect to see. Notice, this one not only contains the "Source" portion and the source data looks identical (but can use a 2nd pair of eyes on this), but there is another section called "Parameters". Why is this elusively missing in the first example and what does the missing "Parameters" mean?
I'm attaching the headers here, too. Maybe this will explain the problem. And posting these here now I do see the different Content-Type, but I think most of my testing was done before I was sending that header.
broken form headers
working form headers
Either something is wrong with the POST data or might I be be missing the Ajax dataType: 'json', or something?
If you have the wrong content type set in the headers, when the data is sent back, and inspected in Firebug, it can't pull them apart as parameters, unless it knows its form encoded data. If the header declares a different type, then if the data is indeed form url encoded, then the browser doesn't parse it as such, therefore can't break it apart into its parameter elements.
So when you make your call, be sure the content type is being sent as 'application/x-www-form-urlencoded' in your Ajax call.
As we all know, file uploading is most often accomplished using POST method. So, why can't the GET method be used for file uploads instead? Is there a specific prohibition against HTTP GET uploads?
GET requests may contain an entity body
RFC 2616 does not prevent an entity body as part of a GET request. This is often misunderstood because PHP muddies the waters with its poorly-named $_GET superglobal. $_GET technically has nothing to do with the HTTP GET request method -- it's nothing more than a key-value list of url-encoded parameters from the request URI query string. You can access the $_GET array even if the request was made via POST/PUT/etc. Weird, right? Not a very good abstraction, is it?
Why a GET entity body is a bad idea
So what does the spec say about the GET method ... well:
In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe."
So the important thing with GET is to make sure any GET request is safe. Still, the prohibition is
only "SHOULD NOT" ... technically HTTP still allows a GET requests to result in an action that isn't
strictly based around "retrieval."
Of course, from a semantic standpoint using a method named GET to perform an action other than
"getting" a resource doesn't make very much sense either.
When a GET entity body is flat-out wrong
Regarding idempotence, the spec says:
Methods can also have the property of "idempotence" in that (aside from error or expiration issues)
the side-effects of N > 0 identical requests is the same as for a single request. The methods GET,
HEAD, PUT and DELETE share this property.
This means that a GET method must not have differing side-effects for multiple requests for the
same resource. So, regardless of the entity body present as part of a GET request, the side-effects
must always be the same. In layman's terms this means that if you send a GET with an entity body
100 times the server cannot create 100 new resources. Whether sent once or 100 times the request must
have the same result. This severely limits the usefulness of the GET method for sending entity bodies.
When in doubt, always fall back to the safety/idempotence tests when evaluating the efficacy
of a method and its resulting side-effects.
In case of GET Method
Appends form-data into the URL in name/value pairs and length of URL is limited(3000 characters).
File content can't be put inside a URL parameter using a form.So use POST
In Get method, the value of action, appends a `?' to it, then appends the form data set, encoded using the "application/x-www-form-urlencoded" content type. The user agent then traverses the link to this URI. In this scenario, form data are restricted to ASCII codes.
So, that file upload is not possible in GET Method
I'm writing some functional tests for a POST API endpoint. I've reviewed the documentation and can't find a way to add content to the POST body. The post method for sfBrowser:
post('some url',array('x'=>'y'))
Only creates POST parameters (in this case x=y). Is there anyway of adding content to the post body using sfBrowser?
From what I have found here, here and here, the POST format takes parameter:value format, so you can send your JSON with some code like:
post('some url', array('json_data' => json_encode($toJson))
and then decode in your action with
$jsonObj = json_decode($request->getParameter('json_data'));
but you need to associate your JSON data with a parameter name in your POST to retrieve it on the server side.
As a side note, after looking at the Symfony code, the parameters are given straight to $_POST except for CSRF, which is tweaked.
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.