Payload in Typhoeus Ruby Delete Request - ruby

I am trying to send request payload(like in a post call) with Typhoeus Delete call.
As far as I know, The latest update to the HTTP 1.1 specification (RFC 7231) explicitly permits an entity body in a DELETE request:
A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.
I tried this code, but body/payload is not retrievable
query_body = {:bodyHash => body}
request = Typhoeus::Request.new(
url,
body: JSON.dump(query_body),
method: :delete,
ssl_verifypeer: false,
ssl_verifyhost: 0,
verbose: true,
)
request.run
response = request.response
http_status = response.code
response.total_time
response.headers
result = JSON.parse(response.body)
At the other side, It comes in an encoded way, where I can not retrieve it
Other side code is like :
def destroy
respond_to do |format|
format.json do
body_hash = params[:bodyHash]
#do stuff
render json: {msg: 'User Successfully Logged out', status: 200}, status: :ok
end
format.all {render json: {msg: 'Only JSON types are supported', status: 406}.to_json, status: :ok}
end
end

Let me cite the specification:
A payload within a DELETE request message has no defined semantics;
sending a payload body on a DELETE request might cause some existing
implementations to reject the request.
I would NOT say it can be called as explicit permission to send payload with DELETE request. It tells you MAY send a payload, but the processing of such a request remains entirely at the discretion of the server.
And this is what happens:
At the other side, it comes in an encoded way, where I can not retrieve it
Why can't you send your payload as a part of POST request, which is guaranteed to be processed by the server normally?

I finally looked at all my requests in which I was payload (POST and PUT) and observed that I was not sending headers along with this DELETE request.
It looks something like this:
query_body = {:bodyHash => body}
request = Typhoeus::Request.new(
url,
body: JSON.dump(query_body),
method: :delete,
ssl_verifypeer: false,
ssl_verifyhost: 0,
verbose: true,
headers: {'X-Requested-With' => 'XMLHttpRequest', 'Content-Type' => 'application/json; charset=utf-8', 'Accept' => 'application/json, text/javascript, */*', 'enctype' => 'application/json'}
)
request.run
response = request.response
http_status = response.code
response.total_time
response.headers
result = JSON.parse(response.body)
Just adding headers to it, made it work

Related

Post request to selling partner API sandbox endpoint return InvalidSignature

I'm currently trying to create a document and upload it to the SP-API sandbox environment using ruby and HTTP.rb gem. My steps are:
Request the LWA access token by a refresh token
Assume the role and request the STS token
Sign the request header using AWS::SignV4 SDK
Send the POST request to the endpoint /feeds/2020-09-04/documents with body json: { 'contentType' => 'text/tab-separated-values; charset=UTF-8' }
However, SP-API keeps returning "code": "InvalidSignature" to me. But all my other 'GET' requests like get_orders, get_order_items are working correctly.
Here is how I send my request:
#url = '/feeds/2020-09-04/documents'
#body = if sandbox
{ 'contentType' => 'text/tab-separated-values; charset=UTF-8' }
else
{ 'contentType' => 'text/xml; charset=UTF-8' }
end
#request_type = 'POST'
response = http.headers(headers).send(#request_type.downcase.to_sym, request_url, json: #body)
I checked the AWS::Signer::V4 document, turns out I should pass the body into the signer as well.
signer.sign_request(http_method: #request_type, url: request_url, body: #body)
I published the amz_sp_api rubygem that does this, but I would welcome a contribution of the ruby code for encrypting the feed submissions as required by SP-API: https://github.com/ericcj/amz_sp_api/issues/1

In ruby with sinatra, How to get I response with get method on rest client?

I use ruby with sinatra and I used rest-client on import for payment.
I got token that string typed through post method on specific url: '... /users/getToken'.
Using this token, I wanna get payments information with get method on this url:
get_url = 'https://api/iamport.kr/payments/'+imp_uid
the detail codes are below,
def get_paymentsdetails(token, imp_uid)
get_url = 'https://api.iamport.kr/payments/'+imp_uid
response = RestClient.get get_url, :data => {}.to_json, :accept => :json, :headers => {'Authorization' => token}
json = JSON.parse(response, :symbolize_names => true)
# json = JSON.parse(response.to_json, {:symbolize_names => true})
return json
end
However, I got 401 unauthorized error on this part of code.
response = RestClient.get get_url, :data => {}.to_json, :accept => :json, :headers => {'Authorization' => token}
After I access get_url with specific imp_uid, I got this page,{"code":-1,"message":"Unauthorized","response":null}
I checked parameter token and imp_uid of get_paymentsdetails function have valid string values,, so How can I access response parameter??
I think that there are some problems on response = RestClient.get get_url.... code.
Thanks.
Method 'get' from the 'RestClient' class return some object with attributes. So response have few values. Which of them do you need? Access to them you can get by their names, its described here.
In your case, after response = RestClient.get get_url... you should have variable response and ability to call response.headers, response.code or response.body.
But im afraid that you have some problems with autorization, which means that imp_uid or token is not correct. Thats why remote server sended to you responce with http-code 401 (Unauthorized). If it is so you should try to check your imp_uid and token. If everything is correct try to reach support of iamport.kr .

Trying to make HTTP Post request with a body using Ruby HTTP start block

I'm trying to make a POST request with basic oauth and a body param.
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'ACCESS_CODE'
request.body = {
to: to,
subject: subject,
text: text,
api_type: 'json',
uh: #modhash
}.to_json
http.request(request)
end
It returns a
<Net::HTTPOK 200 OK readbody=true>
so I know the oauth is working but the body param is not getting passed into the request because it is returning this error
[".error.NO_USER.field-to"]], ["please enter a username"]]
I checked all the data values in the body hash and none of them are null.
Use the set_form_data method to set your POST body:
Here is an example from the docs:
request = Net::HTTP::Post.new(uri)
request.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')

Ruby Typhoeus gem - Invalid Json in body?

I have the following code:
require 'Typhoeus'
url = Typhoeus::Request.new("https://fluidsurveys.com/api/v2/webhooks/subscribe/",
userpwd: "username_test:password_test",
method: :post,
body: {
'subscription_url' => 'http://glacial-spire-test.herokuapp.com/hooks/response_created_callback',
'event' => 'response_complete'
},
headers: { 'Content-Type' => "application/json"})
response = url.run.body
puts response
This returns a response code of 400 and an error:
Content-Type set to application/json but could not decode valid JSON in request body.
Here are the docs for the API call I am making: http://docs.fluidsurveys.com/api/webhooks.html
POST /api/v2/webhooks/subscribe/ΒΆ
Returns a status of 409 if a webhook with the subscription url already exists. Returns a
status of 201 if the webhook was successfully created. Requests must be sent as an
application/json-encoded dictionary with the required fields subscription_url and event
Sample request (ACCORDING TO DOCS):
{
"subscription_url": "http://fluidsurveys.com/api/v2/callback/",
"event": "response_complete",
"survey": 1,
"collector": 1
}
What am I doing wrong here? survey and collector are optional params, and I don't see an issue with the json in my body.
I am guessing you might need to convert the request body into JSON using a library like Oj (https://github.com/ohler55/oj). Using the Oj library:
requestBody = {
'subscription_url' => 'http://glacial-spire-test.herokuapp.com/hook/response_created_callback',
'event' => 'response_complete'
}
url = Typhoeus::Request.new("https://fluidsurveys.com/api/v2/webhooks/subscribe/",
userpwd: "username_test:password_test",
method: :post,
body: Oj.dump(requestBody, mode: :compat),
headers: { 'Content-Type' => "application/json"})
response = url.run.body
puts response
The critical line is:
body: Oj.dump(requestBody, mode: :compat)
If you need to load any JSON content to Ruby, just use Oj.load

Api Requests with Ruby gem Typhoeus

What is wrong with the following request?
request = Typhoeus::Request.new("http://fluidsurveys.com/api/v2/groups",
method: :get,
userpwd: "test_user:test_password",
headers: { 'ContentType' => "application/json"})
response = request.body
puts response
This returns undefined method body for #<Typhoeus::Request:0x007f8e50d3b1d0> (NoMethodError)
The following request works fine with httparty:
call= "/api/v2/groups/"
auth = {:username => "test_user", :password => "test_password"}
url = HTTParty.get("http://fluidsurveys.com/api/v2/groups",
:basic_auth => auth,
:headers => { 'ContentType' => 'application/json' } )
response = url.body
puts response
EDIT:
I tried this:
response = request.response
puts response.body
with no luck. I receive this : undefined method body for nil:NilClass (NoMethodError)
From https://github.com/typhoeus/typhoeus
You need to do the get before the response body is available.
EDIT: Here is an operable solution. It doesn't use your website, which I couldn't access even manually. But, this returns response code 200 and the response_body. Running this in my debugger showed the complete response, which you could see using "puts response.inspect".
class TyphoeusTry
require 'typhoeus'
request = Typhoeus::Request.new("http://www.google.com",
method: :get,
userpwd: "test_user:test_password",
headers: { ContentType: "application/json"})
response = request.run
puts response.response_body
end
The problem is that you didn't actually execute your request. The following code should work.
request = Typhoeus::Request.new("http://fluidsurveys.com/api/v2/groups",
method: :get,
userpwd: "test_user:test_password",
headers: { 'ContentType' => "application/json"})
request.run
response = request.response
response_code = response.code
response_body = response.body

Resources