socketry / async-http

MIT License
298 stars 45 forks source link

HTTP/1 fails over HTTPS #84

Closed TimWillard closed 1 year ago

TimWillard commented 2 years ago

Running

Async do
  internet = Async::HTTP::Internet.new(protocol: Async::HTTP::Protocol::HTTP1)
  response = internet.call("GET", "https://google.com", [], nil)
end

raises

0.23s    error: Async::Task [oid=0x5474] [ec=0x5488] [pid=61464] [2021-09-23 13:42:09 -0400]
               |   EOFError: Could not read line!
               |   → /Users/timothywillard/.gem/ruby/2.7.3/gems/async-http-0.56.5/lib/async/http/protocol/http1/connection.rb:55 in `read_line'
               |     /Users/timothywillard/.gem/ruby/2.7.3/gems/protocol-http1-0.14.2/lib/protocol/http1/connection.rb:201 in `read_response'
               |     /Users/timothywillard/.gem/ruby/2.7.3/gems/async-http-0.56.5/lib/async/http/protocol/http1/response.rb:31 in `read'
               |     /Users/timothywillard/.gem/ruby/2.7.3/gems/async-http-0.56.5/lib/async/http/protocol/http1/client.rb:78 in `call'
               |     /Users/timothywillard/.gem/ruby/2.7.3/gems/protocol-http-0.22.5/lib/protocol/http/request.rb:53 in `call'
               |     /Users/timothywillard/.gem/ruby/2.7.3/gems/async-http-0.56.5/lib/async/http/client.rb:142 in `make_response'
               |     /Users/timothywillard/.gem/ruby/2.7.3/gems/async-http-0.56.5/lib/async/http/client.rb:105 in `call'
               |     /Users/timothywillard/.gem/ruby/2.7.3/gems/protocol-http-0.22.5/lib/protocol/http/middleware.rb:50 in `call'
               |     /Users/timothywillard/.gem/ruby/2.7.3/gems/protocol-http-0.22.5/lib/protocol/http/accept_encoding.rb:50 in `call'
               |     /Users/timothywillard/.gem/ruby/2.7.3/gems/async-http-0.56.5/lib/async/http/internet.rb:58 in `call'
               |     (irb):3 in `block in <main>'
               |     /Users/timothywillard/.gem/ruby/2.7.3/gems/async-1.30.1/lib/async/task.rb:260 in `block in make_fiber

If we change to just http it works:

Async do
  internet = Async::HTTP::Internet.new(protocol: Async::HTTP::Protocol::HTTP1)
  response = internet.call("GET", "http://google.com", [], nil)
end
ioquatix commented 1 year ago

That's because you are using TLS.

Check https://github.com/socketry/async-http/blob/main/lib/async/http/protocol/https.rb to see how to implement your own TLS wrapper that only advertises and supports HTTP/1.