Errno::EADDRNOTAVAIL when you hit api from Rails on Docker

Asked 2 years ago, Updated 2 years ago, 68 views

  • I want to get a response to book information by tapping Google books api from Rails' Book model
web_1|Errno::EADDRNOTAVAIL (Failed to open TCP connection to:80 (Address not available-connect(2) for nil port80):
web_1|   
web_1 | app/models/book.rb:24:in `search'
web_1 | app/controllers/books_controller.rb:3:in`search'

Tap the API using the keywords (book name, author, etc.) sent from the form.

class BooksController <ApplicationController
  def search
    @results=Book.search(params[:book_search][:search_key_word])
  end
end

Since it contains Japanese, it is encoded using the url_encode method.

class Book <ApplicationRecord
  class<<self
    def search(key_word)
      api_endpoint=ERB::Util.url_encode("https://www.googleapis.com/books/v1/volumes?q=#{key_word}&maxResults=20")
      response=Net::HTTP.get(URI.parse(api_endpoint))#This is where the above error occurs.
      JSON.parse (response)
    end
  end
end

Curl for the same endpoint naturally returns a proper response.

Does using docker have anything to do with it?
Based on alpine linux.
https://hub.docker.com/layers/ruby/library/ruby/2.6.6-alpine/images/sha256-95d5b6bf7084a6a0f04b48a7fc1c533ccb15e1550c670ff589ef56e620f40286?context=explore

p>
  • docker 2.3.0.4
  • docker-compose 3.8
  • rails container base image ruby:2.6.6-alpine
  • ruby 2.6.6
  • rails 6.0.3.2

I would appreciate it if you could let me know if there is anything you know.
Thank you for your cooperation.

ruby-on-rails ruby docker google-api

2022-09-30 10:53

2 Answers

ERB::Util.url_encode may not be required.

 api_endpoint=ERB::Util.url_encode("https://www.googleapis.com/books/v1/volumes?q=#{key_word}&maxResults=20")

Here

api_endpoint="https://www.googleapis.com/books/v1/volumes?q=#{key_word}&maxResults=20"

Why don't you change it like this?

[Additional]

If the key_word is an untrusted value, it is safer to encode only the key_word and use it as part of the URL instead of encoding (escaping) the entire URL.
You can use URI.encode_www_form_component.

Example:

encoded=URI.encode_www_form_component(key_word)
uri="https://www.googleapis.com/books/v1/volumes?q=#{encoded}&maxResults=20"


2022-09-30 10:53

Resolved.

The cause is

ERB::Util.url_encode("https://www.googleapis.com/books/v1/volumes?q=#{key_word}&maxResults=20")

When I passed the string that came back when I encoded this part to URI.parse, it returned URI::Generic.Both uri's host and scheme are nil, so it seems that it was not retrieved correctly.
I passed it directly to Net::HTTP.get, so I got a title-like error.

URI.encode is deprecated, so I wanted to encode it with another method.
Ultimately, URI.parse of a string encoded using WEBrick::HTTPUtils.#escape returned an instance of URI::HTTP, and the scheme was set correctly.

Thank you.

  • Reference
def search(key_word)
uri=URI.parse(WEBrick::HTTPUtils.escape("https://www.googleapis.com/books/v1/volumes?q=#{key_word}&maxResults=20")))
response=Net::HTTP.get_response(uri)
JSON.parse (response.body)
end


2022-09-30 10:53

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.