HTTP2 frame flow_control_error on AWS CloudFront websites
Hi,
When requesting a CloudFront-hosted and TLS-encrypted website, HTTPX prints a flow_control_error
frame error message and the thread is blocked forever.
% HTTPX_DEBUG=2 pry -rhttpx
[1] pry(main)> Timeout.timeout(60) { HTTPX.get("https://www.rust-lang.org") }
resolver: query A for www.rust-lang.org
resolver: server: udp://10.0.1.1:53...
resolver: WRITE: 35 bytes...
resolver: READ: 281 bytes...
resolver: query A for dq70m0d2ic23x.cloudfront.net
resolver: WRITE: 46 bytes...
resolver: READ: 110 bytes...
resolver: answer www.rust-lang.org: [#<IPAddr: IPv4:99.84.151.54/255.255.255.255>, #<IPAddr: IPv4:99.84.151.125/255.255.255.255>, #<IPAddr: IPv4:99.84.151.109/255.255.255.255>, #<IPAddr: IPv4:99.84.151.80/255.255.255.255>]
Connected to www.rust-lang.org (99.84.151.80) port 443 (#11)
99.84.151.80:443 connected -> negotiated
SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
ALPN, server accepted to use h2
Server certificate:
subject: /CN=www.rust-lang.org
start date: 2019-11-08 00:00:00 UTC
start date: 2020-12-08 12:00:00 UTC
issuer: /C=US/O=Amazon/OU=Server CA 1B/CN=Amazon
0: frame was sent!
0: {:type=>:settings, :stream=>0, :payload=>[[:settings_enable_push, 0], [:settings_max_concurrent_streams, 100]]}
READ: 40 bytes...
0: frame was received!
0: {:length=>18, :type=>:settings, :flags=>[], :stream=>0, :payload=>[[:settings_max_concurrent_streams, 128], [:settings_initial_window_size, 65536], [:settings_max_frame_size, 16777215]]}
0: frame was sent!
0: {:type=>:settings, :stream=>0, :payload=>[], :flags=>[:ack]}
0: frame was received!
0: {:length=>4, :type=>:window_update, :flags=>[], :stream=>0, :increment=>2147418112}
: frame was sent!
: {:type=>:goaway, :last_stream=>0, :error=>:flow_control_error, :payload=>nil}
: frame was sent!
: {:type=>:goaway, :last_stream=>0, :error=>:no_error, :payload=>nil}
Timeout::Error: execution expired
from /home/…/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/httpx-0.6.0/lib/httpx/selector.rb:88:in `select'
Backtrace:
Exception: Timeout::Error: execution expired
--
0: /home/…/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/httpx-0.6.0/lib/httpx/selector.rb:88:in `select'
1: /home/…/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/httpx-0.6.0/lib/httpx/selector.rb:88:in `select'
2: /home/…/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/httpx-0.6.0/lib/httpx/pool.rb:30:in `block in next_tick'
3: /home/…/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/httpx-0.6.0/lib/httpx/pool.rb:29:in `catch'
4: /home/…/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/httpx-0.6.0/lib/httpx/pool.rb:29:in `next_tick'
I came across this when trying to request my own CloudFront-hosted blog, which resulted in the same behavior.
Edited by Mikkel Kroman