protocol-http 0.23.12 → 0.24.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/design.md +167 -0
  4. data/lib/protocol/http/accept_encoding.rb +5 -20
  5. data/lib/protocol/http/body/buffered.rb +3 -19
  6. data/lib/protocol/http/body/completable.rb +2 -19
  7. data/lib/protocol/http/body/deflate.rb +3 -30
  8. data/lib/protocol/http/body/digestable.rb +9 -21
  9. data/lib/protocol/http/body/file.rb +4 -21
  10. data/lib/protocol/http/body/head.rb +3 -20
  11. data/lib/protocol/http/body/inflate.rb +8 -22
  12. data/lib/protocol/http/body/readable.rb +6 -23
  13. data/lib/protocol/http/body/reader.rb +5 -21
  14. data/lib/protocol/http/body/rewindable.rb +2 -19
  15. data/lib/protocol/http/body/stream.rb +6 -23
  16. data/lib/protocol/http/body/wrapper.rb +2 -19
  17. data/lib/protocol/http/content_encoding.rb +2 -19
  18. data/lib/protocol/http/cookie.rb +3 -19
  19. data/lib/protocol/http/error.rb +2 -19
  20. data/lib/protocol/http/header/authorization.rb +2 -19
  21. data/lib/protocol/http/header/cache_control.rb +4 -21
  22. data/lib/protocol/http/header/connection.rb +4 -21
  23. data/lib/protocol/http/header/cookie.rb +2 -19
  24. data/lib/protocol/http/header/etag.rb +3 -20
  25. data/lib/protocol/http/header/etags.rb +2 -19
  26. data/lib/protocol/http/header/multiple.rb +2 -19
  27. data/lib/protocol/http/header/split.rb +8 -21
  28. data/lib/protocol/http/header/vary.rb +2 -19
  29. data/lib/protocol/http/headers.rb +12 -19
  30. data/lib/protocol/http/methods.rb +2 -19
  31. data/lib/protocol/http/middleware/builder.rb +2 -19
  32. data/lib/protocol/http/middleware.rb +2 -19
  33. data/lib/protocol/http/reference.rb +77 -69
  34. data/lib/protocol/http/request.rb +3 -20
  35. data/lib/protocol/http/response.rb +10 -20
  36. data/lib/protocol/http/url.rb +4 -20
  37. data/lib/protocol/http/version.rb +3 -20
  38. data/lib/protocol/http.rb +2 -19
  39. data/license.md +27 -0
  40. data/readme.md +32 -0
  41. data.tar.gz.sig +0 -0
  42. metadata +9 -4
  43. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4cae774ef59f117617900a2b230789cdeb05c4eb7a5ec37fe92a9fd9ecfdd960
4
- data.tar.gz: 323033ee1461a0690f5dfb130b0a710b89358c65097e0759031df5a54b5a8175
3
+ metadata.gz: ca739827af38110440c34d4df98b7e67dfcc671266b45d0d4e9599a0cf352259
4
+ data.tar.gz: 1d79370138e22504cd3b8c41b9285cd3c323dbbe4b56ed810eece6189e1734db
5
5
  SHA512:
6
- metadata.gz: d8a9a03e66bd5f3a31e73646d5defc3faa5e05324927ae0c999bb66d2767461a35cd7e5d394ed34a4e24bdbcddcf2186a910e1137e3c4dfd989d3ec420e973c3
7
- data.tar.gz: 2b9a8c75c3775f52d3ad711b1565e4db6b2b03968c240c0f5f7fccd365bde27f69ee9d3f9754ace710172eb4edd91a9c5f890adfa1a7e523a0db1be44d806d36
6
+ metadata.gz: e4291f142cde7c38d3bd8e96f050df2eaec3551eafcc5381e7518813d4405576504f7a404fc34f688df3ab1867510587ea9052d763451733ed97da4fd5e9c47b
7
+ data.tar.gz: 56bde2a2296edaf86aac94a2b88a84b86b88abf967205d0c124b88f477773bcc55dca29c294ab52fe042b621e49fed11429e5ef98a6fd627526176ff7935af2e
checksums.yaml.gz.sig CHANGED
Binary file
data/design.md ADDED
@@ -0,0 +1,167 @@
1
+ # Middleware Design
2
+
3
+ `Body::Writable` is a queue of String chunks.
4
+
5
+ ## Request Response Model
6
+
7
+ ~~~ruby
8
+ class Request
9
+ attr :verb
10
+ attr :target
11
+ attr :body
12
+ end
13
+
14
+ class Response
15
+ attr :status
16
+ attr :headers
17
+ attr :body
18
+ end
19
+
20
+ def call(request)
21
+ return response
22
+ end
23
+
24
+ def call(request)
25
+ return @app.call(request)
26
+ end
27
+ ~~~
28
+
29
+ ## Stream Model
30
+
31
+ ~~~ruby
32
+ class Stream
33
+ attr :verb
34
+ attr :target
35
+
36
+ def respond(status, headers) = ...
37
+
38
+ attr_accessor :input
39
+ attr_accessor :output
40
+ end
41
+
42
+ class Response
43
+ def initialize(verb, target)
44
+ @input = Body::Writable.new
45
+ @output = Body::Writable.new
46
+ end
47
+
48
+ def request(verb, target)
49
+ # Create a request stream suitable for writing into the buffered response:
50
+ Stream.new(verb, target, @input, @output)
51
+ end
52
+
53
+ def write(...)
54
+ @input.write(...)
55
+ end
56
+
57
+ def read
58
+ @output.read
59
+ end
60
+ end
61
+
62
+ def call(stream)
63
+ # nothing. maybe error
64
+ end
65
+
66
+ def call(stream)
67
+ @app.call(stream)
68
+ end
69
+ ~~~
70
+
71
+ # Client Design
72
+
73
+ ## Request Response Model
74
+
75
+ ~~~ruby
76
+ request = Request.new("GET", url)
77
+ response = call(request)
78
+
79
+ response.headers
80
+ response.read
81
+ ~~~
82
+
83
+ ## Stream Model
84
+
85
+ ~~~ruby
86
+ response = Response.new
87
+ call(response.request("GET", url))
88
+
89
+ response.headers
90
+ response.read
91
+ ~~~
92
+
93
+ ## Differences
94
+
95
+ The request/response model has a symmetrical design which naturally uses the return value for the result of executing the request. The result encapsulates the behaviour of how to read the response status, headers and body. Because of that, streaming input and output becomes a function of the result object itself. As in:
96
+
97
+ ~~~ruby
98
+ def call(request)
99
+ body = Body::Writable.new
100
+
101
+ Fiber.schedule do
102
+ while chunk = request.input.read
103
+ body.write(chunk.reverse)
104
+ end
105
+ end
106
+
107
+ return Response[200, [], body]
108
+ end
109
+
110
+ input = Body::Writable.new
111
+ response = call(... body ...)
112
+
113
+ input.write("Hello World")
114
+ input.close
115
+ response.read -> "dlroW olleH"
116
+ ~~~
117
+
118
+ The streaming model does not have the same symmetry, and instead opts for a uni-directional flow of information.
119
+
120
+ ~~~ruby
121
+ def call(stream)
122
+ Fiber.schedule do
123
+ while chunk = stream.read
124
+ stream.write(chunk.reverse)
125
+ end
126
+ end
127
+ end
128
+
129
+ input = Body::Writable.new
130
+ response = Response.new(...input...)
131
+ call(response.stream)
132
+
133
+ input.write("Hello World")
134
+ input.close
135
+ response.read -> "dlroW olleH"
136
+ ~~~
137
+
138
+ The value of this uni-directional flow is that it is natural for the stream to be taken out of the scope imposed by the nested `call(request)` model. However, the user must explicitly close the stream, since it's no longer scoped to the client and/or server.
139
+
140
+ ## Connection Upgrade
141
+
142
+ ### HTTP/1
143
+
144
+ ```
145
+ GET /path/to/websocket HTTP/1.1
146
+ connection: upgrade
147
+ upgrade: websocket
148
+ ```
149
+
150
+ Request.new(GET, ..., protocol = websocket)
151
+ -> Response.new(101, ..., protocol = websocket)
152
+
153
+ ```
154
+ 101 Switching Protocols
155
+ upgrade: websocket
156
+ ```
157
+
158
+ ### HTTP/2
159
+
160
+ ```
161
+ :method CONNECT
162
+ :path /path/to/websocket
163
+ :protocol websocket
164
+ ```
165
+
166
+ Request.new(CONNECT, ..., protocol = websocket)
167
+ -> Response.new(200, ..., protocol = websocket)
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2023, by Samuel Williams.
22
5
 
23
6
  require_relative 'middleware'
24
7
 
@@ -34,7 +17,9 @@ module Protocol
34
17
 
35
18
  DEFAULT_WRAPPERS = {
36
19
  'gzip' => Body::Inflate.method(:for),
37
- 'identity' => ->(body){body},
20
+
21
+ # There is no point including this:
22
+ # 'identity' => ->(body){body},
38
23
  }
39
24
 
40
25
  def initialize(app, wrappers = DEFAULT_WRAPPERS)
@@ -1,24 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2023, by Samuel Williams.
5
+ # Copyright, 2020, by Bryan Powell.
22
6
 
23
7
  require_relative 'readable'
24
8
 
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2023, by Samuel Williams.
22
5
 
23
6
  require_relative 'wrapper'
24
7
 
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2023, by Samuel Williams.
22
5
 
23
6
  require_relative 'wrapper'
24
7
 
@@ -38,16 +21,6 @@ module Protocol
38
21
  'gzip' => GZIP,
39
22
  }
40
23
 
41
- def self.encoding_name(window_size)
42
- if window_size <= -8
43
- return 'deflate'
44
- elsif window_size >= 16
45
- return 'gzip'
46
- else
47
- return 'compress'
48
- end
49
- end
50
-
51
24
  def initialize(body, stream)
52
25
  super(body)
53
26
 
@@ -118,4 +91,4 @@ module Protocol
118
91
  end
119
92
  end
120
93
  end
121
- end
94
+ end
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2023, by Samuel Williams.
22
5
 
23
6
  require_relative 'wrapper'
24
7
 
@@ -35,6 +18,7 @@ module Protocol
35
18
  end
36
19
  end
37
20
 
21
+ # @parameter callback [Block] The callback is invoked when the digest is complete.
38
22
  def initialize(body, digest = Digest::SHA256.new, callback = nil)
39
23
  super(body)
40
24
 
@@ -46,8 +30,12 @@ module Protocol
46
30
  @digest
47
31
  end
48
32
 
49
- def etag
50
- @digest.hexdigest.dump
33
+ def etag(weak: false)
34
+ if weak
35
+ "W/\"#{digest.hexdigest}\""
36
+ else
37
+ "\"#{digest.hexdigest}\""
38
+ end
51
39
  end
52
40
 
53
41
  def stream?
@@ -1,33 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2023, by Samuel Williams.
22
5
 
23
6
  require_relative 'readable'
24
- require 'async/io/stream'
25
7
 
26
8
  module Protocol
27
9
  module HTTP
28
10
  module Body
29
11
  class File < Readable
30
- BLOCK_SIZE = Async::IO::BLOCK_SIZE
12
+ BLOCK_SIZE = 4096
31
13
  MODE = ::File::RDONLY | ::File::BINARY
32
14
 
33
15
  def self.open(path, *arguments, **options)
@@ -71,6 +53,7 @@ module Protocol
71
53
 
72
54
  def rewind
73
55
  @file.seek(@offset)
56
+ @remaining = @length
74
57
  end
75
58
 
76
59
  def stream?
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2023, by Samuel Williams.
22
5
 
23
6
  require_relative 'readable'
24
7
 
@@ -52,4 +35,4 @@ module Protocol
52
35
  end
53
36
  end
54
37
  end
55
- end
38
+ end
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2023, by Samuel Williams.
22
5
 
23
6
  require 'zlib'
24
7
 
@@ -40,16 +23,19 @@ module Protocol
40
23
  return if @stream.finished?
41
24
 
42
25
  # The stream might have been closed while waiting for the chunk to come in.
43
- if chunk = super
26
+ while chunk = super
44
27
  @input_length += chunk.bytesize
45
28
 
46
29
  # It's possible this triggers the stream to finish.
47
30
  chunk = @stream.inflate(chunk)
48
31
 
32
+ break unless chunk&.empty?
33
+ end
34
+
35
+ if chunk
49
36
  @output_length += chunk.bytesize
50
37
  elsif !@stream.closed?
51
38
  chunk = @stream.finish
52
-
53
39
  @output_length += chunk.bytesize
54
40
  end
55
41
 
@@ -62,4 +48,4 @@ module Protocol
62
48
  end
63
49
  end
64
50
  end
65
- end
51
+ end
@@ -1,26 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'async/io/buffer'
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2023, by Samuel Williams.
24
5
 
25
6
  module Protocol
26
7
  module HTTP
@@ -39,12 +20,14 @@ module Protocol
39
20
  def close(error = nil)
40
21
  end
41
22
 
42
- # Will read return any data?
23
+ # Optimistically determine whether read (may) return any data.
24
+ # If this returns true, then calling read will definitely return nil.
25
+ # If this returns false, then calling read may return nil.
43
26
  def empty?
44
27
  false
45
28
  end
46
29
 
47
- # Whether calling read will block.
30
+ # Whether calling read will return a chunk of data without blocking.
48
31
  # We prefer pessimistic implementation, and thus default to `false`.
49
32
  # @return [Boolean]
50
33
  def ready?
@@ -1,24 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2023, by Samuel Williams.
5
+ # Copyright, 2022, by Dan Olson.
22
6
 
23
7
  module Protocol
24
8
  module HTTP
@@ -57,9 +41,9 @@ module Protocol
57
41
  end
58
42
 
59
43
  # Write the body of the response to the given file path.
60
- def save(path, mode = ::File::WRONLY|::File::CREAT, *args)
44
+ def save(path, mode = ::File::WRONLY|::File::CREAT, **options)
61
45
  if @body
62
- ::File.open(path, mode, *args) do |file|
46
+ ::File.open(path, mode, **options) do |file|
63
47
  self.each do |chunk|
64
48
  file.write(chunk)
65
49
  end
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2023, by Samuel Williams.
22
5
 
23
6
  require_relative 'wrapper'
24
7
  require_relative 'buffered'
@@ -1,24 +1,7 @@
1
1
  # frozen_string_literal: true
2
- #
3
- # Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2023, by Samuel Williams.
22
5
 
23
6
  require_relative 'buffered'
24
7
 
@@ -27,7 +10,7 @@ module Protocol
27
10
  module Body
28
11
  # The input stream is an IO-like object which contains the raw HTTP POST data. When applicable, its external encoding must be “ASCII-8BIT” and it must be opened in binary mode, for Ruby 1.9 compatibility. The input stream must respond to gets, each, read and rewind.
29
12
  class Stream
30
- def initialize(input, output = Buffered.new)
13
+ def initialize(input = nil, output = Buffered.new)
31
14
  @input = input
32
15
  @output = output
33
16
 
@@ -53,8 +36,8 @@ module Protocol
53
36
  def read(length = nil, buffer = nil)
54
37
  return '' if length == 0
55
38
 
56
- buffer ||= Async::IO::Buffer.new
57
-
39
+ buffer ||= String.new.force_encoding(Encoding::BINARY)
40
+
58
41
  # Take any previously buffered data and replace it into the given buffer.
59
42
  if @buffer
60
43
  buffer.replace(@buffer)