protocol-http 0.22.5 → 0.22.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 18e5cfb137351205caf1e8c38a22b3857b55593d75496784326918f7159e686d
4
- data.tar.gz: a9679ae47a3313b8fcd14dc5ea5a22b93fdf1a08c8d01f03dfdb81ea8ee16338
3
+ metadata.gz: 4b1672fc86e8bbe321f648e200205314ee472f9b01c326882f089e149b584f11
4
+ data.tar.gz: acbe42e8d8af4b50d018325b0204cec345ed161fbb7eba0583a512ce65c0a713
5
5
  SHA512:
6
- metadata.gz: f3a0305df607f355df9ad6ec5ec3db2442ced0bfd30ef792af8e1823b850a03a1f46069baf21aa52b802a31593ce11ab79fab2225016336872a7d0504b9c59e1
7
- data.tar.gz: ca27f71e4768d5b50590e85f9dabc5003a9daa367494f29eb8ce2e742cb22907a580c1b8f3a11ec0abe946b1cb7c036cddb9eb14c46202fbcce5d3c47a31a028
6
+ metadata.gz: 1cda8cf0c22f5d9a01a308cc83f2b80209bc3ad98ec84c5082d0846e6835224bb6c2ef9f9cc25b12eaa542f77000fa13c7cc9d2aba2107ba362e737c13ef90a0
7
+ data.tar.gz: 4fcd1417896726bce8019ea8fc5ebdbd92f07484611855c4cc04b0ba1a59deb18a79dd1d0c4b8978b7ec48c3c27376b09f3d75cd33728d4d5474093a08699694
checksums.yaml.gz.sig ADDED
Binary file
@@ -72,7 +72,7 @@ module Protocol
72
72
  stream.write(chunk)
73
73
  end
74
74
  ensure
75
- stream.close($!)
75
+ stream.close
76
76
  end
77
77
 
78
78
  # Read all remaining chunks into a buffered body and close the underlying input.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
-
2
+ #
3
3
  # Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -20,15 +20,19 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
21
  # THE SOFTWARE.
22
22
 
23
+ require_relative 'buffered'
24
+
23
25
  module Protocol
24
26
  module HTTP
25
27
  module Body
26
28
  # 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.
27
29
  class Stream
28
- def initialize(input, output)
30
+ def initialize(input, output = Buffered.new)
29
31
  @input = input
30
32
  @output = output
31
33
 
34
+ raise ArgumentError, "Non-writable output!" unless output.respond_to?(:write)
35
+
32
36
  # Will hold remaining data in `#read`.
33
37
  @buffer = nil
34
38
  @closed = false
@@ -45,29 +49,62 @@ module Protocol
45
49
  # @param buffer [String] the buffer which will receive the data
46
50
  # @return a buffer containing the data
47
51
  def read(length = nil, buffer = nil)
52
+ return '' if length == 0
53
+
48
54
  buffer ||= Async::IO::Buffer.new
49
- buffer.clear
55
+
56
+ # Take any previously buffered data and replace it into the given buffer.
57
+ if @buffer
58
+ buffer.replace(@buffer)
59
+ @buffer = nil
60
+ end
50
61
 
51
- until buffer.bytesize == length
52
- @buffer = read_next if @buffer.nil?
53
- break if @buffer.nil?
62
+ if length
63
+ while buffer.bytesize < length and chunk = read_next
64
+ buffer << chunk
65
+ end
66
+
67
+ # This ensures the subsequent `slice!` works correctly.
68
+ buffer.force_encoding(Encoding::BINARY)
69
+
70
+ # This will be at least one copy:
71
+ @buffer = buffer.byteslice(length, buffer.bytesize)
54
72
 
55
- remaining_length = length - buffer.bytesize if length
73
+ # This should be zero-copy:
74
+ buffer.slice!(length)
56
75
 
57
- if remaining_length && remaining_length < @buffer.bytesize
58
- # We know that we are not going to reuse the original buffer.
59
- # But byteslice will generate a hidden copy. So let's freeze it first:
60
- @buffer.freeze
61
-
62
- buffer << @buffer.byteslice(0, remaining_length)
63
- @buffer = @buffer.byteslice(remaining_length, @buffer.bytesize)
76
+ if buffer.empty?
77
+ return nil
64
78
  else
65
- buffer << @buffer
66
- @buffer = nil
79
+ return buffer
67
80
  end
81
+ else
82
+ while chunk = read_next
83
+ buffer << chunk
84
+ end
85
+
86
+ return buffer
87
+ end
88
+ end
89
+
90
+ # Read at most `length` bytes from the stream. Will avoid reading from the underlying stream if possible.
91
+ def read_partial(length = nil)
92
+ if @buffer
93
+ buffer = @buffer
94
+ @buffer = nil
95
+ else
96
+ buffer = read_next
68
97
  end
69
98
 
70
- return nil if buffer.empty? && length && length > 0
99
+ if buffer and length
100
+ if buffer.bytesize > length
101
+ # This ensures the subsequent `slice!` works correctly.
102
+ buffer.force_encoding(Encoding::BINARY)
103
+
104
+ @buffer = buffer.byteslice(length, buffer.bytesize)
105
+ buffer.slice!(length)
106
+ end
107
+ end
71
108
 
72
109
  return buffer
73
110
  end
@@ -76,6 +113,11 @@ module Protocol
76
113
  @buffer ||= read_next
77
114
  chunk = nil
78
115
 
116
+ unless @buffer
117
+ buffer&.clear
118
+ return
119
+ end
120
+
79
121
  if @buffer.bytesize > length
80
122
  chunk = @buffer.byteslice(0, length)
81
123
  @buffer = @buffer.byteslice(length, @buffer.bytesize)
@@ -94,7 +136,12 @@ module Protocol
94
136
  end
95
137
 
96
138
  def write(buffer)
97
- @output.write(buffer)
139
+ if @output
140
+ @output.write(buffer)
141
+ return buffer.bytesize
142
+ else
143
+ raise IOError, "Stream is not writable, output has been closed!"
144
+ end
98
145
  end
99
146
 
100
147
  alias write_nonblock write
@@ -104,17 +151,21 @@ module Protocol
104
151
 
105
152
  def close_read
106
153
  @input&.close
154
+ @input = nil
107
155
  end
108
156
 
109
157
  # close must never be called on the input stream. huh?
110
158
  def close_write
111
159
  @output&.close
160
+ @output = nil
112
161
  end
113
162
 
114
163
  # Close the input and output bodies.
115
- def close
164
+ def close(error = nil)
116
165
  self.close_read
117
166
  self.close_write
167
+
168
+ return nil
118
169
  ensure
119
170
  @closed = true
120
171
  end
@@ -132,11 +183,11 @@ module Protocol
132
183
  private
133
184
 
134
185
  def read_next
135
- if chunk = @input&.read
136
- return chunk
186
+ if @input
187
+ return @input.read
137
188
  else
138
189
  @input = nil
139
- return nil
190
+ raise IOError, "Stream is not readable, input has been closed!"
140
191
  end
141
192
  end
142
193
  end
@@ -101,22 +101,27 @@ module Protocol
101
101
  # An array of `[key, value]` pairs.
102
102
  attr :fields
103
103
 
104
- # @return the trailer if there are any.
104
+ # @returns Whether there are any trailers.
105
105
  def trailer?
106
106
  @tail != nil
107
107
  end
108
108
 
109
- # Record the current headers, and prepare to receive trailer.
109
+ # Record the current headers, and prepare to add trailers.
110
+ #
111
+ # This method is typically used after headers are sent to capture any
112
+ # additional headers which should then be sent as trailers.
113
+ #
114
+ # A sender that intends to generate one or more trailer fields in a
115
+ # message should generate a trailer header field in the header section of
116
+ # that message to indicate which fields might be present in the trailers.
117
+ #
118
+ # @parameter names [Array] The trailer header names which will be added later.
119
+ # @yields block {|name, value| ...} The trailer headers if any.
120
+ # @returns An enumerator which is suitable for iterating over trailers.
110
121
  def trailer!(&block)
111
- return nil unless self.include?(TRAILER)
112
-
113
122
  @tail ||= @fields.size
114
123
 
115
- return to_enum(:trailer!) unless block_given?
116
-
117
- if @tail
118
- @fields.drop(@tail).each(&block)
119
- end
124
+ return trailer(&block)
120
125
  end
121
126
 
122
127
  # Enumerate all headers in the trailer, if there are any.
@@ -23,13 +23,14 @@
23
23
  module Protocol
24
24
  module HTTP
25
25
  module URL
26
- # Escapes a generic string, using percent encoding.
26
+ # Escapes a string using percent encoding.
27
27
  def self.escape(string, encoding = string.encoding)
28
28
  string.b.gsub(/([^a-zA-Z0-9_.\-]+)/) do |m|
29
29
  '%' + m.unpack('H2' * m.bytesize).join('%').upcase
30
30
  end.force_encoding(encoding)
31
31
  end
32
32
 
33
+ # Unescapes a percent encoded string.
33
34
  def self.unescape(string, encoding = string.encoding)
34
35
  string.b.gsub(/%(\h\h)/) do |hex|
35
36
  Integer(hex, 16).chr
@@ -39,7 +40,7 @@ module Protocol
39
40
  # According to https://tools.ietf.org/html/rfc3986#section-3.3, we escape non-pchar.
40
41
  NON_PCHAR = /([^a-zA-Z0-9_\-\.~!$&'()*+,;=:@\/]+)/.freeze
41
42
 
42
- # Escapes a path
43
+ # Escapes non-path characters using percent encoding.
43
44
  def self.escape_path(path)
44
45
  encoding = path.encoding
45
46
  path.b.gsub(NON_PCHAR) do |m|
@@ -47,7 +48,7 @@ module Protocol
47
48
  end.force_encoding(encoding)
48
49
  end
49
50
 
50
- # Encodes a hash or array into a query string
51
+ # Encodes a hash or array into a query string.
51
52
  def self.encode(value, prefix = nil)
52
53
  case value
53
54
  when Array
@@ -67,9 +68,12 @@ module Protocol
67
68
  end
68
69
  end
69
70
 
71
+ # Scan a string for URL-encoded key/value pairs.
72
+ # @yields {|key, value| ...}
73
+ # @parameter key [String] The unescaped key.
74
+ # @parameter value [String] The unescaped key.
70
75
  def self.scan(string)
71
- # TODO Ruby 2.6 doesn't require `.each`
72
- string.split('&').each do |assignment|
76
+ string.split('&') do |assignment|
73
77
  key, value = assignment.split('=', 2)
74
78
 
75
79
  yield unescape(key), unescape(value)
@@ -22,6 +22,6 @@
22
22
 
23
23
  module Protocol
24
24
  module HTTP
25
- VERSION = "0.22.5"
25
+ VERSION = "0.22.9"
26
26
  end
27
27
  end
data.tar.gz.sig ADDED
Binary file
metadata CHANGED
@@ -1,14 +1,47 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protocol-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.22.5
4
+ version: 0.22.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
+ - Bruno Sutic
9
+ - Bryan Powell
10
+ - Olle Jonsson
11
+ - Yuta Iwama
8
12
  autorequire:
9
13
  bindir: bin
10
- cert_chain: []
11
- date: 2021-07-15 00:00:00.000000000 Z
14
+ cert_chain:
15
+ - |
16
+ -----BEGIN CERTIFICATE-----
17
+ MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
18
+ ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
19
+ CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
20
+ MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
21
+ MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
22
+ bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
23
+ igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
24
+ 9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
25
+ sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
26
+ e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
27
+ XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
28
+ RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
29
+ tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
30
+ zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
31
+ xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
32
+ BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
33
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
34
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
35
+ cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
36
+ xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
37
+ c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
38
+ 8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
39
+ JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
40
+ eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
41
+ Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
42
+ voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
43
+ -----END CERTIFICATE-----
44
+ date: 2022-08-07 00:00:00.000000000 Z
12
45
  dependencies:
13
46
  - !ruby/object:Gem::Dependency
14
47
  name: bundler
@@ -112,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
145
  - !ruby/object:Gem::Version
113
146
  version: '0'
114
147
  requirements: []
115
- rubygems_version: 3.1.6
148
+ rubygems_version: 3.3.7
116
149
  signing_key:
117
150
  specification_version: 4
118
151
  summary: Provides abstractions to handle HTTP protocols.
metadata.gz.sig ADDED
Binary file