Stubing HTTPS call using WebMock - ruby-on-rails

I'd like to stub https call using webmock.
Let's assume gateway url as https://some_gateway.com.
After doing:
stub_request(:post, 'https://some_gateway.com').with(body: {})
in specs.
I use Net::HTTP to generate request:
Net::HTTP.post_form(URI.parse('https://some_gateway.com'), {})
I receive problem because Webmock expects https://some_gateway.com but receives version with added port 433 so: http://www.secure.fake-payment.com:443/gateway_prod so can't see registered stub.
How can I deal with this behavior ?

Take a look at the answer for this question: WebMock: Rspec - Test Facebook Validation by using JSON response
Your code will do http request with port 443 vs doing really https
Net::HTTP.post_form(URI.parse('https://some_gateway.com'), {})
And here you can find the answer how to do https request using Net::HTTP
Using Net::HTTP.get for an https url

Related

AWS API Gateway issue for HTTP Method

I created an AWS API-gateway for an HTTP method PUT. When I do a test in API-gateway, that works fine, but when I call it from a REST client, I get 404 bad-request and missing authentication token errors. I didn't set any authorization to true or a required API key to true.
I passed these query parameters to a REST client:
auth_id : 8798iuyiu123123
time_stamp :1231231
test_json : [{"id"=>"1","value"=>"mount"},{"id"=>"2","value"=>"chart"}]
HEADER
content-type : application/json
When I change the test_json value to %5B%7B%22id%22:%221%22,%22value%22:%22test%22%7D,%7B%22id%22:%222%22,%22value%22:%2213+%D8%B4%D8%A7%D8%B1%D8%, then I get the response.
i am new to react, calling from react
Request.put('https://api-gateway.sqwdwed123.com/eretw/update-chart')
.set('Content-Type', 'application/json')
.query({ auth_id: localStorage.auth_id})
.query({ time_stamp:this.props.time_stamp})
.query({ test_json:JSON.stringify(newadd)})
should i pass this test_json through body?
Am I doing anything wrong?
This is usually related to requesting a URL that doesn't exist. Please make sure you're using the correct HTTP method and resource path to a valid resource (the sample invoke URL does not include any resource path). If this still doesn't work. Make sure you actually deployed your API.
The HTTP Response of Bad Request is because you have the Query Parameter that are not URL Encoded. There are 2 things that you can do now:
Pass the test_json as Query Param but making sure that they are URL Encoded. This will put a restriction on the size of the string and hence Not Recommended.
Pass the test_json as Request Body. (Recommended)

Ruby Net::HTTP using SSL

I have a very simple API, that I would like to make a POST to using ruby and NOT using a GEM just the built in libraries net/http, uri, and openssl if needed.
Anyway, I am using the code below to make a very simple POST request but am getting some VERY strange results and was hoping someone else has seen this.
I have also tested the same request below in POSTMAN and NodeJS and BOTH work as expected, the only one I can not get to work is Ruby.
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://somesite.dev/devices")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["key"] = '1234567'
response = http.request(request)
puts response.read_body
The result is something I have not seen before: I am getting the header key twice... So the log to the API shows a query like this:
SELECT * FROM device where key = '1234567, 1234567' LIMIT ...
As stated above I can make the same request via POSTMAN or NodeJS and get the correct result.
NOTE: Because I have a local copy of the API I can test locally BUT it's not SSL it's all over http. When making the request locally it works just fine. So from what I can tell this issue only presents it self when SSL is introduced.
Any help would be amazing! Thanks!!
Ruby Version 2.2.1
The issue was with something I did not list in my initial question. The API was using AWS API Gateway, and HTTP_PROXY was enabled on the method causing this strange issue. After I removed HTTP_PROXY the issue cleared up and the above code worked!

Query server with PUT method

I will replace my command line
`curl -XPUT 'host:port/url' -d '{"val": "some_json"}'̀
by a Rails command, and get the result...
Somewhere like this :
response = call('put', 'host:port/url', '{"val" : "some_json"}')
Is there any predefined method to do this in Rails, or some gem ?
I know the command get of HTTP, but I will do a 'PUT' method.
Net::HTTP.get(URI.parse('host:port/url'))
Thanks for your replies
You can use Net::HTTP to send any standard http requests.
Here is a way, you can connect to any url ( http / https ), with any valid http methods with or without parameters.
def universal_connector(api_url, api_parameters={}, method="Get")
# Do raise Error, if url is invalid and Method is invalid
uri = URI(api_url)
req = eval("Net::HTTP::#{method.capitalize}.new('#{uri}')")
req.set_form_data(api_parameters)
Net::HTTP.start(uri.host, uri.port,:use_ssl => uri.scheme == 'https') do |http|
response = http.request(req)
return response.body
end
end
There are many alternatives available as well. Specifically, Faraday. Also, read this before making a choice.
#get is just a simple shortcut for the whole code (Net::HTTP Ruby library tends to be very verbose). However, Net::HTTP perfectly supports PUT requests.
Another alternative is to use an HTTP client as a wrapper. The most common alternatives are HTTParty and Faraday.
HTTParty.put('host:port/url', { body: {"val" : "some_json"} })
As a side note, please keep in mind that Rails is a framework, not a programming language. Your question is about how to perform an HTTP PUT request in Ruby, not Rails. It's important to understand the difference.

Ruby Proxy Authentication GET/POST with OpenURI or net/http

I'm using ruby 1.9.3 and trying to use open-uri to get a url and try posting using Net:HTTP
Im trying to use proxy authentication for both:
Trying to do a POST request with net/http:
require 'net/http'
require 'open-uri'
http = Net::HTTP.new("google.com", 80)
headers = { 'User-Agent' => 'Ruby 193'}
resp, data = http.post("/", "name1=value1&name2=value2", headers)
puts data
And for open-uri which I can't get to do POST I use:
data = open("http://google.com/","User-Agent"=> "Ruby 193").read
How would I modify these to use a proxy with HTTP Authentication
I've tried (for open-uri)
data = open("http://google.com/","User-Agent"=> "Ruby 193", :proxy_http_basic_authentication => ["http://proxy.com:8000/", "proxy-user", "proxy-password"]).read
However all I will get is a OpenURI::HTTPError: 407 Proxy Authentication Required. I've verified all and it works in the browser with the same authentication and proxy details but I can't get ruby to do it.
How would I modify the code above to add http authentication properly? Has anyone gone through this atrocity?
Try:
require "open-uri"
proxy_uri = URI.parse("http://proxy.com:8000")
data = open("http://www.whatismyipaddress.com/", :proxy_http_basic_authentication => [proxy_uri, "username", "password"]).read
puts data
As for Net::HTTP, I recently implemented support for proxies with http authentication into a Net::HTTP wrapper library called http. If you look at my last pull-request, you'll see the basic implementation.
EDIT: Hopefully this will get you moving in the right direction.
Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port,"username","password").start('whatismyipaddress.com') do |http|
puts http.get('/').body
end
EDIT 11/24/2020: Net::HTTP::Proxy is now considered obsolete. You can now configure proxies when creating a new instance of Net::HTTP. See the documentation for Net::HTTP.new for more details.

Setting outgoing IP address in open-uri with RoR

I'm new to open-uri and trying to set an outgoing IP address using open-uri in ruby on rails. I used this post as a reference to get started. I'm porting an app from PHP where I could use CURLOPT_INTERFACE in curl_setopt. What's the best way to do this using open-uri in rails? (Doing this from the controller - not command line.)
If there's not a way to do this - any suggestions on an alternative to open-uri? My goal is to take in and parse JSON data.
What I understand from your questions is you want to hit another server from a specific IP which suggests you have a server with couple of addresses.
What I can suggest you is try to execute curl directly and do what you want to do or use a wrapper for it.
Doesn't look like open-uri can do this. But with net/https it's fairly easy.
require 'net/https'
require 'json'
uri = URI('https://jsonvat.com/')
http = Net::HTTP.new(uri.host, uri.port)
http.local_host = '1.2.3.4'
http.use_ssl = true
request = Net::HTTP::Get.new('/')
request.content_type = 'application/json'
request.initialize_http_header('Content-Type' => 'application/json')
response = http.request(request)
json = JSON.parse(response.body)
Probably you don't need the "require" lines inside Rails Controllers.
You can specify the outgoing IP address with the http.local_host line.
https://stackoverflow.com/a/24896074/1371731
https://yukimotopress.github.io/http

Resources