socketry / async-http

MIT License
298 stars 45 forks source link

Async::HTTP::Protocol::HTTP2::Client failed due to Protocol::HTTP2::GoawayError #23

Closed picatz closed 5 years ago

picatz commented 5 years ago

I came across some weird behavior today that I don't quite know how to manage.

require 'async'
require 'async/http/internet'

Async do
  internet = Async::HTTP::Internet.new

  url = 'https://www.hashicorp.com/jobs'

  resp = internet.get(url)

  # then I'd manage the resp
ensure
  internet&.close
end

But, I'm getting the following error:

$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]
$ ruby script.rb
 0.88s: <Async::Task:0x3fdc7c8e95fc h2 reading data for Async::HTTP::Protocol::HTTP2::Client failed>
      |   Protocol::HTTP2::GoawayError: 
      |   → /Users/picat/.rvm/gems/ruby-2.6.3/gems/protocol-http2-0.3.0/lib/protocol/http2/connection.rb:158 in `receive_goaway'
      |     /Users/picat/.rvm/gems/ruby-2.6.3/gems/protocol-http2-0.3.0/lib/protocol/http2/goaway_frame.rb:56 in `apply'
      |     /Users/picat/.rvm/gems/ruby-2.6.3/gems/protocol-http2-0.3.0/lib/protocol/http2/connection.rb:117 in `read_frame'
      |     /Users/picat/.rvm/gems/ruby-2.6.3/gems/async-http-0.42.0/lib/async/http/protocol/http2/connection.rb:71 in `block in read_in_background'
      |     /Users/picat/.rvm/gems/ruby-2.6.3/gems/async-1.17.1/lib/async/task.rb:204 in `block in make_fiber'

Working Version

The following code using net/http doesn't experience the same issue, but I'd rather use async/http/internet if possible:

require 'net/http'
require 'uri'

uri = URI.parse("https://www.hashicorp.com/jobs")
response = Net::HTTP.get_response(uri)

puts response
$ ruby other_script.rb
#<Net::HTTPOK:0x00007f9a2811da18>
ioquatix commented 5 years ago

It's probably something wrong with protocol-http2 and the remote server is not happy. The best way to debug it is to print out individual frames and see where it goes wrong.

ioquatix commented 5 years ago

I checked and the issue is the new setting in the h2 websocket rfc. I've added this as a spec... I'm not sure what the solution is yet. Because I don't know if the remote server should ignore settings it doesn't understand. Is that RFC compliant?

ioquatix commented 5 years ago

So, from what I can see, Hashicorp's HTTP/2 server is in violation of the RFC:

An endpoint that receives a SETTINGS frame with any unknown or unsupported identifier MUST ignore that setting.

Here is the response:

% nghttp -v https://www.hashicorp.com/jobs
[  0.409] recv (stream_id=13) :status: 200
[  0.410] recv (stream_id=13) content-type: text/html; charset=utf-8
[  0.410] recv (stream_id=13) date: Mon, 10 Jun 2019 09:04:18 GMT
[  0.410] recv (stream_id=13) etag: W/"3681a-z4jCsdHR4CgC6O3MC2v4eWD63DU"
[  0.410] recv (stream_id=13) server: Netlify
[  0.410] recv (stream_id=13) strict-transport-security: max-age=15552000; includeSubDomains
[  0.410] recv (stream_id=13) via: 1.1 vegur
[  0.410] recv (stream_id=13) x-content-type-options: nosniff
[  0.410] recv (stream_id=13) x-dns-prefetch-control: off
[  0.410] recv (stream_id=13) x-download-options: noopen
[  0.410] recv (stream_id=13) x-frame-options: SAMEORIGIN
[  0.410] recv (stream_id=13) x-xss-protection: 1; mode=block
[  0.410] recv (stream_id=13) content-encoding: gzip
[  0.410] recv (stream_id=13) age: 1
[  0.410] recv (stream_id=13) vary: Accept-Encoding
[  0.410] recv (stream_id=13) x-nf-request-id: 488c9482-57ad-4e90-aa63-c9bb980799f4-19530674
[  0.410] recv HEADERS frame <length=305, flags=0x04, stream_id=13>

So, I don't know what netlify is, but I guess we can try to reach out to them.

ioquatix commented 5 years ago

I added a spec to track whether the issue is fixed: https://github.com/socketry/async-http/blob/de02ee6eb4febd753989d0049ec37098821d3310/spec/async/http/internet_spec.rb#L51-L55

picatz commented 5 years ago

Netlify is a relatively popular service to deploy static sites. I've tried contacting support via their website -- but I'm worried that won't fix the issue, or at least not very quickly.

fool commented 5 years ago

I work for Netlify's support and I have brought it up with our Platform team. We'll keep working with @picatz via the helpdesk thread, but I cannot promise a fast resolution.

One presumes he will follow up here as we come to some conclusion :)

picatz commented 5 years ago

Small update: Netlify recognizes that their server is violating the RFC, but it won't be a quick fix.

ioquatix commented 5 years ago

Issue is fixed by avoiding sending this setting to server. Even if it's in violation of the spec, it wasn't necessary for us to send it, so I've just removed it, and it works.