Ruby on rails HTTP request issue - ruby-on-rails

I am an newbie to Ruby on Rails. I have a url which points to a JSON output. When I ran the URL directly like http://user:pass#myurl.com/json, I am getting the response without any authendication. However http://myurl.com/json requires a username and password through a standard apache pop up authentication box. I have tried to access this URL from my rails controller like the following:
result = JSON.parse(open("http://user:pass#myurl.com/json").read)
When I try to do, I just get an error which says ArgumentError, userinfo not supported. [RFC3986]
Also I have tried the below one. I am getting a 401-Unauthorized error
open("http://...", :http_basic_authentication=>[user, password])
How can I make a request that works in this case. Any help would be appreciated.

You need to use Net::HTTP (or some other HTTP client).
require 'net/http'
require 'uri'
require 'json'
uri = URI('http://myurl.com/json')
req = Net::HTTP::Get.new( uri )
req.basic_auth 'user', 'pass'
res = Net::HTTP.start(uri.hostname, uri.port) {|http|
http.request(req)
}
result = JSON.parse(res.body)
puts result

Related

how do I include a header in an http request in ruby

Have the below code working:
uri = URI.parse("http://www.ncdc.noaa.gov/cdo-web/api/v2/datasets/")
response = Net::HTTP.get_response(uri)
Now I also need to pass a header with this token hash in it:
token: "fjhKJFSDHKJHjfgsdfdsljh"
I cannot find any documentation on how to do this. How do I do it?
get_response is a shorthand for making a request, when you need more control - do a full request yourself.
There's an example in ruby standard library here:
uri = URI.parse("http://www.ncdc.noaa.gov/cdo-web/api/v2/datasets/")
req = Net::HTTP::Get.new(uri)
req['token'] = 'fjhKJFSDHKJHjfgsdfdsljh'
res = Net::HTTP.start(uri.hostname, uri.port) {|http|
http.request(req)
}
Though you surely could use Net::HTTP for this goal, gem excon allows you to do it far easier:
require 'excon'
url = 'http://www.ncdc.noaa.gov/cdo-web/api/v2/datasets/'
Excon.get(url, headers: {token: 'fjhKJFSDHKJHjfgsdfdsljh'})

API call using Net::HTTP throwing Net::HTTPBadResponse error

I am working on rails environment. I am using Net::HTTP module for calling an external API and getting the response. This is working fine in my local host. But in staging it throwing an Net::HTTPBadResponse error. My staging is SSL enabled. This is the difference. Providing the code snippet and error below.
parameters = {'VirtualNumber' => '09845xxxxxx','Number[]' => "09878xxxxxx" }
x = Net::HTTP.post_form(URI.parse("https://example.com"), parameters)
Error:
Net::HTTPBadResponse (wrong status line: "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">")
The successful result will be in XML format. Can any one help me to solve this.
Thank You,
Regards
The issue was calling the API from ssl enabled site. So while calling the API we need to enable the ssl. And along with that need to provide basic authentication.
parameters = {'VirtualNumber' => '09845xxxxxx','Number[]' => "09878xxxxxx" }
url = URI.parse("https://example.com")
request = Net::HTTP::Post.new(url.path)
request.basic_auth "user", "pass"
request.set_form_data(parameters)
sock = Net::HTTP.new(url.host, url.port)
if url.scheme == 'https'
sock.use_ssl = true
end
response = sock.start {|http| http.request(request) }

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.

403 Developer Inactive on an HTTP pull

I am trying to query some XML from a hotel database using Ruby, and am getting the results:
403 Developer Inactive
I used the code:
require 'net/http'
url = URI.parse('URL of the HTTP query')
req = Net::HTTP::Get.new(url.path)
res = Net::HTTP.start(url.host, url.port) {|http|
http.request(req)
}
puts res.body
I would give the actual URL, but it contains the API key/etc...so I really cannot divulge it.
Is there anything wrong with the code or might it be on the company needing to activate the key?
Thanks
403 is the HTTP status code FORBIDDEN, which leads me to believe you have a problem authenticating your API request, maybe because of a wrong key or something.

Writing Mock RSpec

I have code in my Ruby on rails project as follows, to get HTTP response from non rails API
app/model/rest_api.rb
require "uri"
require "net/https"
require "net/http"
require "active_support"
class RestApi
# the URL for the Twitter Trends endpoint
#url = 'http://api.twitter.com/1/trends.json'
def self.sampleRes
uri = URI.parse( #url)
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
return response
end
end
I have just started learning Ruby on Rails and RSPEC. Can someone please help that how can I write RSpec for HTTP request without actually making request to actual API URL(need some mock)
You can mock out the request part and make expectations about what should be called etc.
mock_req = double("http request")
mock_req.should_receive(:request)
Net::HTTP::Get.should_receive(:new).and_return(mock_req)
Your code could also be simplified to:
open('http://api.twitter.com/1/trends.json').read
You aren't doing any error handling, status checking etc. (maybe this is example code?) but, whatever you expect your request to return you should mock/stub out those expectations.

Resources