protocol-http 0.20.1 → 0.22.3

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: 5f14e6a0192840efd07d2ba8e8e3a8bd9312eb5fa8b976f1e12baaf14ee49696
4
- data.tar.gz: 2548bc880b20a5e162cad7fdcbbece9a0cdfae429861b8a5f1bbd68cf904cb9b
3
+ metadata.gz: ae0619e142c0e086b69d661ba9ae444330f52170bec2baff74241c7f49a906ba
4
+ data.tar.gz: 6b9b328ea74065aa14d07ba55d7f16bb5890b8df98162991cd17e92050bfaf4d
5
5
  SHA512:
6
- metadata.gz: b1e6692c96818aed1ed11c02b976169598ba9df9afc1f73109745168f62d85a75b6bf9abe530cac1daa39a3a40b5a815e06280581d8912b6c32f7e488f35fac0
7
- data.tar.gz: 747e961c97c027258a46fbbd70f9845eead55d0c3dc6d108dae0083b99693bf5384f3868c9d50e5270d06337341879d265dc362a7907a16d22ecca73149e8223
6
+ metadata.gz: 216e6bb9c9b9f399c12b4f1e8c49f62ea2d9f2529e16249554159ab09b64d6eb84630235d2ad8c01344881509f9c4920aaa8c0ba5c5e0894d928623a2c43ea0b
7
+ data.tar.gz: 3faf9365436e8b233047ee3b5a7c4393de83e31ca06c5b195e1ac7e97751b619bffaebd52c9351e02697fe9669b2f9a32514a8abdc3f0d0df5594a296aaddd39
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
3
+ # Copyright, 2020, 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
6
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -25,8 +25,8 @@ require_relative 'wrapper'
25
25
  module Protocol
26
26
  module HTTP
27
27
  module Body
28
- # Invokes a callback once the body has finished reading.
29
- class Streamable < Wrapper
28
+ # Invokes a callback once the body has completed, either successfully or due to an error.
29
+ class Completable < Wrapper
30
30
  def self.wrap(message, &block)
31
31
  if body = message&.body and !body.empty?
32
32
  message.body = self.new(message.body, block)
@@ -60,6 +60,21 @@ module Protocol
60
60
  nil
61
61
  end
62
62
 
63
+ # Should the internal mechanism prefer to use {call}?
64
+ # @returns [Boolean]
65
+ def stream?
66
+ false
67
+ end
68
+
69
+ # Write the body to the given stream.
70
+ def call(stream)
71
+ while chunk = self.read
72
+ stream.write(chunk)
73
+ end
74
+ ensure
75
+ stream.close($!)
76
+ end
77
+
63
78
  # Read all remaining chunks into a buffered body and close the underlying input.
64
79
  def finish
65
80
  # Internally, this invokes `self.each` which then invokes `self.close`.
@@ -71,6 +71,14 @@ module Protocol
71
71
  def inspect
72
72
  @body.inspect
73
73
  end
74
+
75
+ def stream?
76
+ @body.stream?
77
+ end
78
+
79
+ def call(stream)
80
+ @body.call(stream)
81
+ end
74
82
  end
75
83
  end
76
84
  end
@@ -32,6 +32,10 @@ module Protocol
32
32
  @directives = directives
33
33
  end
34
34
 
35
+ attr :name
36
+ attr :value
37
+ attr :directives
38
+
35
39
  def encoded_name
36
40
  URL.escape(@name)
37
41
  end
@@ -61,11 +65,11 @@ module Protocol
61
65
  return buffer
62
66
  end
63
67
 
64
- def self.parse string
65
- head, *options = string.split(/\s*;\s*/)
68
+ def self.parse(string)
69
+ head, *directives = string.split(/\s*;\s*/)
66
70
 
67
71
  key, value = head.split('=')
68
- directives.collect{|directive| directive.split('=', 2)}.to_h
72
+ directives = self.parse_directives(directives)
69
73
 
70
74
  self.new(
71
75
  URI.decode(key),
@@ -73,6 +77,13 @@ module Protocol
73
77
  directives,
74
78
  )
75
79
  end
80
+
81
+ def self.parse_directives(strings)
82
+ strings.collect do |string|
83
+ key, value = string.split('=', 2)
84
+ [key, value || true]
85
+ end.to_h
86
+ end
76
87
  end
77
88
  end
78
89
  end
@@ -37,7 +37,7 @@ module Protocol
37
37
  Split = Header::Split
38
38
  Multiple = Header::Multiple
39
39
 
40
- TRAILERS = 'trailers'
40
+ TRAILER = 'trailer'
41
41
 
42
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.
43
43
  # @return [Headers] an instance of headers.
@@ -67,7 +67,7 @@ module Protocol
67
67
  @fields = fields
68
68
  @indexed = indexed
69
69
 
70
- # Marks where trailers start in the @fields array.
70
+ # Marks where trailer start in the @fields array.
71
71
  @tail = nil
72
72
  end
73
73
 
@@ -84,10 +84,10 @@ module Protocol
84
84
  @tail = nil
85
85
  end
86
86
 
87
- # Flatten trailers into the headers.
87
+ # Flatten trailer into the headers.
88
88
  def flatten!
89
89
  if @tail
90
- self.delete(TRAILERS)
90
+ self.delete(TRAILER)
91
91
  @tail = nil
92
92
  end
93
93
 
@@ -101,27 +101,27 @@ module Protocol
101
101
  # An array of `[key, value]` pairs.
102
102
  attr :fields
103
103
 
104
- # @return the trailers if there are any.
105
- def trailers?
104
+ # @return the trailer if there are any.
105
+ def trailer?
106
106
  @tail != nil
107
107
  end
108
108
 
109
- # Record the current headers, and prepare to receive trailers.
110
- def trailers!(&block)
111
- return nil unless self.include?(TRAILERS)
109
+ # Record the current headers, and prepare to receive trailer.
110
+ def trailer!(&block)
111
+ return nil unless self.include?(TRAILER)
112
112
 
113
113
  @tail ||= @fields.size
114
114
 
115
- return to_enum(:trailers!) unless block_given?
115
+ return to_enum(:trailer!) unless block_given?
116
116
 
117
117
  if @tail
118
118
  @fields.drop(@tail).each(&block)
119
119
  end
120
120
  end
121
121
 
122
- # Enumerate all trailers, if there are any.
123
- def trailers(&block)
124
- return to_enum(:trailers) unless block_given?
122
+ # Enumerate all headers in the trailer, if there are any.
123
+ def trailer(&block)
124
+ return to_enum(:trailer) unless block_given?
125
125
 
126
126
  if @tail
127
127
  @fields.drop(@tail).each(&block)
@@ -35,17 +35,17 @@ module Protocol
35
35
  end
36
36
 
37
37
  class Builder
38
- def initialize(default_app = NotFound, &block)
38
+ def initialize(default_app = NotFound)
39
39
  @use = []
40
40
  @app = default_app
41
-
42
- instance_eval(&block) if block_given?
43
41
  end
44
42
 
45
- def use(middleware, *args, &block)
46
- @use << proc {|app| middleware.new(app, *args, &block)}
43
+ def use(middleware, *arguments, &block)
44
+ @use << proc {|app| middleware.new(app, *arguments, &block)}
47
45
  end
48
46
 
47
+ ruby2_keywords(:use) if respond_to?(:ruby2_keywords, true)
48
+
49
49
  def run(app)
50
50
  @app = app
51
51
  end
@@ -56,7 +56,11 @@ module Protocol
56
56
  end
57
57
 
58
58
  def self.build(&block)
59
- Builder.new(&block).to_app
59
+ builder = Builder.new
60
+
61
+ builder.instance_eval(&block)
62
+
63
+ return builder.to_app
60
64
  end
61
65
  end
62
66
  end
@@ -22,6 +22,6 @@
22
22
 
23
23
  module Protocol
24
24
  module HTTP
25
- VERSION = "0.20.1"
25
+ VERSION = "0.22.3"
26
26
  end
27
27
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protocol-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.1
4
+ version: 0.22.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-19 00:00:00.000000000 Z
11
+ date: 2021-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: covered
14
+ name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: covered
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -54,21 +54,14 @@ dependencies:
54
54
  version: '0'
55
55
  description:
56
56
  email:
57
- - samuel.williams@oriontransfer.co.nz
58
57
  executables: []
59
58
  extensions: []
60
59
  extra_rdoc_files: []
61
60
  files:
62
- - ".editorconfig"
63
- - ".github/workflows/development.yml"
64
- - ".gitignore"
65
- - ".rspec"
66
- - README.md
67
- - bake.rb
68
- - gems.rb
69
61
  - lib/protocol/http.rb
70
62
  - lib/protocol/http/accept_encoding.rb
71
63
  - lib/protocol/http/body/buffered.rb
64
+ - lib/protocol/http/body/completable.rb
72
65
  - lib/protocol/http/body/deflate.rb
73
66
  - lib/protocol/http/body/digestable.rb
74
67
  - lib/protocol/http/body/file.rb
@@ -78,7 +71,6 @@ files:
78
71
  - lib/protocol/http/body/reader.rb
79
72
  - lib/protocol/http/body/rewindable.rb
80
73
  - lib/protocol/http/body/stream.rb
81
- - lib/protocol/http/body/streamable.rb
82
74
  - lib/protocol/http/body/wrapper.rb
83
75
  - lib/protocol/http/content_encoding.rb
84
76
  - lib/protocol/http/cookie.rb
@@ -101,7 +93,6 @@ files:
101
93
  - lib/protocol/http/response.rb
102
94
  - lib/protocol/http/url.rb
103
95
  - lib/protocol/http/version.rb
104
- - protocol-http.gemspec
105
96
  homepage: https://github.com/socketry/protocol-http
106
97
  licenses:
107
98
  - MIT
@@ -121,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
112
  - !ruby/object:Gem::Version
122
113
  version: '0'
123
114
  requirements: []
124
- rubygems_version: 3.0.3
115
+ rubygems_version: 3.1.6
125
116
  signing_key:
126
117
  specification_version: 4
127
118
  summary: Provides abstractions to handle HTTP protocols.
data/.editorconfig DELETED
@@ -1,5 +0,0 @@
1
- root = true
2
-
3
- [*]
4
- indent_style = tab
5
- indent_size = 2
@@ -1,44 +0,0 @@
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 DELETED
@@ -1,14 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- /external/
10
-
11
- # rspec failure tracking
12
- .rspec_status
13
- /gems.locked
14
- .covered.db
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --warnings
3
- --require spec_helper
data/README.md DELETED
@@ -1,90 +0,0 @@
1
- # Protocol::HTTP
2
-
3
- Provides abstractions for working with the HTTP protocol.
4
-
5
- [![Development Status](https://github.com/socketry/protocol-http/workflows/Development/badge.svg)](https://github.com/socketry/protocol-http/actions?workflow=Development)
6
-
7
- ## Installation
8
-
9
- Add this line to your application's Gemfile:
10
-
11
- ``` ruby
12
- gem 'protocol-http'
13
- ```
14
-
15
- And then execute:
16
-
17
- $ bundle
18
-
19
- Or install it yourself as:
20
-
21
- $ gem install protocol-http
22
-
23
- ## Usage
24
-
25
- ### Headers
26
-
27
- ``` ruby
28
- require 'protocol/http/headers'
29
-
30
- headers = Protocol::HTTP::Headers.new
31
-
32
- headers['Content-Type'] = "image/jpeg"
33
-
34
- headers['content-type']
35
- # => "image/jpeg"
36
- ```
37
-
38
- ### Reference
39
-
40
- ``` ruby
41
- require 'protocol/http/reference'
42
-
43
- reference = Protocol::HTTP::Reference.new("/search", q: 'kittens')
44
-
45
- reference.to_s
46
- # => "/search?q=kittens"
47
- ```
48
-
49
- ### URL
50
-
51
- ``` ruby
52
- require 'protocol/http/url'
53
-
54
- reference = Protocol::HTTP::Reference.parse("/search?q=kittens")
55
-
56
- parameters = Protocol::HTTP::URL.decode(reference.query_string)
57
- # => {"q"=>"kittens"}
58
- ```
59
-
60
- ## Contributing
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
67
-
68
- ## License
69
-
70
- Released under the MIT license.
71
-
72
- Copyright, 2019, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
73
-
74
- Permission is hereby granted, free of charge, to any person obtaining a copy
75
- of this software and associated documentation files (the "Software"), to deal
76
- in the Software without restriction, including without limitation the rights
77
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
78
- copies of the Software, and to permit persons to whom the Software is
79
- furnished to do so, subject to the following conditions:
80
-
81
- The above copyright notice and this permission notice shall be included in
82
- all copies or substantial portions of the Software.
83
-
84
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
85
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
86
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
87
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
88
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
89
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
90
- THE SOFTWARE.
data/bake.rb DELETED
@@ -1,37 +0,0 @@
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
data/gems.rb DELETED
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source "https://rubygems.org"
4
-
5
- # Specify your gem's dependencies in protocol-http.gemspec
6
- gemspec
7
-
8
- group :maintenance, optional: true do
9
- gem "bake-modernize"
10
- gem "bake-bundler"
11
- end
12
-
13
- group :test do
14
- gem 'async-io'
15
- gem 'async-rspec'
16
- end
@@ -1,25 +0,0 @@
1
-
2
- require_relative "lib/protocol/http/version"
3
-
4
- Gem::Specification.new do |spec|
5
- spec.name = "protocol-http"
6
- spec.version = Protocol::HTTP::VERSION
7
- spec.authors = ["Samuel Williams"]
8
- spec.email = ["samuel.williams@oriontransfer.co.nz"]
9
-
10
- spec.summary = "Provides abstractions to handle HTTP protocols."
11
- spec.homepage = "https://github.com/socketry/protocol-http"
12
- spec.license = "MIT"
13
-
14
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
15
- f.match(%r{^(test|spec|features)/})
16
- end
17
-
18
- spec.required_ruby_version = '>= 2.5'
19
-
20
- spec.require_paths = ["lib"]
21
-
22
- spec.add_development_dependency "covered"
23
- spec.add_development_dependency "bundler"
24
- spec.add_development_dependency "rspec"
25
- end