protocol-http 0.16.3 → 0.20.1

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: 8f3dfaca48112b9b8d52096c8cab996403736391102e44a2f9ed6f5e71c2ce7d
4
- data.tar.gz: 611c1ba35c482cba1e4fbeb98daadaf7872b8d2198717c795dfa94a4343e7b38
3
+ metadata.gz: 5f14e6a0192840efd07d2ba8e8e3a8bd9312eb5fa8b976f1e12baaf14ee49696
4
+ data.tar.gz: 2548bc880b20a5e162cad7fdcbbece9a0cdfae429861b8a5f1bbd68cf904cb9b
5
5
  SHA512:
6
- metadata.gz: 8d6988b4b2f2c1218c441d05788b88db0aa8890ac70877acc6f87c8ce2f18e32bae5d20505532ece25576c792c1935d42f69bb11ea3e34a8908211ed3fadc88f
7
- data.tar.gz: 111ec27937755f580826ff37e2cdfcce11b8fcc571434e31c12822e355694b5d4431fc378c3e91476368006bf657bcb0be164392302274221586074e0193b03a
6
+ metadata.gz: b1e6692c96818aed1ed11c02b976169598ba9df9afc1f73109745168f62d85a75b6bf9abe530cac1daa39a3a40b5a815e06280581d8912b6c32f7e488f35fac0
7
+ data.tar.gz: 747e961c97c027258a46fbbd70f9845eead55d0c3dc6d108dae0083b99693bf5384f3868c9d50e5270d06337341879d265dc362a7907a16d22ecca73149e8223
@@ -3,4 +3,3 @@ root = true
3
3
  [*]
4
4
  indent_style = tab
5
5
  indent_size = 2
6
-
@@ -0,0 +1,44 @@
1
+ name: Development
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+ runs-on: ${{matrix.os}}-latest
8
+ continue-on-error: ${{matrix.experimental}}
9
+
10
+ strategy:
11
+ matrix:
12
+ os:
13
+ - ubuntu
14
+ - macos
15
+
16
+ ruby:
17
+ - 2.5
18
+ - 2.6
19
+ - 2.7
20
+
21
+ experimental: [false]
22
+ env: [""]
23
+
24
+ include:
25
+ - os: ubuntu
26
+ ruby: truffleruby
27
+ experimental: true
28
+ - os: ubuntu
29
+ ruby: jruby
30
+ experimental: true
31
+ - os: ubuntu
32
+ ruby: head
33
+ experimental: true
34
+
35
+ steps:
36
+ - uses: actions/checkout@v2
37
+ - uses: ioquatix/setup-ruby@master
38
+ with:
39
+ ruby-version: ${{matrix.ruby}}
40
+ bundler-cache: true
41
+
42
+ - name: Run tests
43
+ timeout-minutes: 5
44
+ run: ${{matrix.env}} bundle exec rspec
data/.gitignore CHANGED
@@ -6,8 +6,9 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ /external/
9
10
 
10
11
  # rspec failure tracking
11
12
  .rspec_status
12
- Gemfile.lock
13
+ /gems.locked
13
14
  .covered.db
data/README.md CHANGED
@@ -2,29 +2,29 @@
2
2
 
3
3
  Provides abstractions for working with the HTTP protocol.
4
4
 
5
- [![Build Status](https://travis-ci.com/socketry/protocol-http.svg?branch=master)](http://travis-ci.com/socketry/protocol-http)
5
+ [![Development Status](https://github.com/socketry/protocol-http/workflows/Development/badge.svg)](https://github.com/socketry/protocol-http/actions?workflow=Development)
6
6
 
7
7
  ## Installation
8
8
 
9
9
  Add this line to your application's Gemfile:
10
10
 
11
- ```ruby
11
+ ``` ruby
12
12
  gem 'protocol-http'
13
13
  ```
14
14
 
15
15
  And then execute:
16
16
 
17
- $ bundle
17
+ $ bundle
18
18
 
19
19
  Or install it yourself as:
20
20
 
21
- $ gem install protocol-http
21
+ $ gem install protocol-http
22
22
 
23
23
  ## Usage
24
24
 
25
25
  ### Headers
26
26
 
27
- ```ruby
27
+ ``` ruby
28
28
  require 'protocol/http/headers'
29
29
 
30
30
  headers = Protocol::HTTP::Headers.new
@@ -37,7 +37,7 @@ headers['content-type']
37
37
 
38
38
  ### Reference
39
39
 
40
- ```ruby
40
+ ``` ruby
41
41
  require 'protocol/http/reference'
42
42
 
43
43
  reference = Protocol::HTTP::Reference.new("/search", q: 'kittens')
@@ -48,7 +48,7 @@ reference.to_s
48
48
 
49
49
  ### URL
50
50
 
51
- ```ruby
51
+ ``` ruby
52
52
  require 'protocol/http/url'
53
53
 
54
54
  reference = Protocol::HTTP::Reference.parse("/search?q=kittens")
@@ -59,17 +59,17 @@ parameters = Protocol::HTTP::URL.decode(reference.query_string)
59
59
 
60
60
  ## Contributing
61
61
 
62
- 1. Fork it
63
- 2. Create your feature branch (`git checkout -b my-new-feature`)
64
- 3. Commit your changes (`git commit -am 'Add some feature'`)
65
- 4. Push to the branch (`git push origin my-new-feature`)
66
- 5. Create new Pull Request
62
+ 1. Fork it
63
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
64
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
65
+ 4. Push to the branch (`git push origin my-new-feature`)
66
+ 5. Create new Pull Request
67
67
 
68
68
  ## License
69
69
 
70
70
  Released under the MIT license.
71
71
 
72
- Copyright, 2019, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
72
+ Copyright, 2019, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
73
73
 
74
74
  Permission is hereby granted, free of charge, to any person obtaining a copy
75
75
  of this software and associated documentation files (the "Software"), to deal
data/bake.rb ADDED
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ def external
4
+ require 'bundler'
5
+
6
+ Bundler.with_unbundled_env do
7
+ clone_and_test("protocol-http1")
8
+ clone_and_test("protocol-http2")
9
+ clone_and_test("async-websocket")
10
+ clone_and_test("async-http")
11
+ clone_and_test("async-rest")
12
+ clone_and_test("falcon")
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def clone_and_test(name)
19
+ path = "external/#{name}"
20
+
21
+ unless File.exist?(path)
22
+ system("git", "clone", "https://git@github.com/socketry/#{name}", path)
23
+ end
24
+
25
+ gemfile = [
26
+ File.join(path, "gems.rb"),
27
+ File.join(path, "Gemfile"),
28
+ ].find{|path| File.exist?(path)}
29
+
30
+ system("git", "checkout", "-f", File.basename(gemfile), chdir: path)
31
+
32
+ File.open(gemfile, "a") do |file|
33
+ file.puts('', 'gem "protocol-http", path: "../../"')
34
+ end
35
+
36
+ system("bundle install && bundle exec rspec", chdir: path)
37
+ end
@@ -5,6 +5,11 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in protocol-http.gemspec
6
6
  gemspec
7
7
 
8
+ group :maintenance, optional: true do
9
+ gem "bake-modernize"
10
+ gem "bake-bundler"
11
+ end
12
+
8
13
  group :test do
9
14
  gem 'async-io'
10
15
  gem 'async-rspec'
@@ -22,8 +22,6 @@
22
22
 
23
23
  require_relative 'readable'
24
24
 
25
- require 'digest/sha2'
26
-
27
25
  module Protocol
28
26
  module HTTP
29
27
  module Body
@@ -61,14 +59,7 @@ module Protocol
61
59
  @digest = nil
62
60
  end
63
61
 
64
- def digest
65
- if @digest.nil?
66
- @digest = Digest::SHA256.new
67
- @chunks.each{|chunk| @digest.update(chunk)}
68
- end
69
-
70
- @digest.hexdigest
71
- end
62
+ attr :chunks
72
63
 
73
64
  def finish
74
65
  self
@@ -82,6 +73,11 @@ module Protocol
82
73
  @index >= @chunks.length
83
74
  end
84
75
 
76
+ # A buffered response is always ready.
77
+ def ready?
78
+ true
79
+ end
80
+
85
81
  def read
86
82
  if chunk = @chunks[@index]
87
83
  @index += 1
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
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_relative 'wrapper'
24
+
25
+ require 'digest/sha2'
26
+
27
+ module Protocol
28
+ module HTTP
29
+ module Body
30
+ # Invokes a callback once the body has finished reading.
31
+ class Digestable < Wrapper
32
+ def self.wrap(message, digest = Digest::SHA256.new, &block)
33
+ if body = message&.body and !body.empty?
34
+ message.body = self.new(message.body, digest, block)
35
+ end
36
+ end
37
+
38
+ def initialize(body, digest = Digest::SHA256.new, callback = nil)
39
+ super(body)
40
+
41
+ @digest = digest
42
+ @callback = callback
43
+ end
44
+
45
+ def digest
46
+ @digest
47
+ end
48
+
49
+ def etag
50
+ @digest.hexdigest.dump
51
+ end
52
+
53
+ def read
54
+ if chunk = super
55
+ @digest.update(chunk)
56
+
57
+ return chunk
58
+ else
59
+ @callback&.call(self)
60
+
61
+ return nil
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -65,6 +65,10 @@ module Protocol
65
65
  @remaining == 0
66
66
  end
67
67
 
68
+ def ready?
69
+ true
70
+ end
71
+
68
72
  def rewind
69
73
  @file.seek(@offset)
70
74
  end
@@ -42,6 +42,10 @@ module Protocol
42
42
  true
43
43
  end
44
44
 
45
+ def ready?
46
+ true
47
+ end
48
+
45
49
  def length
46
50
  @length
47
51
  end
@@ -44,6 +44,13 @@ module Protocol
44
44
  false
45
45
  end
46
46
 
47
+ # Whether calling read will block.
48
+ # We prefer pessimistic implementation, and thus default to `false`.
49
+ # @return [Boolean]
50
+ def ready?
51
+ false
52
+ end
53
+
47
54
  def length
48
55
  nil
49
56
  end
@@ -33,22 +33,16 @@ module Protocol
33
33
 
34
34
  @chunks = []
35
35
  @index = 0
36
- @digest = nil
37
- end
38
-
39
- def digest
40
- if @digest.nil?
41
- @digest = Digest::SHA256.new
42
- @chunks.each{|chunk| @digest.update(chunk)}
43
- end
44
-
45
- @digest.hexdigest
46
36
  end
47
37
 
48
38
  def empty?
49
39
  (@index >= @chunks.size) && super
50
40
  end
51
41
 
42
+ def ready?
43
+ (@index < @chunks.size) || super
44
+ end
45
+
52
46
  # A rewindable body wraps some other body. Convert it to a buffered body
53
47
  def buffered
54
48
  Buffered.new(@chunks)
@@ -61,7 +55,6 @@ module Protocol
61
55
  else
62
56
  if chunk = super
63
57
  @chunks << chunk
64
- @digest&.update(chunk)
65
58
  @index += 1
66
59
  end
67
60
  end
@@ -27,6 +27,12 @@ module Protocol
27
27
  module Body
28
28
  # Wrapping body instance. Typically you'd override `#read`.
29
29
  class Wrapper < Readable
30
+ def self.wrap(message)
31
+ if body = message.body
32
+ message.body = self.new(body)
33
+ end
34
+ end
35
+
30
36
  def initialize(body)
31
37
  @body = body
32
38
  end
@@ -49,6 +55,10 @@ module Protocol
49
55
  @body.empty?
50
56
  end
51
57
 
58
+ def ready?
59
+ @body.ready?
60
+ end
61
+
52
62
  def length
53
63
  @body.length
54
64
  end
@@ -40,7 +40,7 @@ module Protocol
40
40
  URL.escape(@value)
41
41
  end
42
42
 
43
- def to_str
43
+ def to_s
44
44
  buffer = String.new.b
45
45
 
46
46
  buffer << encoded_name << '=' << encoded_value
@@ -26,21 +26,23 @@ module Protocol
26
26
  module HTTP
27
27
  module Header
28
28
  # Used for basic authorization.
29
- # @example headers.add('authorization', Authorization.new("samuel", "password"))
30
- class Authorization
31
- KEY = "Authorization"
32
-
33
- def initialize(username, password)
34
- @username = username
35
- @password = password
36
- end
37
-
38
- def encoded
39
- "#{@username}:#{@password}"
29
+ #
30
+ # ~~~ ruby
31
+ # headers.add('authorization', Authorization.basic("my_username", "my_password"))
32
+ # ~~~
33
+ class Authorization < String
34
+ # Splits the header and
35
+ # @return [Tuple(String, String)]
36
+ def credentials
37
+ self.split(/\s+/, 2)
40
38
  end
41
39
 
42
- def to_str
43
- 'Basic %s' % Base64.strict_encode64(self.encoded)
40
+ def self.basic(username, password)
41
+ encoded = "#{username}:#{password}"
42
+
43
+ self.new(
44
+ "Basic #{Base64.strict_encode64(encoded)}"
45
+ )
44
46
  end
45
47
  end
46
48
  end
@@ -20,8 +20,6 @@
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 'split'
24
-
25
23
  module Protocol
26
24
  module HTTP
27
25
  module Header
@@ -28,6 +28,7 @@ require_relative 'header/cache_control'
28
28
  require_relative 'header/etag'
29
29
  require_relative 'header/etags'
30
30
  require_relative 'header/vary'
31
+ require_relative 'header/authorization'
31
32
 
32
33
  module Protocol
33
34
  module HTTP
@@ -35,16 +36,31 @@ module Protocol
35
36
  class Headers
36
37
  Split = Header::Split
37
38
  Multiple = Header::Multiple
39
+
38
40
  TRAILERS = 'trailers'
39
41
 
40
- # Construct an instance from a headers Array or Hash. No-op if already an instance of `Headers`.
42
+ # Construct an instance from a headers Array or Hash. No-op if already an instance of `Headers`. If the underlying array is frozen, it will be duped.
41
43
  # @return [Headers] an instance of headers.
42
44
  def self.[] headers
45
+ if headers.nil?
46
+ return self.new
47
+ end
48
+
43
49
  if headers.is_a?(self)
44
- headers
45
- else
46
- self.new(headers.to_a)
50
+ if headers.frozen?
51
+ return headers.dup
52
+ else
53
+ return headers
54
+ end
47
55
  end
56
+
57
+ fields = headers.to_a
58
+
59
+ if fields.frozen?
60
+ fields = fields.dup
61
+ end
62
+
63
+ return self.new(fields)
48
64
  end
49
65
 
50
66
  def initialize(fields = [], indexed = nil)
@@ -53,7 +69,6 @@ module Protocol
53
69
 
54
70
  # Marks where trailers start in the @fields array.
55
71
  @tail = nil
56
- @deferred = []
57
72
  end
58
73
 
59
74
  def initialize_dup(other)
@@ -61,47 +76,53 @@ module Protocol
61
76
 
62
77
  @fields = @fields.dup
63
78
  @indexed = @indexed.dup
64
- @deferred = @deferred.dup
65
79
  end
66
80
 
67
81
  def clear
68
82
  @fields.clear
69
83
  @indexed = nil
70
84
  @tail = nil
71
- @deferred.clear
72
85
  end
73
86
 
74
- # An array of `[key, value]` pairs.
75
- attr :fields
87
+ # Flatten trailers into the headers.
88
+ def flatten!
89
+ if @tail
90
+ self.delete(TRAILERS)
91
+ @tail = nil
92
+ end
93
+
94
+ return self
95
+ end
76
96
 
77
- # Mark the subsequent headers as trailers.
78
- def trailers!
79
- @tail ||= @fields.size
97
+ def flatten
98
+ self.dup.flatten!
80
99
  end
81
100
 
101
+ # An array of `[key, value]` pairs.
102
+ attr :fields
103
+
82
104
  # @return the trailers if there are any.
83
105
  def trailers?
84
106
  @tail != nil
85
107
  end
86
108
 
87
- def flatten!
88
- unless @deferred.empty?
89
- @tail ||= @fields.size
90
-
91
- @deferred.each do |key, value|
92
- self.add(key, value.call)
93
- end
109
+ # Record the current headers, and prepare to receive trailers.
110
+ def trailers!(&block)
111
+ return nil unless self.include?(TRAILERS)
112
+
113
+ @tail ||= @fields.size
114
+
115
+ return to_enum(:trailers!) unless block_given?
116
+
117
+ if @tail
118
+ @fields.drop(@tail).each(&block)
94
119
  end
95
120
  end
96
121
 
97
- # Enumerate all trailers, including evaluating all deferred headers.
122
+ # Enumerate all trailers, if there are any.
98
123
  def trailers(&block)
99
- return nil unless self.include?(TRAILERS)
100
-
101
124
  return to_enum(:trailers) unless block_given?
102
125
 
103
- flatten!
104
-
105
126
  if @tail
106
127
  @fields.drop(@tail).each(&block)
107
128
  end
@@ -110,18 +131,9 @@ module Protocol
110
131
  def freeze
111
132
  return if frozen?
112
133
 
113
- # Ensure all deferred headers are evaluated:
114
- self.flatten!
115
-
116
134
  # Ensure @indexed is generated:
117
135
  self.to_h
118
136
 
119
- # Remove all trailers:
120
- self.delete(TRAILERS)
121
-
122
- # No longer has stateful trailers:
123
- @tail = nil
124
-
125
137
  @fields.freeze
126
138
  @indexed.freeze
127
139
 
@@ -159,16 +171,11 @@ module Protocol
159
171
  end
160
172
 
161
173
  # Add the specified header key value pair.
174
+ #
162
175
  # @param key [String] the header key.
163
176
  # @param value [String] the header value to assign.
164
- # @yield dynamically generate the value when used as a trailer.
165
- def add(key, value = nil, &block)
166
- if block_given?
167
- @deferred << [key, block]
168
- self[TRAILERS] = key
169
- else
170
- self[key] = value
171
- end
177
+ def add(key, value)
178
+ self[key] = value
172
179
  end
173
180
 
174
181
  # Set the specified header key to the specified value, replacing any existing header keys with the same name.
@@ -211,8 +218,6 @@ module Protocol
211
218
  'user-agent' => false,
212
219
  'referer' => false,
213
220
  'host' => false,
214
- 'authorization' => false,
215
- 'proxy-authorization' => false,
216
221
  'if-modified-since' => false,
217
222
  'if-unmodified-since' => false,
218
223
  'from' => false,
@@ -228,6 +233,10 @@ module Protocol
228
233
  'via' => Split,
229
234
  'x-forwarded-for' => Split,
230
235
 
236
+ # Authorization headers:
237
+ 'authorization' => Header::Authorization,
238
+ 'proxy-authorization' => Header::Authorization,
239
+
231
240
  # Cache validations:
232
241
  'etag' => Header::ETag,
233
242
  'if-match' => Header::ETags,
@@ -51,9 +51,9 @@ module Protocol
51
51
 
52
52
  # Use Methods.constants to get all constants.
53
53
  self.each do |name, value|
54
- define_method(name.downcase) do |location, headers = [], body = nil|
54
+ define_method(name.downcase) do |location, headers = nil, body = nil|
55
55
  self.call(
56
- Request[value, location.to_str, Headers[headers], body]
56
+ Request[value, location.to_s, Headers[headers], body]
57
57
  )
58
58
  end
59
59
  end
@@ -28,6 +28,14 @@ require_relative 'response'
28
28
  module Protocol
29
29
  module HTTP
30
30
  class Middleware < Methods
31
+ # Convert a block to a middleware delegate.
32
+ def self.for(&block)
33
+ def block.close
34
+ end
35
+
36
+ return self.new(block)
37
+ end
38
+
31
39
  def initialize(delegate)
32
40
  @delegate = delegate
33
41
  end
@@ -110,12 +110,10 @@ module Protocol
110
110
  return buffer
111
111
  end
112
112
 
113
- def to_str
113
+ def to_s
114
114
  append(String.new)
115
115
  end
116
116
 
117
- alias to_s to_str
118
-
119
117
  # Merges two references as specified by RFC2396, similar to `URI.join`.
120
118
  def + other
121
119
  other = self.class[other]
@@ -28,7 +28,7 @@ module Protocol
28
28
  class Request
29
29
  prepend Body::Reader
30
30
 
31
- def initialize(scheme = nil, authority = nil, method = nil, path = nil, version = nil, headers = [], body = nil, protocol = nil)
31
+ def initialize(scheme = nil, authority = nil, method = nil, path = nil, version = nil, headers = Headers.new, body = nil, protocol = nil)
32
32
  @scheme = scheme
33
33
  @authority = authority
34
34
  @method = method
@@ -48,12 +48,6 @@ module Protocol
48
48
  attr_accessor :body
49
49
  attr_accessor :protocol
50
50
 
51
- def trailers
52
- if @headers.respond_to?(:trailers)
53
- @headers.trailers
54
- end
55
- end
56
-
57
51
  # Send the request to the given connection.
58
52
  def call(connection)
59
53
  connection.call(self)
@@ -69,6 +63,7 @@ module Protocol
69
63
 
70
64
  def self.[](method, path, headers, body)
71
65
  body = Body::Buffered.wrap(body)
66
+ headers = ::Protocol::HTTP::Headers[headers]
72
67
 
73
68
  self.new(nil, nil, method, path, nil, headers, body)
74
69
  end
@@ -28,7 +28,7 @@ module Protocol
28
28
  class Response
29
29
  prepend Body::Reader
30
30
 
31
- def initialize(version = nil, status = 200, headers = [], body = nil, protocol = nil)
31
+ def initialize(version = nil, status = 200, headers = Headers.new, body = nil, protocol = nil)
32
32
  @version = version
33
33
  @status = status
34
34
  @headers = headers
@@ -42,12 +42,6 @@ module Protocol
42
42
  attr_accessor :body
43
43
  attr_accessor :protocol
44
44
 
45
- def trailers
46
- if @headers.respond_to?(:trailers)
47
- @headers.trailers
48
- end
49
- end
50
-
51
45
  def hijack?
52
46
  false
53
47
  end
@@ -88,8 +82,9 @@ module Protocol
88
82
  @status == 500
89
83
  end
90
84
 
91
- def self.[](status, headers = [], body = nil, protocol = nil)
85
+ def self.[](status, headers = nil, body = nil, protocol = nil)
92
86
  body = Body::Buffered.wrap(body)
87
+ headers = ::Protocol::HTTP::Headers[headers]
93
88
 
94
89
  self.new(nil, status, headers, body, protocol)
95
90
  end
@@ -22,6 +22,6 @@
22
22
 
23
23
  module Protocol
24
24
  module HTTP
25
- VERSION = "0.16.3"
25
+ VERSION = "0.20.1"
26
26
  end
27
27
  end
@@ -15,12 +15,11 @@ Gem::Specification.new do |spec|
15
15
  f.match(%r{^(test|spec|features)/})
16
16
  end
17
17
 
18
- spec.required_ruby_version = '~> 2.5'
18
+ spec.required_ruby_version = '>= 2.5'
19
19
 
20
20
  spec.require_paths = ["lib"]
21
21
 
22
22
  spec.add_development_dependency "covered"
23
23
  spec.add_development_dependency "bundler"
24
- spec.add_development_dependency "bake-bundler"
25
24
  spec.add_development_dependency "rspec"
26
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protocol-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.3
4
+ version: 0.20.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-06 00:00:00.000000000 Z
11
+ date: 2020-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: covered
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: bake-bundler
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: rspec
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,7 +52,7 @@ dependencies:
66
52
  - - ">="
67
53
  - !ruby/object:Gem::Version
68
54
  version: '0'
69
- description:
55
+ description:
70
56
  email:
71
57
  - samuel.williams@oriontransfer.co.nz
72
58
  executables: []
@@ -74,15 +60,17 @@ extensions: []
74
60
  extra_rdoc_files: []
75
61
  files:
76
62
  - ".editorconfig"
63
+ - ".github/workflows/development.yml"
77
64
  - ".gitignore"
78
65
  - ".rspec"
79
- - ".travis.yml"
80
- - Gemfile
81
66
  - README.md
67
+ - bake.rb
68
+ - gems.rb
82
69
  - lib/protocol/http.rb
83
70
  - lib/protocol/http/accept_encoding.rb
84
71
  - lib/protocol/http/body/buffered.rb
85
72
  - lib/protocol/http/body/deflate.rb
73
+ - lib/protocol/http/body/digestable.rb
86
74
  - lib/protocol/http/body/file.rb
87
75
  - lib/protocol/http/body/head.rb
88
76
  - lib/protocol/http/body/inflate.rb
@@ -118,13 +106,13 @@ homepage: https://github.com/socketry/protocol-http
118
106
  licenses:
119
107
  - MIT
120
108
  metadata: {}
121
- post_install_message:
109
+ post_install_message:
122
110
  rdoc_options: []
123
111
  require_paths:
124
112
  - lib
125
113
  required_ruby_version: !ruby/object:Gem::Requirement
126
114
  requirements:
127
- - - "~>"
115
+ - - ">="
128
116
  - !ruby/object:Gem::Version
129
117
  version: '2.5'
130
118
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -133,8 +121,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
121
  - !ruby/object:Gem::Version
134
122
  version: '0'
135
123
  requirements: []
136
- rubygems_version: 3.1.2
137
- signing_key:
124
+ rubygems_version: 3.0.3
125
+ signing_key:
138
126
  specification_version: 4
139
127
  summary: Provides abstractions to handle HTTP protocols.
140
128
  test_files: []
@@ -1,22 +0,0 @@
1
- language: ruby
2
- dist: xenial
3
- cache: bundler
4
-
5
- script: bundle exec rspec
6
-
7
- matrix:
8
- include:
9
- - rvm: 2.5
10
- - rvm: 2.6
11
- - rvm: 2.7
12
- - rvm: 2.6
13
- env: COVERAGE=PartialSummary,Coveralls
14
- - rvm: 2.7
15
- - rvm: truffleruby
16
- - rvm: jruby-head
17
- env: JRUBY_OPTS="--debug -X+O"
18
- - rvm: ruby-head
19
- allow_failures:
20
- - rvm: truffleruby
21
- - rvm: ruby-head
22
- - rvm: jruby-head