Skip to content

Commit ef5d49d

Browse files
committed
Modernize gem.
1 parent f95fd5b commit ef5d49d

19 files changed

+166
-36
lines changed

examples/streaming/bidirectional.rb

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/usr/bin/env ruby
22
# frozen_string_literal: true
33

4+
# Released under the MIT License.
5+
# Copyright, 2024, by Samuel Williams.
6+
47
require 'async'
58
require 'async/http/client'
69
require 'async/http/server'

examples/streaming/gems.rb

+4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2024, by Samuel Williams.
5+
26
source "https://rubygems.org"
37

48
gem "async"

examples/streaming/unidirectional.rb

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/usr/bin/env ruby
22
# frozen_string_literal: true
33

4+
# Released under the MIT License.
5+
# Copyright, 2024, by Samuel Williams.
6+
47
require 'async'
58
require 'async/http/client'
69
require 'async/http/server'

fixtures/protocol/http/body/a_readable_body.rb

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
1+
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2024, by Samuel Williams.
5+
16
module Protocol
27
module HTTP
38
module Body
49
AReadableBody = Sus::Shared("a readable body") do
5-
with "#close" do
6-
it "should close the body" do
10+
with "#read" do
11+
it "after closing, returns nil" do
712
body.close
13+
814
expect(body.read).to be_nil
915
end
1016
end
17+
18+
with "empty?" do
19+
it "returns true after closing" do
20+
body.close
21+
22+
expect(body).to be(:empty?)
23+
end
24+
end
1125
end
1226
end
1327
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2024, by Samuel Williams.
5+
6+
module Protocol
7+
module HTTP
8+
module Body
9+
AWritableBody = Sus::Shared("a readable body") do
10+
with "#read" do
11+
it "after closing the write end, returns all chunks" do
12+
body.write("Hello ")
13+
body.write("World!")
14+
body.close_write
15+
16+
expect(body.read).to be == "Hello "
17+
expect(body.read).to be == "World!"
18+
expect(body.read).to be_nil
19+
end
20+
end
21+
22+
with "empty?" do
23+
it "returns false before writing" do
24+
expect(body).not.to be(:empty?)
25+
end
26+
27+
it "returns true after all chunks are consumed" do
28+
body.write("Hello")
29+
body.close_write
30+
31+
expect(body).not.to be(:empty?)
32+
expect(body.read).to be == "Hello"
33+
expect(body.read).to be_nil
34+
35+
expect(body).to be(:empty?)
36+
end
37+
end
38+
end
39+
end
40+
end
41+
end

lib/protocol/http/body/buffered.rb

+25-3
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,18 @@ def initialize(chunks = [], length = nil)
5252

5353
attr :chunks
5454

55+
def finish
56+
self
57+
end
58+
5559
def close(error = nil)
56-
@chunks = []
60+
@index = @chunks.length
61+
end
62+
63+
def clear
64+
@chunks.clear
65+
@length = 0
66+
@index = 0
5767
end
5868

5969
def length
@@ -70,6 +80,8 @@ def ready?
7080
end
7181

7282
def read
83+
return nil unless @chunks
84+
7385
if chunk = @chunks[@index]
7486
@index += 1
7587

@@ -81,18 +93,28 @@ def write(chunk)
8193
@chunks << chunk
8294
end
8395

96+
def close_write(error)
97+
# Nothing to do.
98+
end
99+
84100
def rewindable?
85-
true
101+
@chunks != nil
86102
end
87103

88104
def rewind
105+
return false unless @chunks
106+
89107
@index = 0
90108

91109
return true
92110
end
93111

94112
def inspect
95-
"\#<#{self.class} #{@chunks.size} chunks, #{self.length} bytes>"
113+
if @chunks
114+
"\#<#{self.class} #{@chunks.size} chunks, #{self.length} bytes>"
115+
else
116+
"\#<#{self.class} closed>"
117+
end
96118
end
97119
end
98120
end

lib/protocol/http/body/deflate.rb

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

33
# Released under the MIT License.
4-
# Copyright, 2019-2023, by Samuel Williams.
4+
# Copyright, 2019-2024, by Samuel Williams.
55

66
require_relative 'wrapper'
77

lib/protocol/http/body/digestable.rb

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

33
# Released under the MIT License.
4-
# Copyright, 2020-2023, by Samuel Williams.
4+
# Copyright, 2020-2024, by Samuel Williams.
55

66
require_relative 'wrapper'
77

lib/protocol/http/body/file.rb

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

33
# Released under the MIT License.
4-
# Copyright, 2019-2023, by Samuel Williams.
4+
# Copyright, 2019-2024, by Samuel Williams.
55

66
require_relative 'readable'
77

lib/protocol/http/body/inflate.rb

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

33
# Released under the MIT License.
4-
# Copyright, 2019-2023, by Samuel Williams.
4+
# Copyright, 2019-2024, by Samuel Williams.
55

66
require 'zlib'
77

lib/protocol/http/body/readable.rb

+8-6
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ def read
7272
def each
7373
return to_enum unless block_given?
7474

75-
while chunk = self.read
76-
yield chunk
75+
begin
76+
while chunk = self.read
77+
yield chunk
78+
end
79+
rescue => error
80+
raise
81+
ensure
82+
self.close(error)
7783
end
78-
rescue => error
79-
raise
80-
ensure
81-
self.close(error)
8284
end
8385

8486
# Read all remaining chunks into a single binary string using `#each`.

lib/protocol/http/body/stream.rb

+3-7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def initialize(input = nil, output = Buffered.new)
2121

2222
# Will hold remaining data in `#read`.
2323
@buffer = nil
24+
2425
@closed = false
2526
@closed_read = false
2627
end
@@ -257,7 +258,7 @@ def close_read(error = nil)
257258
@closed_read = true
258259
@buffer = nil
259260

260-
input&.close(error)
261+
input.close(error)
261262
end
262263
end
263264

@@ -266,12 +267,7 @@ def close_write(error = nil)
266267
if output = @output
267268
@output = nil
268269

269-
# This is a compatibility hack to work around limitations in protocol-rack and can be removed when external tests are passing without it.
270-
if output.method(:close).arity == 1
271-
output.close(error)
272-
else
273-
output.close
274-
end
270+
output.close_write(error)
275271
end
276272
end
277273

lib/protocol/http/body/streamable.rb

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

33
# Released under the MIT License.
4-
# Copyright, 2022, by Samuel Williams.
4+
# Copyright, 2019-2024, by Samuel Williams.
55

66
require_relative 'readable'
77
require_relative 'writable'
@@ -137,7 +137,6 @@ def call(stream)
137137

138138
# Closing a stream indicates we are no longer interested in reading from it.
139139
def close(error = nil)
140-
$stderr.puts "Closing input: #{@input.inspect}"
141140
if input = @input
142141
@input = nil
143142
input.close(error)

lib/protocol/http/body/writable.rb

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

33
# Released under the MIT License.
4-
# Copyright, 2018-2023, by Samuel Williams.
4+
# Copyright, 2024, by Samuel Williams.
55

66
require_relative 'readable'
77

@@ -65,17 +65,64 @@ def read
6565
# Write a single chunk to the body. Signal completion by calling `#finish`.
6666
def write(chunk)
6767
# If the reader breaks, the writer will break.
68-
# The inverse of this is less obvious (*)
6968
if @closed
7069
raise(@error || Closed)
7170
end
7271

73-
@count += 1
7472
@queue.push(chunk)
73+
@count += 1
7574
end
7675

76+
# This alias is provided for compatibility with template generation.
7777
alias << write
7878

79+
def close_write(error = nil)
80+
@error ||= error
81+
@queue.close
82+
end
83+
84+
class Output
85+
def initialize(writable)
86+
@writable = writable
87+
@closed = false
88+
end
89+
90+
def closed?
91+
@closed || @writable.closed?
92+
end
93+
94+
def write(chunk)
95+
@writable.write(chunk)
96+
end
97+
98+
def close(error = nil)
99+
@closed = true
100+
101+
if error
102+
@writable.close(error)
103+
else
104+
@writable.close_write
105+
end
106+
end
107+
end
108+
109+
# Create an output wrapper which can be used to write chunks to the body.
110+
def output
111+
output = Output.new(self)
112+
113+
unless block_given?
114+
return output
115+
end
116+
117+
begin
118+
yield output
119+
rescue => error
120+
raise error
121+
ensure
122+
output.close(error)
123+
end
124+
end
125+
79126
def inspect
80127
"\#<#{self.class} #{@count} chunks written, #{status}>"
81128
end

test/protocol/http/body/deflate.rb

+1-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# frozen_string_literal: true
33

44
# Released under the MIT License.
5-
# Copyright, 2019-2023, by Samuel Williams.
5+
# Copyright, 2019-2024, by Samuel Williams.
66

77
require 'protocol/http/body/buffered'
88
require 'protocol/http/body/deflate'
@@ -17,7 +17,6 @@
1717

1818
it "should round-trip data" do
1919
body.write("Hello World!")
20-
body.close
2120

2221
expect(decompressed_body.join).to be == "Hello World!"
2322
end
@@ -26,7 +25,6 @@
2625

2726
it "should round-trip data" do
2827
body.write(data)
29-
body.close
3028

3129
expect(decompressed_body.read).to be == data
3230
expect(decompressed_body.read).to be == nil
@@ -39,7 +37,6 @@
3937
10.times do
4038
body.write("Hello World!")
4139
end
42-
body.close
4340

4441
10.times do
4542
expect(decompressed_body.read).to be == "Hello World!"

test/protocol/http/body/digestable.rb

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

33
# Released under the MIT License.
4-
# Copyright, 2020-2023, by Samuel Williams.
4+
# Copyright, 2020-2024, by Samuel Williams.
55

66
require 'protocol/http/body/digestable'
77
require 'protocol/http/body/buffered'

test/protocol/http/body/file.rb

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

33
# Released under the MIT License.
4-
# Copyright, 2019-2023, by Samuel Williams.
4+
# Copyright, 2019-2024, by Samuel Williams.
55

66
require 'protocol/http/body/file'
77

0 commit comments

Comments
 (0)