Change non ascii character in an HTTP request

633 views Asked by At

i have to make an http get call to an external service. By sending an address, the latitude and longitude coordinates are returned. The problem is that if the address is Russian or French I have errors like:

URI must be ascii only "http://nominatim.openstreetmap.org/?format=json&addressdetails=1&q={Barrage de G\u00E9nissiat, Rue Marcel Paul, Injoux, Franclens, Nantua, Ain, Auvergne-Rh\u00F4ne-Alpes, Francia metropolitana, 74910, Francia}&format=json" 

My code is:

url = "http://nominatim.openstreetmap.org/?format=json&addressdetails=1&q={"+ address_search +"}&format=json";
response = Faraday.get url

the variable address_search is:

 Barrage de Génissiat, Rue Marcel Paul, Injoux, Franclens, Nantua, Ain, Auvergne-Rhône-Alpes, Francia metropolitana, 74910, Francia

Faraday is just a grm in rails to make an HTTP request, nothing strange. I have to manipulate the URL. Do you have any suggestion?

EDIT:

  print Rails.logger.info "body " + response.body
    print Rails.logger.info response.status
    print Rails.logger.info response.env.url

This is the output

body []
200
https://nominatim.openstreetmap.org/?addressdetails=1&format=json&q=Barrage+de+G%C3%A9nissiat%2C+Rue+Marcel+Paul%2C+Injoux%2C+Franclens%2C+Nantua%2C+Ain%2C+Auvergne-Rh%C3%B4ne-Alpes%2C+Francia+metropolitana%2C+74910%2C+Francia
  Rendering homes/index.html.erb within layouts/application
2

There are 2 answers

13
Yakov On

The query should be encoded, you can do it manually:

query = 'Barrage de Génissiat, Rue Marcel Paul, Injoux, Franclens, Nantua, Ain, Auvergne-Rhône-Alpes, Francia metropolitana, 74910, Francia'
address_search = URI.escape(query)
url = "https://nominatim.openstreetmap.org/?format=json&addressdetails=1&q=#{address_search}&format=json"
response = Faraday.get(url)

Or leave the job for Faraday:

query = 'Barrage de Génissiat, Rue Marcel Paul, Injoux, Franclens, Nantua, Ain, Auvergne-Rhône-Alpes, Francia metropolitana, 74910, Francia'
connection = Faraday.new('https://nominatim.openstreetmap.org')
response = connection.get do |request|
  request.params = { format: 'json', addressdetails: 1, q: query }
end

Here is the response:

=> #<Faraday::Response:0x0000556afc452060
 @env=
  #<struct Faraday::Env
   method=:get,
   body=
    "[{\"place_id\":104161692,\"licence\":\"Data \xC2\xA9 OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright\",\"osm_type\":\"way\",\"osm_id\":80667335,\"boundingbox\":[\"46.0516289\",\"46.0531641\",\"5.8112371\",\"5.81
4139\"],\"lat\":\"46.0523765\",\"lon\":\"5.812744291298651\",\"display_name\":\"Barrage de G\xC3\xA9nissiat, Rue Marcel Paul, Injoux, Franclens, Nantua, Ain, Auvergne-Rh\xC3\xB4ne-Alpes, France m\xC3\xA9tropolitaine, 74910, France\"
,\"class\":\"tourism\",\"type\":\"attraction\",\"importance\":1.7983764706069638,\"icon\":\"https://nominatim.openstreetmap.org/images/mapicons/poi_point_of_interest.p.20.png\",\"address\":{\"tourism\":\"Barrage de G\xC3\xA9nissiat\
",\"road\":\"Rue Marcel Paul\",\"suburb\":\"Injoux\",\"village\":\"Franclens\",\"municipality\":\"Nantua\",\"county\":\"Ain\",\"state\":\"Auvergne-Rh\xC3\xB4ne-Alpes\",\"country\":\"France\",\"postcode\":\"74910\",\"country_code\":\
"fr\"}}]",
   url=
    #<URI::HTTPS https://nominatim.openstreetmap.org/?addressdetails=1&format=json&q=Barrage+de+G%C3%A9nissiat%2C+Rue+Marcel+Paul%2C+Injoux%2C+Franclens%2C+Nantua%2C+Ain%2C+Auvergne-Rh%C3%B4ne-Alpes%2C+Francia+metropolitana%2C+74910%2C+Francia>,
   request=#<struct Faraday::RequestOptions params_encoder=nil, proxy=nil, bind=nil, timeout=nil, open_timeout=nil, write_timeout=nil, boundary=nil, oauth=nil, context=nil>,
   request_headers={"User-Agent"=>"Faraday v0.17.3"},
   ssl=
    #<struct Faraday::SSLOptions
     verify=true,
     ca_file=nil,
     ca_path=nil,
     verify_mode=nil,
     cert_store=nil,
     client_cert=nil,
     client_key=nil,
     certificate=nil,
     private_key=nil,
     verify_depth=nil,
     version=nil,
     min_version=nil,
     max_version=nil>,
   parallel_manager=nil,
   params=nil,
   response=#<Faraday::Response:0x0000556afc452060 ...>,
   response_headers=
    {"server"=>"nginx",
     "date"=>"Thu, 15 Oct 2020 19:42:53 GMT",
     "content-type"=>"application/json; charset=UTF-8",
     "transfer-encoding"=>"chunked",
     "connection"=>"close",
     "access-control-allow-origin"=>"*",
     "access-control-allow-methods"=>"OPTIONS,GET"},
   status=200,
   reason_phrase="OK">,
 @on_complete_callbacks=[]>

Make sure that you use https schema, otherwise, you'll get a response with a redirect.

3
Vito On

I use this code:

  query = "Barrage de Génissiat, Rue Marcel Paul, Injoux, Franclens, Nantua, Ain, Auvergne-Rhône-Alpes, Francia metropolitana, 74910, Francia"
  connection = Faraday.new('https://nominatim.openstreetmap.org')


    response = connection.get do |request|
      request.params = { format: 'json', addressdetails: 1, q: query }
    end


    print Rails.logger.info response.body

And I receive []..