protocol-http 0.16.3 → 0.20.1

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: 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