(rails) weird problem with url validation - ruby-on-rails

i'm trying to see if a url exists. here is my code for doing so:
validate :registered_domain_name_exists
private
def registered_domain_name_exists
if url and url.match(URI::regexp(%w(http https))) then
begin # check header response
case Net::HTTP.get_response(URI.parse(url))
when Net::HTTPSuccess then true
else errors.add(:url, "URL does not exist") and false
end
rescue # DNS failures
errors.add(:url, "URL does not exist") and false
end
end
end
however, this code is failing. it says http://www.biorad.com is not a valid website. this is absolutely incorrect. Also, knowing that http://www.biorad.com just redirects you to http://www.bio-rad.com/evportal/evolutionPortal.portal i tried this url too, and that also failed. again, i know this can't be possible. what's wrong with my code??

Each of the example urls you gave is a redirect (http status code 301 or 302). Your code is only considering http status code 2xx to be success. Add another case:
when Net::HTTPRedirection then true
UPDATE: Note that using HTTP HEAD instead of GET will transmit less data across the network.
uri = URI.parse(url)
response = Net::HTTP.start(uri.host, uri.port) {|http|
http.head('/')
}

Related

How can I get the value in a hash of the response of POST request on Ruby?

Now, I am working on a project using post request on Ruby.
I could get the response with the code below.
def send_param(param)
uri = URI.parse('https:~~~~~~~~~~~~')
https = Net::HTTP.new(uri.host, 443)
response = https.post(uri.path, param.to_query)
print response.body
end
And response.body looks like something like this
{"result": {"id":1111, "name": John}}
Now, I need to get the value of John above.
it will be something like this.
response["name"]
but I can't get the value as expected.
So I want you to help me, if you can.
Thank you.
You can parse it and fetch the result after it using the dig method.
def send_param(param)
uri = URI.parse('https:~~~~~~~~~~~~')
https = Net::HTTP.new(uri.host, 443)
response = https.post(uri.path, param.to_query)
JSON.parse(response.body)
end
result = send_param({})
result.dig('result', 'name')

Rails app to check the status of a server

I want to achieve a problem, where we manually go and check a webapp/server if it is up/down. I want to build a rails app which can automate this task.
Consider my app url is: HostName:PORT/Route?Params (may or may not have port in url)
I checked 'net/http'
def check_status()
#url='host'
uri = URI(#url)
http = Net::HTTP.new(#url,port)
response = http.request_get('/<route>?<params>')
if response == Net::HTTPSuccess
#result='Running'
else
#result='Not Running'
end
end
I am facing error at ,
response = http.request_get('/<route>?<params>')
when the app is down throwing 'Failed to open TCP connection to URL' which is correct.
Can you guys help me find some new solution or how can I improve the above implementation?
Since it's working as intended and you just need to handle the error that's returned when the app is down, wrap it in a rescue block.
def check_status()
#url='host'
uri = URI(#url)
http = Net::HTTP.new(#url,port)
begin
response = http.request_get('/<route>?<params>')
rescue TheClassNameOfThisErrorWhenSiteIsDown
#result = 'Not Running'
end
if response == Net::HTTPSuccess
#result='Running'
else
#result='Not Running'
end
end
end
Just came across this old question. Net::HTTP methods get and head don't raise an exception. So use one of these instead.
def up?(site)
Net::HTTP.new(site).head('/').kind_of? Net::HTTPOK
end
up? 'www.google.com' #=> true

RSpec tests for RestClient::Request.execute: Any way to see the request?

I am using RestClient gem to build an API client and the calls to the API are processed by this method here
def call(api_name,api_endpoint,token = nil,*extra_params)
endpoint = fetch_endpoint(api_name,api_endpoint)
params = {}
endpoint['params'].each_with_index { |p,i| params[p] = endpoint['values'][i] }
puts params
if token.nil? then
response = RestClient::Request.execute(method: endpoint['method'], url: endpoint['url'], params: params.to_json)
else
response = RestClient::Request.execute(method: endpoint['method'], url: endpoint['url'], headers: {"Authorization" => "Bearer #{token}"}, params: params.to_json)
end
response
end
As you may see, all I do is mounting a hash with parameters/values for the call and invoking RestClient::Request#execute to get a response.
It happens that some of my tests, like this one
it 'request_autorization' do
obj = SpotifyIntegration.new
response = obj.call('spotify','request_authorization',nil,state: obj.random_state_string)
myjson = JSON.parse(response.body)
expect(myjson).to eq({})
end
are returning a 400 Bad request error, and I really don't know why. Other tests, like this one
it 'my_playlists (with no authorization token)' do
obj = SpotifyIntegration.new
expect {
response = obj.call('spotify','my_playlists')
}.to raise_error(RestClient::Unauthorized,'401 Unauthorized')
end
processed by the same method, run perfectly fine.
Is there any way to see the request sent? I mean, see how RestClient is mount/sending my request to the corresponding API? May be this way I could understand what is happening.
By "see the request" I mean something like
puts RestClient::Request.prepared_request
or
puts RestClient::Request.prepared_url
I've searched the RestClient documentation and found nothing similar, but maybe some of you know how to do this.
You might try using RestClient.log to get more information. Something like:
RestClient.log = STDOUT
WebMock is also a great test framework for HTTP requests. The tests for rest-client itself make a lot of use of WebMock.

Ruby: Detecting broken links without actually crawling the URL?

Is there a Ruby gem, or Ruby-esque way to check a webpage for broken links without crawling the actual links and checking for 404's, etc. Basically, I want a solution that works offline, and I want to detect links that are obviously syntactically broken, not links that point to web pages that don't exist.
So for instance, if a link points to "http//stackoverflow.com", that's a syntactically broken link, and I want to detect that. However if a link points to "http://www.webpagedoesnotexistyet.com" and it returns a 404, I'm OK with not detecting that.
Use nokogiri to parse the HTML and URI.parse to check for valid URLs. URI will raise an error if it encounters what it considers to be an invalid url.
Use this : Links below is an array of links
for link in links do
begin
url = URI.parse(link)
req = Net::HTTP.new(url.host, url.port)
res = req.request_head(url.path)
if res.code == "200"
puts "#{res.code} ok - #{link}"
else
puts "#{res.code} error - #{link}"
end
rescue
puts "breaking for #{link}"
end
end
You can use URI.regexp. If a string matches it, it is a valid uri.
require 'uri'
def valid_uri?(s)
!!(s =~ URI.regexp)
end
valid_uri?('http//stackoverflow.com') # => false
valid_uri?('http://www.webpagedoesnotexistyet.com/') # => true

Validating URL by making request

In Rails controller, I'd like to validate a user-inputted URL (say, it's in a variable url) by making a request to it, and checking that the response is not 50X. How can I do that?
You can send request from a controller using Net::Http module as follows
uri = URI('http://festivalsherpa.com')
response = Net::HTTP.get_response(uri)
response.to_hash["status"] will return you proper response code
There is one more way
you can do in more meaningful way like:
uri = URI.parse(your_url)
connection = Net::HTTP.new(uri.host)
request = Net::HTTP::Get.new(uri.request_uri) # For post req, you can replace 'Get' by 'Post'
response = connection.request(request)
You can see what is returned:
p response.body
If the response returned is JSON, then you can do
JSON.parse(response.body) #It will give you hash object
You can check the response code/status
p response.code
If you want to handle status codes, then you can handle it through case statements
case response.code
when "200"
<some code>
when "500"
<some code>
end
And so on..

Resources