Hang when using Spotify API

I've tested and I can complete these requests just fine with other HTTP2 clients like async-http. You need to get a token to complete any request, unfortunately.

Script:

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

url = 'https://api.spotify.com/v1/search?query=metallica&type=artist'
headers = {'accept' => 'application/json', 'content-type' => 'application/json', 'authorization' => 'Bearer {TOKEN}'}

Async do
  internet = Async::HTTP::Internet.new
  puts internet.get(url, headers.to_a).read
end

puts HTTPX.get(url, headers: headers).to_s

HTTPX debug:

$ HTTPX_DEBUG=2 ruby test.rb
resolver: query A for api.spotify.com
resolver: server: udp://192.168.0.5:53...
resolver: WRITE: 33 bytes...
resolver: READ: 77 bytes...
resolver: query A for wg.spotify.com
resolver: WRITE: 32 bytes...
resolver: READ: 48 bytes...
resolver: answer api.spotify.com: [#<IPAddr: IPv4:35.186.224.53/255.255.255.255>]
Connected to api.spotify.com (35.186.224.53) port 443 (#12)
35.186.224.53:443 connected -> negotiated

SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
ALPN, server accepted to use h2
Server certificate:
 subject: /C=SE/L=Stockholm/O=Spotify AB/CN=*.spotify.com
 start date: 2017-05-16 00:00:00 UTC
 expire date: 2020-07-29 12:00:00 UTC
 issuer: /C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
 SSL certificate verify ok.
0: frame was sent!
0: {:type=>:settings, :stream=>0, :payload=>[[:settings_enable_push, 0], [:settings_max_concurrent_streams, 100]]}
WRITE: 45 bytes...
READ: 40 bytes...
0: frame was received!
0: {:length=>18, :type=>:settings, :flags=>[], :stream=>0, :payload=>[[:settings_max_concurrent_streams, 100], [:settings_initial_window_size, 1048576], [:settings_max_header_list_size, 16384]]}
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=>983041}
WRITE: 9 bytes...
READ: 9 bytes...
0: frame was received!
0: {:length=>0, :type=>:settings, :flags=>[:ack], :stream=>0, :payload=>[]}
1: -> HEADER: :scheme: https
-> HEADER: :method: GET
-> HEADER: :path: /v1/search?query=metallica&type=artist
-> HEADER: :authority: api.spotify.com
-> HEADER: accept: application/json
-> HEADER: content-type: application/json
-> HEADER: authorization: Bearer {TOKEN}
-> HEADER: user-agent: httpx.rb/0.7.0
1: frame was sent!
1: {:type=>:headers, :flags=>[:end_headers, :end_stream], :payload=>{":scheme"=>"https", ":method"=>"GET", ":path"=>"/v1/search?query=metallica&type=artist", ":authority"=>"api.spotify.com", "accept"=>"application/json", "content-type"=>"application/json", "authorization"=>"Bearer {TOKEN}", "user-agent"=>"httpx.rb/0.7.0"}, :stream=>1}
1: waiting for response...
WRITE: 217 bytes...
READ: 349 bytes...
1: frame was received!
1: {:length=>340, :type=>:headers, :flags=>[:end_headers], :stream=>1, :payload=>"\x88_\x96\x1Du\xD0b\r&=LtA\xEA\xFBP\x93\x8E\xC4\x150Z\x99V{X\x8F\xAE\xD8\xE81>\x94\xA4~V\x1C\xC5\x81\xD1\x00\x1F@\x89\xF2\xB5\x87\x8C\xE9B\xC9\x1C\xDF\x8D\xA8\xE6\xAAB\xF9\xFAR\xA3\xCAz(?\x8FT\x01*@\x94\x19\bT!b\x1E\xA4\xD8z\x16\x1D\x14\x1F\xC2\xD3\x94r\x16\xC4\x7F\xD5\x84\x84-i\xFAR\x1A\xEB[]\x03L\xA7\xB2\x9F\xA5!\xB53\x9E\xC3{\x1ALz\xBE\x94\xBCz\x92Z\x92\xB6\xFFU\x97\xE9MV\x1AcU\xF4\xA6\xD2\xA6\xCFKC*Kg\xD2\x9B\xAB:M/\xA5\xA1\xAE\xB5\xB8\x96\xC4\x18\xF5})\xF8\xB5\xEA\x0Fl\x8Bo\xB0d*\xD7\x8FRK\xE5?@\x94\x19\bT!b\x1E\xA4\xD8z\x16\x1D\x14\x1F\xC2\xD4\x953\x9ED\x7F\xA2\xC5\x83\x7F\xD2\x9A\xF5n\xDF\xF4\xA6\xAD{\xF2j\xD3\xBB\xE9M|7\xFD)\x7F\x06|\e\xF0})\xAE\x1D\xF7\xB1\xFF@\x96\x19\bT!b\x1E\xA4\xD8z\x16\x1D\x14\x1F\xC2\xC4\xB0\xB2\x16\xA4\x98t#\x83M\x96\x97@\x8F\x19\bT!b\x1E\xA4\xD8z\x16\xA4~V\x1C\xC5\x85p\r<\x00\x7F\\\x83i\xB7\x9B\x00\x83\x90i/\x96\xDF=\xBFJ\x05\xC5!\xAE\xC5\x04\x01\x01@\xBDp\x0F\\dJb\xD1\xBF|\x87\n\xE1Rc\x9Ej\v@\x85\x1D\tY\x1D\xC9\x84%\x05\x1D\x9F"}
1:<- HEADER: :status: 200
<- HEADER: content-type: application/json; charset=utf-8
<- HEADER: cache-control: public, max-age=7200
<- HEADER: x-robots-tag: noindex, nofollow
<- HEADER: access-control-allow-origin: *
<- HEADER: access-control-allow-headers: Accept, App-Platform, Authorization, Content-Type, Origin, Retry-After, Spotify-App-Version, X-Cloud-Trace-Context
<- HEADER: access-control-allow-methods: GET, POST, OPTIONS, PUT, DELETE, PATCH
<- HEADER: access-control-allow-credentials: true
<- HEADER: access-control-max-age: 604800
<- HEADER: content-length: 4585
<- HEADER: date: Thu, 16 Apr 2020 18:08:32 GMT
<- HEADER: via: 1.1 google
<- HEADER: alt-svc: clear
READ: 1396 bytes...
READ: 1396 bytes...
READ: 835 bytes...
1: frame was received!
1: {:length=>3618, :type=>:data, :flags=>[], :stream=>1, :payload=>3618}
1: <- DATA: 3618 bytes...
1: <- "{\n  \"artists\" : {\n    \"href\" : \"https://api.spotify.com/v1/search?query=metallica&type=artist&offset=0&limit=20\",\n    \"items\" : [ {\n      \"external_urls\" : {\n        \"spotify\" : \"https://open.spotify.com/artist/2ye2Wgw4gimLv2eAKyk1NB\"\n      },\n      \"followers\" : {\n        \"href\" : null,\n        \"total\" : 13704033\n      },\n      \"genres\" : [ \"alternative metal\", \"hard rock\", \"metal\", \"old school thrash\", \"rock\", \"speed metal\", \"thrash metal\" ],\n      \"href\" : \"https://api.spotify.com/v1/artists/2ye2Wgw4gimLv2eAKyk1NB\",\n      \"id\" : \"2ye2Wgw4gimLv2eAKyk1NB\",\n      \"images\" : [ {\n        \"height\" : 640,\n        \"url\" : \"https://i.scdn.co/image/5a06711d7fc48d5e0e3f9a3274ffed3f0af1bd91\",\n        \"width\" : 640\n      }, {\n        \"height\" : 320,\n        \"url\" : \"https://i.scdn.co/image/0c22030833eb55c14013bb36eb6a429328868c29\",\n        \"width\" : 320\n      }, {\n        \"height\" : 160,\n        \"url\" : \"https://i.scdn.co/image/c1fb4d88de092b5617e649bd4c406b5cab7d3ddd\",\n        \"width\" : 160\n      } ],\n      \"name\" : \"Metallica\",\n      \"popularity\" : 83,\n      \"type\" : \"artist\",\n      \"uri\" : \"spotify:artist:2ye2Wgw4gimLv2eAKyk1NB\"\n    }, {\n      \"external_urls\" : {\n        \"spotify\" : \"https://open.spotify.com/artist/7Cb4VdtakIlAvklqegssGB\"\n      },\n      \"followers\" : {\n        \"href\" : null,\n        \"total\" : 15322\n      },\n      \"genres\" : [ ],\n      \"href\" : \"https://api.spotify.com/v1/artists/7Cb4VdtakIlAvklqegssGB\",\n      \"id\" : \"7Cb4VdtakIlAvklqegssGB\",\n      \"images\" : [ {\n        \"height\" : 640,\n        \"url\" : \"https://i.scdn.co/image/ab67616d0000b2730baa189d8d5e6ca03a5adfed\",\n        \"width\" : 640\n      }, {\n        \"height\" : 300,\n        \"url\" : \"https://i.scdn.co/image/ab67616d00001e020baa189d8d5e6ca03a5adfed\",\n        \"width\" : 300\n      }, {\n        \"height\" : 64,\n        \"url\" : \"https://i.scdn.co/image/ab67616d000048510baa189d8d5e6ca03a5adfed\",\n        \"width\" : 64\n      } ],\n      \"name\" : \"Spartan Metallican Visionary\",\n      \"popularity\" : 29,\n      \"type\" : \"artist\",\n      \"uri\" : \"spotify:artist:7Cb4VdtakIlAvklqegssGB\"\n    }, {\n      \"external_urls\" : {\n        \"spotify\" : \"https://open.spotify.com/artist/2ouOJPakXli9ePEiCAHNqw\"\n      },\n      \"followers\" : {\n        \"href\" : null,\n        \"total\" : 11\n      },\n      \"genres\" : [ ],\n      \"href\" : \"https://api.spotify.com/v1/artists/2ouOJPakXli9ePEiCAHNqw\",\n      \"id\" : \"2ouOJPakXli9ePEiCAHNqw\",\n      \"images\" : [ {\n        \"height\" : 640,\n        \"url\" : \"https://i.scdn.co/image/6a698afb1465ad279389e3fb0a5f80b79bc486d9\",\n        \"width\" : 640\n      }, {\n        \"height\" : 320,\n        \"url\" : \"https://i.scdn.co/image/7d224e966298a809ccef8de68af099ecf8629226\",\n        \"width\" : 320\n      }, {\n        \"height\" : 160,\n        \"url\" : \"https://i.scdn.co/image/e5de385f2791e549c320ceed9cbb1a1e8cdcac5c\",\n        \"width\" : 160\n      } ],\n      \"name\" : \"Metallicash\",\n      \"popularity\" : 0,\n      \"type\" : \"artist\",\n      \"uri\" : \"spotify:artist:2ouOJPakXli9ePEiCAHNqw\"\n    }, {\n      \"external_urls\" : {\n        \"spotify\" : \"https://open.spotify.com/artist/7I2EiRxYEZigLPzgu43HWq\"\n      },\n      \"followers\" : {\n        \"href\" : null,\n        \"total\" : 160\n      },\n      \"genres\" : [ ],\n      \"href\" : \"https://api.spotify.com/v1/artists/7I2EiRxYEZigLPzgu43HWq\",\n      \"id\" : \"7I2EiRxYEZigLPzgu43HWq\",\n      \"images\" : [ ],\n      \"name\" : \"Metallica: Burton\",\n      \"popularity\" : 0,\n      \"type\" : \"artist\",\n      \"uri\" : \"spotify:artist:7I2EiRxYEZigLPzgu43HWq\"\n    }, {\n      \"external_urls\" : {\n        \"spotify\" : \"https://open.spotify.com/artist/61OPB1XJSYA5JoAvWZUQ4Z\"\n      },\n      \"followers\" : {\n "
READ: 976 bytes...
1: frame was received!
1: {:length=>967, :type=>:data, :flags=>[], :stream=>1, :payload=>967}
1: <- DATA: 967 bytes...
1: <- "       \"href\" : null,\n        \"total\" : 468\n      },\n      \"genres\" : [ ],\n      \"href\" : \"https://api.spotify.com/v1/artists/61OPB1XJSYA5JoAvWZUQ4Z\",\n      \"id\" : \"61OPB1XJSYA5JoAvWZUQ4Z\",\n      \"images\" : [ ],\n      \"name\" : \"Metallica Tribute Band\",\n      \"popularity\" : 4,\n      \"type\" : \"artist\",\n      \"uri\" : \"spotify:artist:61OPB1XJSYA5JoAvWZUQ4Z\"\n    }, {\n      \"external_urls\" : {\n        \"spotify\" : \"https://open.spotify.com/artist/7xXiZGPcqDEijirJubILoZ\"\n      },\n      \"followers\" : {\n        \"href\" : null,\n        \"total\" : 314\n      },\n      \"genres\" : [ ],\n      \"href\" : \"https://api.spotify.com/v1/artists/7xXiZGPcqDEijirJubILoZ\",\n      \"id\" : \"7xXiZGPcqDEijirJubILoZ\",\n      \"images\" : [ ],\n      \"name\" : \"Made famous by Metallica\",\n      \"popularity\" : 2,\n      \"type\" : \"artist\",\n      \"uri\" : \"spotify:artist:7xXiZGPcqDEijirJubILoZ\"\n    } ],\n    \"limit\" : 20,\n    \"next\" : null,\n    \"offset\" : 0,\n    \"previous\" : null,\n    \"total\" : 10\n  }\n}"
READ: 9 bytes...
1: frame was received!
1: {:length=>0, :type=>:data, :flags=>[:end_stream], :stream=>1, :payload=>0}
1: <- DATA: 0 bytes...
1: <- ""
^C: frame was sent!
: {:type=>:goaway, :last_stream=>1, :error=>:no_error, :payload=>nil}
WRITE: 17 bytes...
35.186.224.53:443 negotiated -> closed

At this point, the script hangs and must be killed.

Edited by Stefan Wrobel