protocol-http 0.26.8 → 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20eddc2f7e87cb40659f99174fe456008413fdaf61841c1c366b17ded34a8dc6
4
- data.tar.gz: 5f7b795b609e434534d1910aeb84fc7ba77dc46e1157add3e40ea2a053e1ae3c
3
+ metadata.gz: a38b2bf9deae253c76d1bfeb0b980cc9ea833ce61c2e2b7ecc890ab951c852fe
4
+ data.tar.gz: de7d4603e6e944e5d05f9b31fe17b4374837128ef6cca687630c7e97fb1ba5f7
5
5
  SHA512:
6
- metadata.gz: 5b8a17aab9953fcefefea89da1913ce0fa8ce96d27dd91aad38690a21165abf42cf0b46f3f49f4b469c9af5409bffa733b69728acf0f55526b4a6bef8be041be
7
- data.tar.gz: 2264dbd29fdbc90a82f37d503c237092f559ec42093be5b57027976aa5c1d6f7019573e8b65a3d7f2d85f7de7de307c2c71e7104be449a2835e086c1ede8fdd9
6
+ metadata.gz: ad5ea5d1e217f3284560d9b3f3114314618ab3ab330c4717bb374eabd51e5a46fb8ab810f04092cb8a7018a3c102da6d752121a3f4a5ef8fc9ae0b131939c38d
7
+ data.tar.gz: 63aeea268ae41d87eb6ff8faea81c5db21c6bcda9da8fedf0d583d045cec1e8fea7a64d065096f52b28019998c0a73d4b642dc3537734d2fa986075e6ea55cca
checksums.yaml.gz.sig CHANGED
Binary file
@@ -11,6 +11,8 @@ module Protocol
11
11
  module Body
12
12
  # 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.
13
13
  class Stream
14
+ NEWLINE = "\n"
15
+
14
16
  def initialize(input = nil, output = Buffered.new)
15
17
  @input = input
16
18
  @output = output
@@ -28,10 +30,14 @@ module Protocol
28
30
 
29
31
  # This provides a read-only interface for data, which is surprisingly tricky to implement correctly.
30
32
  module Reader
31
- # rack.hijack_io must respond to:
32
- # read, write, read_nonblock, write_nonblock, flush, close, close_read, close_write, closed?
33
-
34
- # read behaves like IO#read. Its signature is read([length, [buffer]]). If given, length must be a non-negative Integer (>= 0) or nil, and buffer must be a String and may not be nil. If length is given and not nil, then this method reads at most length bytes from the input stream. If length is not given or nil, then this method reads all data until EOF. When EOF is reached, this method returns nil if length is given and not nil, or “” if length is not given or is nil. If buffer is given, then the read data will be placed into buffer instead of a newly created String object.
33
+ # Read data from the underlying stream.
34
+ #
35
+ # If given a non-negative length, it will read at most that many bytes from the stream. If the stream is at EOF, it will return nil.
36
+ #
37
+ # If the length is not given, it will read all data until EOF, or return an empty string if the stream is already at EOF.
38
+ #
39
+ # If buffer is given, then the read data will be placed into buffer instead of a newly created String object.
40
+ #
35
41
  # @param length [Integer] the amount of data to read
36
42
  # @param buffer [String] the buffer which will receive the data
37
43
  # @return a buffer containing the data
@@ -55,7 +61,7 @@ module Protocol
55
61
 
56
62
  # This ensures the subsequent `slice!` works correctly.
57
63
  buffer.force_encoding(Encoding::BINARY)
58
-
64
+
59
65
  # This will be at least one copy:
60
66
  @buffer = buffer.byteslice(length, buffer.bytesize)
61
67
 
@@ -76,7 +82,13 @@ module Protocol
76
82
  end
77
83
  end
78
84
 
79
- # Read at most `length` bytes from the stream. Will avoid reading from the underlying stream if possible.
85
+ # Read some bytes from the stream.
86
+ #
87
+ # If the length is given, at most length bytes will be read. Otherwise, one chunk of data from the underlying stream will be read.
88
+ #
89
+ # Will avoid reading from the underlying stream if there is buffered data available.
90
+ #
91
+ # @parameter length [Integer] The maximum number of bytes to read.
80
92
  def read_partial(length = nil)
81
93
  if @buffer
82
94
  buffer = @buffer
@@ -98,11 +110,13 @@ module Protocol
98
110
  return buffer
99
111
  end
100
112
 
113
+ # Similar to {read_partial} but raises an `EOFError` if the stream is at EOF.
101
114
  def readpartial(length)
102
115
  read_partial(length) or raise EOFError, "End of file reached!"
103
116
  end
104
117
 
105
- def read_nonblock(length, buffer = nil)
118
+ # Read data from the stream without blocking if possible.
119
+ def read_nonblock(length, buffer = nil, exception: nil)
106
120
  @buffer ||= read_next
107
121
  chunk = nil
108
122
 
@@ -127,10 +141,55 @@ module Protocol
127
141
 
128
142
  return buffer
129
143
  end
144
+
145
+ # Read data from the stream until encountering pattern.
146
+ #
147
+ # @parameter pattern [String] The pattern to match.
148
+ # @parameter offset [Integer] The offset to start searching from.
149
+ # @parameter chomp [Boolean] Whether to remove the pattern from the returned data.
150
+ # @returns [String] The contents of the stream up until the pattern, which is consumed but not returned.
151
+ def read_until(pattern, offset = 0, chomp: false)
152
+ # We don't want to split on the pattern, so we subtract the size of the pattern.
153
+ split_offset = pattern.bytesize - 1
154
+
155
+ @buffer ||= read_next
156
+ return nil if @buffer.nil?
157
+
158
+ until index = @buffer.index(pattern, offset)
159
+ offset = @buffer.bytesize - split_offset
160
+
161
+ offset = 0 if offset < 0
162
+
163
+ if chunk = read_next
164
+ @buffer << chunk
165
+ else
166
+ return nil
167
+ end
168
+ end
169
+
170
+ @buffer.freeze
171
+ matched = @buffer.byteslice(0, index+(chomp ? 0 : pattern.bytesize))
172
+ @buffer = @buffer.byteslice(index+pattern.bytesize, @buffer.bytesize)
173
+
174
+ return matched
175
+ end
176
+
177
+ # Read a single line from the stream.
178
+ #
179
+ # @parameter separator [String] The line separator, defaults to `\n`.
180
+ # @parameter *options [Hash] Additional options, passed to {read_until}.
181
+ def gets(separator = NEWLINE, **options)
182
+ read_until(separator, **options)
183
+ end
130
184
  end
131
185
 
132
186
  include Reader
133
187
 
188
+ # Write data to the underlying stream.
189
+ #
190
+ # @parameter buffer [String] The data to write.
191
+ # @raises [IOError] If the stream is not writable.
192
+ # @returns [Integer] The number of bytes written.
134
193
  def write(buffer)
135
194
  if @output
136
195
  @output.write(buffer)
@@ -140,36 +199,68 @@ module Protocol
140
199
  end
141
200
  end
142
201
 
143
- def write_nonblock(buffer)
202
+ # Write data to the stream using {write}.
203
+ #
204
+ # Provided for compatibility with IO-like objects.
205
+ #
206
+ # @parameter buffer [String] The data to write.
207
+ # @parameter exception [Boolean] Whether to raise an exception if the write would block, currently ignored.
208
+ # @returns [Integer] The number of bytes written.
209
+ def write_nonblock(buffer, exception: nil)
144
210
  write(buffer)
145
211
  end
146
212
 
213
+ # Write data to the stream using {write}.
147
214
  def <<(buffer)
148
215
  write(buffer)
149
216
  end
150
217
 
218
+ # Write lines to the stream.
219
+ #
220
+ # The current implementation buffers the lines and writes them in a single operation.
221
+ #
222
+ # @parameter arguments [Array(String)] The lines to write.
223
+ # @parameter separator [String] The line separator, defaults to `\n`.
224
+ def puts(*arguments, separator: NEWLINE)
225
+ buffer = ::String.new
226
+
227
+ arguments.each do |argument|
228
+ buffer << argument << separator
229
+ end
230
+
231
+ write(buffer)
232
+ end
233
+
234
+ # Flush the output stream.
235
+ #
236
+ # This is currently a no-op.
151
237
  def flush
152
238
  end
153
239
 
240
+ # Close the input body.
154
241
  def close_read
155
- @closed_read = true
156
- @buffer = nil
157
-
158
- @input&.close
159
- @input = nil
242
+ if @input
243
+ @closed_read = true
244
+ @buffer = nil
245
+
246
+ @input&.close
247
+ @input = nil
248
+ end
160
249
  end
161
250
 
162
- # close must never be called on the input stream. huh?
251
+ # Close the output body.
163
252
  def close_write
164
- @output&.close
165
- @output = nil
253
+ if @output
254
+ @output&.close
255
+ @output = nil
256
+ end
166
257
  end
167
258
 
168
259
  # Close the input and output bodies.
169
260
  def close(error = nil)
170
261
  self.close_read
171
262
  self.close_write
172
-
263
+
173
264
  return nil
174
265
  ensure
175
266
  @closed = true
@@ -5,6 +5,6 @@
5
5
 
6
6
  module Protocol
7
7
  module HTTP
8
- VERSION = "0.26.8"
8
+ VERSION = "0.27.0"
9
9
  end
10
10
  end
data/lib/protocol/http.rb CHANGED
@@ -9,3 +9,10 @@ require_relative 'http/headers'
9
9
  require_relative 'http/request'
10
10
  require_relative 'http/response'
11
11
  require_relative 'http/middleware'
12
+
13
+ # @namespace
14
+ module Protocol
15
+ # @namespace
16
+ module HTTP
17
+ end
18
+ end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protocol-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.8
4
+ version: 0.27.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -47,7 +47,7 @@ cert_chain:
47
47
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
48
48
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
49
49
  -----END CERTIFICATE-----
50
- date: 2024-07-07 00:00:00.000000000 Z
50
+ date: 2024-07-12 00:00:00.000000000 Z
51
51
  dependencies: []
52
52
  description:
53
53
  email:
@@ -114,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
114
  - !ruby/object:Gem::Version
115
115
  version: '0'
116
116
  requirements: []
117
- rubygems_version: 3.5.11
117
+ rubygems_version: 3.5.9
118
118
  signing_key:
119
119
  specification_version: 4
120
120
  summary: Provides abstractions to handle HTTP protocols.
metadata.gz.sig CHANGED
Binary file