RestClient for Ruby with smarkets.com api - Curl to RestClient - ruby

the api I'm working with is here:
I'm able to log in fine and get back an auth token, but cant figure out how to do anything that requires a token. I get back a forbidden response when I try to get or post a private URL.
they give an example of the request that needs to be sent using curl:
curl \
--header 'Authorization: UserLogin token="kk5lvKJG1FohVbS3kcHllyTshdcBKX4FpFAKFnx_Eh0IYYpXN3Hg6HZLceXuYt7V52mCcdUk5i_GUMc~"' \
-X POST \
'https://api.smarkets.com/v1/users/renew'
My question is: how would one send an equivalent request using the RestClient library in Ruby? I have a feeling that i'm messing up the header because the header in RestClient is all {:key => 'value'} pairs and I don't see how that would translate to the header given in the example.

In an HTTP request, headers are key/value pairs separated by a :, so the header pair that you need to send is:
:authorization => 'UserLogin token="kk5lvKJG1FohVbS3kcHllyTshdcBKX4FpFAKFnx_Eh0IYYpXN3Hg6HZLceXuYt7V52mCcdUk5i_GUMc~"'
So, to reproduce the request you give in your example:
RestClient.post 'https://api.smarkets.com/v1/users/renew', '', :authorization => 'UserLogin token="kk5lvKJG1FohVbS3kcHllyTshdcBKX4FpFAKFnx_Eh0IYYpXN3Hg6HZLceXuYt7V52mCcdUk5i_GUMc~"'

Related

Refresh token response with missing elements of conversation object

I have been working with Direct Line for a long time, but I'm confused when refreshing tokens. I send a request like:
curl --location --request POST 'https://directline.botframework.com/v3/directline/tokens/refresh' --header 'Authorization: Bearer xxxxx'
And according to the documentation here, it should return a conversation object (described here), that should contain (amongs others) streamUrl and referenceGrammarId (as it does in generate token), but I don't get them in the response, I get just conversationId, token and expires_in, making it more difficult to handle the token refresh.
Is this the expected behavior, or those missing properties should be present?
Yes, it was the expected behavior, said the technical team at Microsoft.

How to get Headers from request?

I am trying to create a webhook. I am brand new to Ruby, but am setting up a very simple practice server. Each time a new issue/ticket is created for one of my github repos, a POST request is made to a URL that I have setup to grab the payload. I am loosely following this tutorial.
I am able to access all the elements that are being posted in the actual payload/body using this code:
require 'sinatra'
require 'json'
post '/payload' do
request.body.rewind
payload_body = request.body.read
puts payload_body
How can I grab the contents of the header? I have been scrolling through documentation, but have had no luck. I tried accessing the header through response and request.headers and received this error: NoMethodError - undefined method `headers' for #<Sinatra::Request:0x0000000006de49e0>
Please let me know if I am missing something here. Thank you.
Here is an example of the headers from my POST request:
Request URL: http://505db39aa8ef.ngrok.io:
Request method: POST
Accept: */*
content-type: application/json
User-Agent: GitHub-Hookshot/cf3e7e0
X-GitHub-Delivery: 8d7fe080-ecc2-11ea-9b34-d35efaaf3885
X-GitHub-Event: issues
X-GitHub-Hook-ID: 245792914
X-GitHub-Hook-Installation-Target-ID: 279687508
X-GitHub-Hook-Installation-Target-Type: repository
X-Hub-Signature: sha1=ed12f9e7a31b08f9109557d6a9dd899ca85de9b5
request.get_header('HTTP_X_GITHUB_HOOK_INSTALLATION_TARGET_TYPE')
# or
request.env['HTTP_X_GITHUB_HOOK_INSTALLATION_TARGET_TYPE']
It is worth mentioning that,sinatra will process custom header:
add prefix HTTP_
capitalize every letter
gsub - to _
You can use request.env to access all headers.
For detail information about what variable will be added HTTP_ you can refer there

ixudra/curl post multipart/form-data with different content type

I am trying to post multipart/form-data in laravel using ixudra/curl that specify the data is application json. The problem Im facing right know is to assign the type for data and still make the header content type is multipart/form-data.
$contents = storage_path('app/curl.txt');
$dataJson = '{"bId":"79", "docId":"23"}';
$response = Curl::to($url)
->withHeaders( array(
'Authorization: Bearer 123432',
'grant_type: jwt-bearer' ) )
->withData( array ('data' => $dataJson ))
->withFile('file', $contents, 'text/*', 'curl.txt')
->containsFile()
->withResponseHeaders()
->returnResponseObject()
->post();
For the curl, it is like this. Somehow, the error is "Failure to Authenticate OAuth Token" and the header content type is not multipart/form-data
curl -v -H "Authorization:Bearer 123432"
-H "grant_type:jwt-bearer"
-F "file=#\"/jet/app/www/default/test/storage/app/curl.txt\""
-F "data={\"bId\":\"79\", \"docId\":\"23\"};type=application/json"
"https://url/private"
Any idea? thanks for your time.
is this still an issue? Looking at your code, I don't see any errors in there. You don't need to include the containsFile() method in there but that's really a detail that won't effect your result in any way.
Based on your description, I doubt that the file has anything to do with the error. I'd recommend trying to make sure if the authentication is correct by using it on a simple GET request, just to make sure. If that works, you should dig deeper into the form.

Pass parameters in RestClient post request

I want to send parameters with a POST request using the RestClient gem (but I don't want to pass the params as JSON).
In a GET request, I would have:
url = "http://example.com?param1=foo&param2=bar"
RestClient.get url
How can I pass the same params but in a POST request without passing a JSON ?
Read ReadMe file of Rest-client git, it has lots of examples showing different types of request.
For your answer, try :
url = "http://example.com"
RestClient.post url,:param1=>foo, :param2=>bar

Post request with body_stream and parameters

I'm building some kind of proxy.
When I call some url in a rack application, I forward that request to an other url.
The request I forward is a POST with a file and some parameters.
I want to add more parameters.
But the file can be quite big. So I send it with Net::HTTP#body_stream instead of Net::HTTP#body.
I get my request as a Rack::Request object and I create my Net::HTTP object with that.
req = Net::HTTP::Post.new(request.path_info)
req.body_stream = request.body
req.content_type = request.content_type
req.content_length = request.content_length
http = Net::HTTP.new(#host, #port)
res = http.request(req)
I've tried several ways to add the proxy's parameters. But it seems nothing in Net::HTTP allows to add parameters to a body_stream request, only to a body one.
Is there a simpler way to proxy a rack request like that ? Or a clean way to add my parameters to my request ?
Well.. as i see it, this is a normal behaviour. I'll explain why. If you only have access to a Rack::Request,(i guess that) your middleware does not parse the response (you do not include something like ActionController::ParamsParser), so you don't have access to a hash of parameters, but to a StringIo. This StringIO corresponds to a stream like:
Content-Type: multipart/form-data; boundary=AaB03x
--AaB03x
Content-Disposition: form-data; name="param1"
value1
--AaB03x
Content-Disposition: form-data; name="files"; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--AaB03x--
What you are trying to do with the Net::HTTP class is to: (1). parse the request into a hash of parameters; (2). merge the parameters hash with your own parameters; (3). recreate the request. The problem is that Net::HTTP library can't do (1), since it is a client library, not a server one.
Therefore, you can not escape parsing some how your request before adding the new parameters.
Possible solutions:
Insert ActionController::ParamsParser before your middleware. After that, you may use the excellent rest-client lib to do something like:
RestClient.post ('http://your_server' + request.path_info), :params => params.merge(your_params)
You can attempt to make a wrapper on the StringIO object, and add, at the end of stream,your own parameters. However, this is not trivial nor advisable.
Might be one year too late, but I had the same issue verifying Paypal IPNs. I wanted to forward back the IPN request to Paypal for verification but needed to add :cmd => '_notify-validate'.
Instead of modifying the body stream, or body, I appended it as part of the URL path, like so:
reply_request = Net::HTTP::Post.new(url.path + '?cmd=_notify-validate')
It seems a bit of a hack, but I think it's worth it if you aren't going to use it for anything else.

Resources