REST Client and foreign characters - ruby-on-rails

How does one deal with foreign characters in REST Client? Ie.:
RestClient.get "http://api.example.com/1.0/items.json;q=æøå"
which in Ruby on Rails unfortunately returns:
URI::InvalidURIError in MyController#index
bad URI(is not URI?)
The URL works fine in the browser.

According to its docs:
If you need to normalize URIs, e.g. to work with International
Resource Identifiers (IRIs), use the addressable gem
(addressable.rubyforge.org/api/) in your code:
require 'addressable/uri'
RestClient.get(Addressable::URI.parse("http://www.詹姆斯.com/").normalize.to_str)
Or you can try to encode/escape the string beforehand:
http://ruby-doc.org/stdlib-1.9.3/libdoc/uri/rdoc/URI/Escape.html#method-i-encode

Related

How to get the hostname from a url with accented letters inside in Ruby

I have the following url inside a field of model:
https://www.reddit.com/r/italy/comments/i6ix3x/trenitalia_sostiene_che_potrà_non_rispettare_il/?sort=new
Inside the URL there is an accented letter (à). If I use URI.parse to get hostname gives me the following error:
URI::InvalidURIError: URI must be ascii only "https://www.reddit.com/r/italy/comments/i6ix3x/trenitalia_sostiene_che_potr\u00E0_non_rispettare_il/?sort=new"
The method URL.encode resolves the problem, but I discover that the URL.encode is obsolete and should not be used.
Which method should I use for replacing URI.encode?
this is encoding issue and you need to do it as below
first lets encode your URI first
encoded_url = URI.encode('https://www.reddit.com/r/italy/comments/i6ix3x/trenitalia_sostiene_che_potrà_non_rispettare_il/?sort=new')
And then parse it
URI.parse(encoded_url)
good luck
The only solution that I find uses the gem Addressable(https://github.com/sporkmonger/addressable):
Addressable::URI.parse('https://www.reddit.com/r/italy/comments/i6ix3x/trenitalia_sostiene_che_potrà_non_rispettare_il/?sort=new').host
Perhaps this could be an inelegant solution:
URI.parse(URI.extract(target.url).first)
# => #<URI::HTTPS https://www.reddit.com/r/italy/comments/i6ix3x/trenitalia_sostiene_che_potr>
Then I use the method host
URI.parse(URI.extract(target.url).first).host
# => "www.reddit.com"

How to use external API in Ruby in Rails

I need to use an external API in my app in order to have companies informations. Beginning and having never used API in ruby, I don't know where to start. Maybe there is a gem for it but I have found 2 API that returns me JSON : https://datainfogreffe.fr/api/v1/documentation and https://firmapi.com/ (they're in french sorry about that).
Does someone have a good tutorial or hints to help me begin ?
The final need is to retrieve companies datas just by giving the company ID.
You can use Net::HTTP to call APIs in Ruby on Rails.
uri = URI(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path, {'Content-Type' => 'application/json'})
request.body = {} # SOME JSON DATA e.g {msg: 'Why'}.to_json
response = http.request(request)
body = JSON.parse(response.body) # e.g {answer: 'because it was there'}
http://ruby-doc.org/stdlib-2.3.1/libdoc/net/http/rdoc/Net/HTTP.html
You can use gem for calling REST APIs in ruby.
Also, if you want to find any ruby gem for any purpose you can have a look at this.
You can have a look at this to get company details.
You need to use HTTP client library. There are a few popular libraries:
HTTParty
Faraday
Built-in Net::HTTP
Rest-Client
HTTPClient
You can take a look and compare them on Ruby Toolbox:
https://www.ruby-toolbox.com/categories/http_clients
Faraday is the most popular one. But it is the heaviest also because it covers most cases. So check documentation for each and depending on your task pick one that works the best.

How to validate URIs by checking if those refer to a given domain name?

I am running Ruby on Rails 4.1.1 and I would like to validate URIs by checking if those are within a given domain name. That is, a uri string can be sent as params to my controller and I would like to check if that uri "refers" to my application domain name www.myapp.com. Of course, the uri should be a valid URI reference.
# Invalid URIs
www.website.com
http://www.website.com
http://www.website.com/
https://www.website.com/
ftp://www.website.com/
ftps://www.website.com/
http://www.website.com/some/path
# Valid URIs
www.myapp.com
http://www.myapp.com
http://www.myapp.com/
https://www.myapp.com/
ftp://www.myapp.com/
ftps://www.myapp.com/
http://www.myapp.com/some/path
How can I make that (maybe by using just Ruby on Rails)?
Note: I am validating URIs in order to allow users to set custom redirects and I am aware of vulnerabilities. I plan to run validations in a method stated in my application_controller.rb.
require 'uri'
uri = URI.parse 'http://www.website.com/some/path'
isOK = case uri.host
when 'www.website.com' then true
else false
end
#⇒ true
Hope it helps.
Currently Addressable is my preferred choice for working with URIs:
require 'addressable/uri'
Addressable::URI.parse('http://www.myapp.com/some/path').host == 'www.myapp.com'

MultiJson::DecodeError unexpected token at {"email":"foo#bar.com"}

I'm developing a new Ruby on Rails 3.2 application.
This application will receive a periodic json callback with statistics.
The callback i receive is not entirely valid. The json rules are separated by newlines.
The callback POSTs have a content-type header of application/json, and contain exactly one JSON string per line, with each line representing one event. Please note that currently the POST headers define this post as application/json, though it’s not; each line is a valid JSON string, but the overall POST body is not. For example:
This is a example of the callback:
{"email":"foo#bar.com","timestamp":1322000095,"unique_arg":"my unique arg","event":"delivered"}
{"email":"foo#bar.com","timestamp":1322000097,"unique_arg":"my unique arg","event":"click"}
{"email":"foo#bar.com","timestamp":1322000096,"unique_arg":"my unique arg","event":"open"}
When i receive this callback my Rails application crashes with a "MultiJson::DecodeError"
743: unexpected token at '{"email":"foo#bar.com","timestamp":1322000096,"unique_arg":"my unique arg","event":"open"}'
I think the application detects the application/json header and try automatic to parse it.
How can i convert this to a valid JSON object, so i can use this in my controller?
Thanks.
Put
gem 'yajl-ruby' in Gemfile and
require 'yajl/json_gem' config/application.rb
In gem file declare
gem 'yajl-ruby'
It is used to Parse and encode multiple JSON objects to and from streams or strings continuous.
And require 'yajl/json_gem' in application.rb
Put Elements in Brackets:
[{"email":"foo#bar.com","timestamp":1322000095,"unique_arg":"my unique arg","event":"delivered"},
{"email":"foo#bar.com","timestamp":1322000097,"unique_arg":"my unique arg","event":"click"},
{"email":"foo#bar.com","timestamp":1322000096,"unique_arg":"my unique arg","event":"open"}]`
Unable to reproduce your problem by copy-and-pasting the error message token using both ActiveSupport::JSON.decode and MultiJson.decode in a Rails shell. Rails 3.2.1
Any other clues?
This issue is likely due to response body encoded in ISO-8859-1 instead of UTF-8. Possible fix on client side is be convert it back to UTF-8 using ruby 'iconv' encoding methods.

Get a json object from the url while using facebook graph api in ruby on rails

how to get the JSON object through URL in my ruby on rails code:
url = "https://graph.facebook.com/me/friends?access_token=XXX"
I am not able to get good tutorial for JSON + Ruby on rails.
Can someone help me out thanks.
require 'open-uri'
require 'json'
json_object = JSON.parse(open("https://graph.facebook.com/me/friends?access_token=XXX").read)
This is the simplest way, though it may not be the fastest.
Edit: If the URI contains special characters in its parameter string, it has to be escaped/encoded with URI.escape first.

Resources