Skip to content

Commit 38ec627

Browse files
authored
Add support for on_data, enabling streaming response body. (#41)
1 parent c1ff0ae commit 38ec627

File tree

6 files changed

+61
-15
lines changed

6 files changed

+61
-15
lines changed

.mailmap

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
Flavio Fernandes <flavio.fernandes6@gmail.com>
1+
Flavio Fernandes <flavio.fernandes6@gmail.com>
2+
Korbin Hoffman <k1@k1.io>

async-http-faraday.gemspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
77
spec.version = Async::HTTP::Faraday::VERSION
88

99
spec.summary = "Provides an adaptor between async-http and faraday."
10-
spec.authors = ["Samuel Williams", "Igor Sidorov", "Andreas Garnaes", "Genki Takiuchi", "Olle Jonsson", "Benoit Daloze", "Denis Talakevich", "Flavio Fernandes", "Jacob Frautschi"]
10+
spec.authors = ["Samuel Williams", "Igor Sidorov", "Andreas Garnaes", "Genki Takiuchi", "Olle Jonsson", "Benoit Daloze", "Denis Talakevich", "Flavio Fernandes", "Jacob Frautschi", "Korbin Hoffman"]
1111
spec.license = "MIT"
1212

1313
spec.cert_chain = ['release.cert']

lib/async/http/faraday/adapter.rb

+18-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# Copyright, 2023, by Genki Takiuchi.
99
# Copyright, 2023, by Flavio Fernandes.
1010
# Copyright, 2024, by Jacob Frautschi.
11+
# Copyright, 2024, by Korbin Hoffman.
1112

1213
require 'faraday'
1314
require 'faraday/adapter'
@@ -119,9 +120,23 @@ def call(env)
119120
request = ::Protocol::HTTP::Request.new(endpoint.scheme, endpoint.authority, method, endpoint.path, nil, headers, body)
120121

121122
with_timeout do
122-
response = client.call(request)
123-
124-
save_response(env, response.status, encoded_body(response), response.headers)
123+
if env.stream_response?
124+
response = env.stream_response do |&on_data|
125+
response = client.call(request)
126+
127+
response.each do |chunk|
128+
on_data.call(chunk)
129+
end
130+
131+
response
132+
end
133+
134+
save_response(env, response.status, nil, response.headers)
135+
else
136+
response = client.call(request)
137+
138+
save_response(env, response.status, encoded_body(response), response.headers)
139+
end
125140
end
126141
end
127142

lib/async/http/faraday/clients.rb

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
# frozen_string_literal: true
22

33
# Released under the MIT License.
4-
# Copyright, 2018-2024, by Samuel Williams.
5-
# Copyright, 2018, by Andreas Garnaes.
6-
# Copyright, 2019, by Denis Talakevich.
7-
# Copyright, 2019-2020, by Igor Sidorov.
8-
# Copyright, 2023, by Genki Takiuchi.
9-
# Copyright, 2023, by Flavio Fernandes.
10-
# Copyright, 2024, by Jacob Frautschi.
4+
# Copyright, 2024, by Samuel Williams.
115

126
require 'faraday'
137
require 'faraday/adapter'

license.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Copyright, 2020, by Benoit Daloze.
99
Copyright, 2023, by Genki Takiuchi.
1010
Copyright, 2023, by Flavio Fernandes.
1111
Copyright, 2024, by Jacob Frautschi.
12+
Copyright, 2024, by Korbin Hoffman.
1213

1314
Permission is hereby granted, free of charge, to any person obtaining a copy
1415
of this software and associated documentation files (the "Software"), to deal

test/async/http/faraday/adapter.rb

+38-3
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,14 @@ def get_response(url = bound_url, path = '/index', adapter_options: {})
128128

129129
expect(response.body).to be == 'text=Hello+World'
130130
end
131-
131+
132132
it "can use a ::Protocol::HTTP::Body::Readable body" do
133133
readable = ::Protocol::HTTP::Body::File.new(File.open(__FILE__, 'r'), 0...128)
134-
134+
135135
response = Faraday.new do |builder|
136136
builder.adapter :async_http
137137
end.post(bound_url, readable)
138-
138+
139139
expect(response.body).to be == File.read(__FILE__, 128)
140140
end
141141
end
@@ -155,6 +155,41 @@ def get_response(url = bound_url, path = '/index', adapter_options: {})
155155
expect(config_block_invoked).to be == true
156156
end
157157
end
158+
159+
with "a streaming response" do
160+
let(:app) do
161+
Protocol::HTTP::Middleware.for do |request|
162+
body = ::Async::HTTP::Body::Writable.new
163+
164+
Async do
165+
3.times do |i|
166+
body.write("chunk#{i}")
167+
end
168+
ensure
169+
body.close
170+
end
171+
172+
Protocol::HTTP::Response[200, {}, body]
173+
end
174+
end
175+
176+
it "can stream response" do
177+
client = Faraday.new do |builder|
178+
builder.adapter :async_http
179+
end
180+
181+
chunks = []
182+
183+
response = client.get(bound_url) do |request|
184+
request.options.on_data = proc do |chunk|
185+
chunks << chunk
186+
end
187+
end
188+
189+
expect(response.body).to be_nil
190+
expect(chunks).to be == ["chunk0", "chunk1", "chunk2"]
191+
end
192+
end
158193
end
159194

160195
with "a remote http server" do

0 commit comments

Comments
 (0)