File: streamable.rb

package info (click to toggle)
ruby-async-http 0.94.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 916 kB
  • sloc: ruby: 5,224; javascript: 40; makefile: 4
file content (134 lines) | stat: -rw-r--r-- 3,397 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2024, by Samuel Williams.

require "async/http/protocol/http"
require "protocol/http/body/streamable"
require "sus/fixtures/async/http"

AnEchoServer = Sus::Shared("an echo server") do
	let(:app) do
		::Protocol::HTTP::Middleware.for do |request|
			streamable = ::Protocol::HTTP::Body::Streamable.response(request) do |stream|
				Console.debug(self, "Echoing chunks...")
				while chunk = stream.readpartial(1024)
					Console.debug(self, "Reading chunk:", chunk: chunk)
					stream.write(chunk)
				end
			rescue EOFError
				Console.debug(self, "EOF.")
				# Ignore.
			ensure
				Console.debug(self, "Closing stream.")
				stream.close
			end
			
			::Protocol::HTTP::Response[200, {}, streamable]
		end
	end
	
	it "should echo the request body" do
		chunks = ["Hello,", "World!"]
		response_chunks = Queue.new
		
		output = ::Protocol::HTTP::Body::Writable.new
		response = client.post("/", body: output)
		stream = ::Protocol::HTTP::Body::Stream.new(response.body, output)
		
		begin
			Console.debug(self, "Echoing chunks...")
			chunks.each do |chunk|
				Console.debug(self, "Writing chunk:", chunk: chunk)
				stream.write(chunk)
			end
			
			Console.debug(self, "Closing write.")
			stream.close_write
			
			Console.debug(self, "Reading chunks...")
			while chunk = stream.readpartial(1024)
				Console.debug(self, "Reading chunk:", chunk: chunk)
				response_chunks << chunk
			end
		rescue EOFError
			Console.debug(self, "EOF.")
			# Ignore.
		ensure
			Console.debug(self, "Closing stream.")
			stream.close
			response_chunks.close
		end
		
		chunks.each do |chunk|
			expect(response_chunks.pop).to be == chunk
		end
	end
end

AnEchoClient = Sus::Shared("an echo client") do
	let(:chunks) {["Hello,", "World!"]}
	let(:response_chunks) {Queue.new}
	
	let(:app) do
		::Protocol::HTTP::Middleware.for do |request|
			streamable = ::Protocol::HTTP::Body::Streamable.response(request) do |stream|
				Console.debug(self, "Echoing chunks...")
				chunks.each do |chunk|
					stream.write(chunk)
				end
				
				Console.debug(self, "Closing write.")
				stream.close_write
				
				Console.debug(self, "Reading chunks...")
				while chunk = stream.readpartial(1024)
					Console.debug(self, "Reading chunk:", chunk: chunk)
					response_chunks << chunk
				end
			rescue EOFError
				Console.debug(self, "EOF.")
				# Ignore.
			ensure
				Console.debug(self, "Closing stream.")
				stream.close
			end
			
			::Protocol::HTTP::Response[200, {}, streamable]
		end
	end
	
	it "should echo the response body" do
		output = ::Protocol::HTTP::Body::Writable.new
		response = client.post("/", body: output)
		stream = ::Protocol::HTTP::Body::Stream.new(response.body, output)
		
		begin
			Console.debug(self, "Echoing chunks...")
			while chunk = stream.readpartial(1024)
				stream.write(chunk)
			end
		rescue EOFError
			Console.debug(self, "EOF.")
			# Ignore.
		ensure
			Console.debug(self, "Closing stream.")
			stream.close
		end
		
		chunks.each do |chunk|
			expect(response_chunks.pop).to be == chunk
		end
	end
end

[Async::HTTP::Protocol::HTTP1, Async::HTTP::Protocol::HTTP2].each do |protocol|
	describe protocol, unique: protocol.name do
		include Sus::Fixtures::Async::HTTP::ServerContext
		
		let(:protocol) {subject}
		
		it_behaves_like AnEchoServer
		it_behaves_like AnEchoClient
	end
end