I have obtained a valid api key from Google Places API. I need to use this on the backend, so I get a server-side key. However, the call does not work using curl nor the Rails console.
It DOES, however, work thru the browser. That said, I have triple checked that I am using the server-side key that I generated. I'm also only using the sample URL that is in the Google places documentation, so all params should be correct. Here is my curl:
curl -v https://maps.googleapis.com/maps/api/place/search/xml?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&sensor=false&key=my_key
Also, in (Ruby) Rails console:
Net::HTTP.get_response(URI.parse("https://maps.googleapis.com/maps/api/place/search/xml?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&sensor=false&key=my_key"))
Any ideas? It seems like multiple people have had issues, but there is nothing specific out there for server keys not working.
Thanks!
With CURL, be sure to put quotes around the URL. Otherwise, if you're working in Linux, the URL will be truncated after the first ampersand, which will cause a REQUEST_DENIED response.
For HTTPS with Ruby, the following should work (ref http://www.rubyinside.com/nethttp-cheat-sheet-2940.html):
require "net/https"
require "uri"
uri = URI.parse("https://maps.googleapis.com/maps/api/place/search/xml?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&sensor=false&key=...")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
print response.body
Related
I am simply trying to do an HTTP PUT request using a Ruby script, and I am literally copying and pasting 100% of the same thing from Hubspot's example. It's working in Hubspot's example, but not mine.
For example, here's the 99% full code from HubSpot API (with my API key redacted):
# https://rubygems.org/gems/hubspot-api-client
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://api.hubapi.com/crm/v3/objects/deals/4104381XXXX/associations/company/530997XXXX/deal_to_company?hapikey=XXXX")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Put.new(url)
request["accept"] = 'application/json'
response = http.request(request)
puts response.read_body
When initiated by hubspot, the response is an HTTP 201, but in my Ruby script it's giving me the following error:
=> #<Net::HTTPUnsupportedMediaType 415 Unsupported Media Type readbody=true>
I have tried directly copying and pasting the exact same thing, but no luck. I would copy what I'm using, but it's 100% the same code as above except for the redacted API, deal, and company IDs. I have copied and pasted HubSpot's example directly into my rails console, but I get an unsupported media type error.
I have also tried adding a body to the request, such as request.body = "hello" and nothing.
Any suggestion would be greatly appreciated.
After analyzing a working cURL request and the ruby script via BurpSuite, I determined that the following HTTP header in the request was the culprit:
Content-Type: application/x-www-form-urlencoded
For whatever reason, the Ruby code in the original post uses this content-type by default, even though the user doesn't specify it. Makes no sense.
Question
Why, suddenly, do all calls to Firebase Cloud Function webhooks timeout when made via ruby's standard HTTP library (Net::HTTP)?
Background
This works just fine:
require 'net/http'
require 'json'
uri = URI("https://postb.in/1570228026855-4628713761921?hello=world")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = 'application/json'
req.body = {a: 1}.to_json
http.request(req)
end
However the same script does not work with a Cloud Function URL in place of the postb.in one.
Making the same POST request to the Cloud Function URL via cURL works. It's only when made via ruby Net:HTTP library where it's timing out:
/usr/lib/ruby/2.5.0/net/http.rb:937:in `initialize': execution expired (Net::OpenTimeout)
This function has been called many times per second over the past several months, from a Ruby Net:HTTP Post without issue. And it suddenly stopped working last night. I've tested on multiple servers with ruby versions 2.3.8 and also 2.5.
The Cloud Function code is:
export const testHook = functions.https.onRequest((request, response) => {
console.log(request)
response.status(200).send('works')
})
The answer ended up being to add require 'resolv-replace' to the ruby script making use of Net::HTTP to make the HTTP POST. Found that thanks to: Ruby Net::OpenTimeout: execution expired
Why Net:HTTP is able to resolve postbin URLs but not Firebase ones, and why it was able to resolve Firebase ones successfully for many months until suddenly not, I can't explain.
I am trying to get PUT working with httpi. I am using curb (curl) as my adapter with gss negotiation (I need to use a Kerberos token). I am able to GET the article_to_update and I'm able to POST new articles using almost the exact same code (remove article_to_update from the URL and change put to post). With the code below I'm getting 408 errors: "Server timeout waiting for the HTTP request from the client." I've also tried an empty body and got the same results.
Any ideas on how to get this working or to debug further?
Alternate (non-rails) solutions for kerberos-authenticated GET/PUT/POST implementations are welcomed as well. This is for a REST API but I didn't see if/how the rest-client gem supported kerberos.
require 'curb'
require 'httpi'
require 'json'
HTTPI.adapter = :curb
url = URI.escape('https://myserver.com/rest/article/article_to_update')
request = HTTPI::Request.new(url: url, open_timeout: 30)
request.headers['Content-Type'] = 'application/json'
request.headers['Accept'] = 'application/json'
request.auth.gssnegotiate
request.body = JSON.dump(
name: 'discovery',
owner: 'greg'
)
response = HTTPI.put(request)
I'm using the ruby rest-client to send requests to a web service. My requests are working, but I'd like to see the actual request that was sent to the service.
I can't do this with Wireshark or tcpdump because I'm using https and don't have access to the servers private key.
In php, when I've used the SoapClient in the past, I've been able to use the __getLastRequest function to see what xml is sent (http://www.php.net/manual/en/soapclient.getlastrequest.php).
Does anyone know the best way for me to see the actual packets sent to the server?
Many thanks,
D.
You can set the environment variable RESTCLIENT_LOG to stdout, stderr or a file name:
test.rb:
require 'rest-client'
RestClient.get "http://www.google.de"
Call:
RESTCLIENT_LOG=stderr ruby test.rb
Output:
RestClient.get "http://www.google.de", "Accept"=>"*/*; q=0.5, application/xml", "Accept-Encoding"=>"gzip, deflate"
# => 200 OK | text/html 10941 bytes
If you use Net::HTTP instead of rest-client, you can use http.set_debug_output $stderr to see the contents of the request and response:
require 'net/http'
require 'openssl'
uri = URI('https://myserverip/myuri')
http = Net::HTTP.new(uri.host, uri.port)
http.set_debug_output $stderr
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri.request_uri)
request.basic_auth 'username', 'password'
response = http.request(request)
#data = response.body
puts response.body
In addition, using Net::HTTP, I can also get it to use a proxy by using something like http = Net::HTTP::Proxy('127.0.0.1','8888').new(uri.host, uri.port).
You can also do the same with rest-client by using RestClient.proxy = "http://127.0.0.1:8888/" just before your RestClient.get(url) etc..
This way I can send the traffic via a tool like Fiddler2 on Windows and then see all the detail I need.
It's just a shame I can't find an equivalent to Fiddler for the Mac since that's where I want to write the code.
It Looks like I'll either have to rewrite my code to use HTTP::Net instead of rest-client, or switch to Windows full time ;), unless anyone has any other thoughts.
I'm new to Ruby coming from Java. I'm trying to make a http get request and I'm getting an http response code of 400. The service I'm calling over http is very particular and I'm pretty sure that my request isn't exactly correct. It'd be helpful to "look inside" the req object after I do the head request (below) to double check that the request_headers that are being sent are what I think I'm sending. Is there a way to print out the req object?
req = Net::HTTP.new(url.host, url.port)
req.use_ssl = true
res = req.head(pathWithScope, request_headers)
code = res.code.to_i
puts "Response code: #{code}"
I tried this: puts "Request Debug: #{req.inspect}" but it only prints this: #<Net::HTTP www.blah.com:443 open=false>
Use set_debug_output.
http = Net::HTTP.new(url.host, url.port)
http.set_debug_output($stdout) # Logger.new("foo.log") works too
That and more in http://github.com/augustl/net-http-cheat-sheet :)
If you want to see & debug exactly what your app is sending, not just see its log output, I've just released an open-source tool for exactly this: http://httptoolkit.tech/view/ruby/
It supports almost all Ruby HTTP libraries so it'll work perfectly for this case, but also many other tools & languages too (Python, Node, Chrome, Firefox, etc).
As noted in the other answer you can configure Net::HTTP to print its logs to work out what it's doing, but that only shows you what it's trying to do, it won't help you if you use any other HTTP libraries or tools (or use modules that do), and it requires you to change your actual application code (and remember to change it back).
With HTTP Toolkit you can just click a button to open a terminal, run your Ruby code from there as normal, and every HTTP request sent gets collected automatically.