Ruby HTTPS Post issue - ruby-on-rails

I have two codes (variable info masked intentionally), the first one I receive the response with 200 code return, but second one I get 403 forbidden, any idea?
def get_token()
http = Net::HTTP.new(server, 443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?
#path(a.k.a) ->www.mysite.com/some_POST_handling_script.rb'
path = '/rest/fastlogin/v1.0?app_key=' + app_key + '&username=%2B' + username + '&format=json'
puts path
headers = {'Content-Type'=> 'application/x-www-form-urlencoded', 'Authorization' => password }
resp, data = http.post(path, data, headers)
puts 'Code = ' + resp.code
puts 'Message = ' + resp.message
resp.each {|key, val| puts key + ' = ' + val}
puts data
puts JSON.parse(resp.body)["access_token"]
result = {}
result["code"] = resp.code
result["token"] = JSON.parse(resp.body)["access_token"]
print result
return result
end
def get_token1()
path = '/rest/fastlogin/v1.0?app_key=' + app_key + '&username=%2B' + username + '&format=json'
uri = URI.parse('https://' + server + path)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?
req = Net::HTTP::Post.new(uri.path)
req["Authorization"] = password
puts uri.host
puts uri.path
puts uri.port
resp,data = http.request(req)
print resp
end

I think this is authentication issue. Credentials which you provide are wrong. That's why 403 forbidden error is occurring.

Related

Add a single contact via sendgrid api in Ruby on Rails

I have a Rails 5 app and have a form where I want the user to enter their email address and be added as a contact. THIS QUESTION go me pretty close. The response error I am getting is: {"errors":[{"field":null,"message":"access forbidden"}]}which looks like an authentication issue. Here is my code...
def email_signup
email_address = params[:email_address]
url = URI("https://api.sendgrid.com/v3/contactdb/recipients")
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["authorization"] = 'Bearer <<my_api_key>>'
request["content-type"] = 'application/json'
request.body = "[{\"email\" : email_address}]"
response = http.request(request)
redirect_to jobs_url, notice: response.read_body
end
What am I missing?
OK...I had two issues that needed to be addressed. First, I had the << in the string portion of my API key, the other was that the request body wasn't formatted quite right. Here is what worked for me:
def email_signup
email_address = params[:email_address]
url = URI("https://api.sendgrid.com/v3/contactdb/recipients")
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["authorization"] = 'Bearer SG.Q9sdfsd9s098sdf89sf809sdf809sd'
request["content-type"] = 'application/json'
request.body = [{"email": email_address}].to_json
response = http.request(request)
redirect_to jobs_url, notice: response.read_body
end

use_ssl value changed, but session already started when trying to make https request

I’m using Rails 4.2.7 and this code for making a Net::Http get request
req = Net::HTTP::Get.new(url)
if !headers.nil?
headers.each do |k, v|
req[k] = v
end
end
res = Net::HTTP.new(uri.host, uri.port).start do |http|
http.use_ssl = (uri.scheme == "https")
http.request(req)
end
status = res.code
content_type = res['content-type']
content_encoding = res['content-encoding']
content = res.body
However, when I make one in which the scheme is “https”, I get the following error
Error during processing: use_ssl value changed, but session already started
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:758:in `use_ssl='
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:118:in `block in get_content'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:853:in `start'
How do I set https while still being able to make my GET request?
According to docs, use_ssl
must be set before starting session.
This is my usual flow:
uri = URI 'some endpoint with encoded params'
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
headers = headers.each_with_object({}) { |(k, v), hash| hash[k] = v }
http.get(uri.request_uri, initheader = headers)
See the docs on get.
Sidenote on your
if !headers.nil?
It would be more readable if you just check for presence:
if headers.present?
Or even shorter:
if headers # would return true unless it's nil or false

Net::HTTP::Post.new request returns empty body in Ruby 2

In Ruby 2.0.0p195, Rails 4.0.0, Net::HTTP::Post.new request returns empty body of response.
#toSend = {
"zuppler_store_id" => 'X3r82l89',
"user_id" => '1'
}.to_json
uri = URI("http://smoothpay.com/zuppler/gen_token_post.php")
http = Net::HTTP.new(uri.host,uri.port)
req = Net::HTTP::Post.new uri
req.content_type = "application/json"
req.body = #toSend # or "[ #{#toSend} ]" ?
res = Net::HTTP.start(uri.host, uri.port) {|http| http.request(req)}
puts "Response #{res.code} - #{res.message}: #{res.body}"
This code returns "Response 200 - OK:"
But it should return like this: {"result":"success","token":"843e5be88fb8cee7d324244929177b4e"}
You can check it by typing this url:
http://smoothpay.com/zuppler/gen_token_test.php
Why is res.body empty?
Seems like that service doesn't like the POST request to be application/json.
This works:
uri = URI("http://smoothpay.com/zuppler/gen_token_post.php")
http = Net::HTTP.new(uri.host,uri.port)
req = Net::HTTP::Post.new uri
req.body = "zuppler_store_id=X3r82l89&user_id=1"
res = Net::HTTP.start(uri.host, uri.port) {|http| http.request(req)}
res.body # => "{\"result\":\"success\",\"token\":\"9502e49d454ab7b7dd2699a26f742cda\"}"
In other words, give the service application/x-www-form-urlencoded. Peculiarly, it will hand you back text/html which you'll have to JSON.parse. Weird service.

How to optimize this Ruby code that fetches web content?

We have a Rails 3.2.12 app that fetches data from a partner API by making POST requests. However, we're finding that our code seems to be a bottleneck, as it takes longer to process requests than expected. Can we do anything to speed up the code?
Should we use another XML parser? Is there a faster way to post SSL requests in Ruby?
Thanks!
def ced( ad )
# Set vars
u = 'e'
pw = 'p'
ad = ad.join ','
url = 'https://r.e.com/interface.asp?ResponseType=XML&Command=BC' + '&UID=' + u + '&PW=' + pw + '&DL=' + ad
results = []
# Invoke API command
uri = URI.parse url
http = Net::HTTP.new uri.host, uri.port
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
req = Net::HTTP::Get.new uri.request_uri
resp = http.request req
# Parse API response
resp_xml = Nokogiri.XML resp.body
resp_xml.remove_namespaces!
num_errors = resp_xml.at_xpath('//ErrCount').content
# Any errors?
if num_errors != '0'
error = true
# No errors, process domains
else
resp_xml.xpath('//CheckResult').each do |elem|
results << {
:domain => elem.xpath('D').text.downcase,
:status => case elem.xpath('RRPCode').text
when '210' then 'a'
when '211' then 't'
else
error = true
'error'
end
}
end
end
<truncated>
end

Too many open files - socket(2) with net/http

I have a problem with http requests with net/http...
I writing a ruby script that interacts with the dailymotion api.
This script will upload a video "test.flv".
Basically it consists of four requests.
It works perfectly until step "#Create the video object".
The following error is raised on the last
"response = http.request(req)" command ->
Errno::EMFILE: Too many open files - socket(2)
Here is the code, thx for any advice...
require 'net/http'
require 'curb'
require 'json'
# Authenticate the user
url = URI.parse( 'https://api.dailymotion.com/oauth/token' )
req = Net::HTTP::Post.new(url.path)
req.set_form_data({ 'grant_type' => 'password',
'client_id' => 'my_client_id',
'client_secret' => 'my_client_secret',
'username' => 'myusername',
'password' => 'mypassword'
})
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = http.request(req)
access_token = JSON.parse( response.body )['access_token']
access_url = 'https://api.dailymotion.com/file/upload?access_token=' + access_token
# Get an upload URL
url = URI.parse( access_url )
req = Net::HTTP::Get.new( url.request_uri )
http = Net::HTTP.new( url.host, url.port )
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = http.request( req )
upload_url = JSON.parse( response.body )['upload_url']
progress_url = JSON.parse( response.body )['progress_url']
# Post the video
fields_hash = {}
post_data = fields_hash.map { |k, v| Curl::PostField.content(k, v.to_s) }
post_data << Curl::PostField.file('file', 'C:/test.flv')
c = Curl::Easy.new(upload_url)
c.multipart_form_post = true
c.http_post(post_data)
file_url = JSON.parse( c.body_str )['url']
# Create the video object
url = URI.parse( 'https://api.dailymotion.com/me/videos' )
req = Net::HTTP::Post.new(url.path)
req.set_form_data({ 'url' => file_url,
'access_token' => access_token
})
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = http.request(req)
puts response.body
Try calling finish
http.finish
after the response = http.request( req ).

Resources