protocol-http1 0.11.1 → 0.14.0
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.
Potentially problematic release.
This version of protocol-http1 might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/protocol/http1/body/chunked.rb +3 -4
- data/lib/protocol/http1/connection.rb +20 -11
- data/lib/protocol/http1/version.rb +1 -1
- metadata +12 -35
- data/.editorconfig +0 -6
- data/.gitignore +0 -13
- data/.rspec +0 -3
- data/.travis.yml +0 -21
- data/Gemfile +0 -6
- data/README.md +0 -92
- data/examples/http1/request.rb +0 -39
- data/protocol-http1.gemspec +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 972a37dfc7d2658f54c796f85054bec8bdb2827e595a42b874d276d320015aa7
|
4
|
+
data.tar.gz: d50ec1a04e61727cb104e7d1224e90bd8c4dc63f41e71854b2376463456ee8ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d19773f15978c311cfba29096fdf6026279c04ee458db6492811368f9251cd54cb697db12f06f748d3130308cf91341a0377933a8c57f07dfceb805380212da1
|
7
|
+
data.tar.gz: 2b804b15e98404899673468bc63f35adf3417d0e6a31e54e3cb77d262c65918242b062de9fa72e302c5b99403482ff1b8f5ec3ce43bf0bb43215d21d0dd91cac
|
@@ -26,7 +26,6 @@ module Protocol
|
|
26
26
|
module HTTP1
|
27
27
|
module Body
|
28
28
|
class Chunked < HTTP::Body::Readable
|
29
|
-
TRAILERS = 'trailers'
|
30
29
|
CRLF = "\r\n"
|
31
30
|
|
32
31
|
def initialize(stream, headers)
|
@@ -62,7 +61,7 @@ module Protocol
|
|
62
61
|
if length == 0
|
63
62
|
@finished = true
|
64
63
|
|
65
|
-
|
64
|
+
read_trailer
|
66
65
|
|
67
66
|
return nil
|
68
67
|
end
|
@@ -89,9 +88,9 @@ module Protocol
|
|
89
88
|
@stream.gets(CRLF, chomp: true)
|
90
89
|
end
|
91
90
|
|
92
|
-
def
|
91
|
+
def read_trailer
|
93
92
|
while line = read_line
|
94
|
-
# Empty line indicates end of
|
93
|
+
# Empty line indicates end of trailer:
|
95
94
|
break if line.empty?
|
96
95
|
|
97
96
|
if match = line.match(HEADER)
|
@@ -281,14 +281,17 @@ module Protocol
|
|
281
281
|
|
282
282
|
def write_fixed_length_body(body, length, head)
|
283
283
|
@stream.write("content-length: #{length}\r\n\r\n")
|
284
|
-
@stream.flush
|
285
284
|
|
286
285
|
if head
|
286
|
+
@stream.flush
|
287
|
+
|
287
288
|
body.close
|
288
289
|
|
289
290
|
return
|
290
291
|
end
|
291
292
|
|
293
|
+
@stream.flush unless body.ready?
|
294
|
+
|
292
295
|
chunk_length = 0
|
293
296
|
body.each do |chunk|
|
294
297
|
chunk_length += chunk.bytesize
|
@@ -298,6 +301,7 @@ module Protocol
|
|
298
301
|
end
|
299
302
|
|
300
303
|
@stream.write(chunk)
|
304
|
+
@stream.flush unless body.ready?
|
301
305
|
end
|
302
306
|
|
303
307
|
@stream.flush
|
@@ -307,28 +311,32 @@ module Protocol
|
|
307
311
|
end
|
308
312
|
end
|
309
313
|
|
310
|
-
def write_chunked_body(body, head,
|
314
|
+
def write_chunked_body(body, head, trailer = nil)
|
311
315
|
@stream.write("transfer-encoding: chunked\r\n\r\n")
|
312
|
-
@stream.flush
|
313
316
|
|
314
317
|
if head
|
318
|
+
@stream.flush
|
319
|
+
|
315
320
|
body.close
|
316
321
|
|
317
322
|
return
|
318
323
|
end
|
319
324
|
|
325
|
+
@stream.flush unless body.ready?
|
326
|
+
|
320
327
|
body.each do |chunk|
|
321
328
|
next if chunk.size == 0
|
322
329
|
|
323
330
|
@stream.write("#{chunk.bytesize.to_s(16).upcase}\r\n")
|
324
331
|
@stream.write(chunk)
|
325
332
|
@stream.write(CRLF)
|
326
|
-
|
333
|
+
|
334
|
+
@stream.flush unless body.ready?
|
327
335
|
end
|
328
336
|
|
329
|
-
if
|
337
|
+
if trailer
|
330
338
|
@stream.write("0\r\n")
|
331
|
-
write_headers(
|
339
|
+
write_headers(trailer)
|
332
340
|
@stream.write("\r\n")
|
333
341
|
else
|
334
342
|
@stream.write("0\r\n\r\n")
|
@@ -342,25 +350,26 @@ module Protocol
|
|
342
350
|
@persistent = false
|
343
351
|
|
344
352
|
@stream.write("\r\n")
|
345
|
-
@stream.flush
|
353
|
+
@stream.flush unless body.ready?
|
346
354
|
|
347
355
|
if head
|
348
356
|
body.close
|
349
357
|
else
|
350
358
|
body.each do |chunk|
|
351
359
|
@stream.write(chunk)
|
352
|
-
|
360
|
+
|
361
|
+
@stream.flush unless body.ready?
|
353
362
|
end
|
354
363
|
end
|
355
364
|
|
356
365
|
@stream.close_write
|
357
366
|
end
|
358
367
|
|
359
|
-
def write_body(version, body, head = false,
|
368
|
+
def write_body(version, body, head = false, trailer = nil)
|
360
369
|
if body.nil?
|
361
370
|
write_connection_header(version)
|
362
371
|
write_empty_body(body)
|
363
|
-
elsif length = body.length and
|
372
|
+
elsif length = body.length and trailer.nil?
|
364
373
|
write_connection_header(version)
|
365
374
|
write_fixed_length_body(body, length, head)
|
366
375
|
elsif body.empty?
|
@@ -370,7 +379,7 @@ module Protocol
|
|
370
379
|
elsif @persistent and version == HTTP11
|
371
380
|
write_connection_header(version)
|
372
381
|
# We specifically ensure that non-persistent connections do not use chunked response, so that hijacking works as expected.
|
373
|
-
write_chunked_body(body, head,
|
382
|
+
write_chunked_body(body, head, trailer)
|
374
383
|
else
|
375
384
|
@persistent = false
|
376
385
|
write_connection_header(version)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protocol-http1
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
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:
|
11
|
+
date: 2021-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: protocol-http
|
@@ -16,28 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.22'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: covered
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
26
|
+
version: '0.22'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: bundler
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,7 +39,7 @@ dependencies:
|
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
42
|
+
name: covered
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
45
|
- - ">="
|
@@ -81,7 +67,7 @@ dependencies:
|
|
81
67
|
- !ruby/object:Gem::Version
|
82
68
|
version: '3.0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
|
-
name: rspec-
|
70
|
+
name: rspec-files
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - "~>"
|
@@ -95,7 +81,7 @@ dependencies:
|
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '1.0'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
|
-
name: rspec-
|
84
|
+
name: rspec-memory
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
87
|
- - "~>"
|
@@ -108,20 +94,12 @@ dependencies:
|
|
108
94
|
- - "~>"
|
109
95
|
- !ruby/object:Gem::Version
|
110
96
|
version: '1.0'
|
111
|
-
description:
|
97
|
+
description:
|
112
98
|
email:
|
113
|
-
- samuel.williams@oriontransfer.co.nz
|
114
99
|
executables: []
|
115
100
|
extensions: []
|
116
101
|
extra_rdoc_files: []
|
117
102
|
files:
|
118
|
-
- ".editorconfig"
|
119
|
-
- ".gitignore"
|
120
|
-
- ".rspec"
|
121
|
-
- ".travis.yml"
|
122
|
-
- Gemfile
|
123
|
-
- README.md
|
124
|
-
- examples/http1/request.rb
|
125
103
|
- lib/protocol/http1.rb
|
126
104
|
- lib/protocol/http1/body/chunked.rb
|
127
105
|
- lib/protocol/http1/body/fixed.rb
|
@@ -130,18 +108,17 @@ files:
|
|
130
108
|
- lib/protocol/http1/error.rb
|
131
109
|
- lib/protocol/http1/reason.rb
|
132
110
|
- lib/protocol/http1/version.rb
|
133
|
-
- protocol-http1.gemspec
|
134
111
|
homepage: https://github.com/socketry/protocol-http1
|
135
112
|
licenses:
|
136
113
|
- MIT
|
137
114
|
metadata: {}
|
138
|
-
post_install_message:
|
115
|
+
post_install_message:
|
139
116
|
rdoc_options: []
|
140
117
|
require_paths:
|
141
118
|
- lib
|
142
119
|
required_ruby_version: !ruby/object:Gem::Requirement
|
143
120
|
requirements:
|
144
|
-
- - "
|
121
|
+
- - ">="
|
145
122
|
- !ruby/object:Gem::Version
|
146
123
|
version: '2.4'
|
147
124
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
@@ -151,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
128
|
version: '0'
|
152
129
|
requirements: []
|
153
130
|
rubygems_version: 3.1.2
|
154
|
-
signing_key:
|
131
|
+
signing_key:
|
155
132
|
specification_version: 4
|
156
133
|
summary: A low level implementation of the HTTP/1 protocol.
|
157
134
|
test_files: []
|
data/.editorconfig
DELETED
data/.gitignore
DELETED
data/.rspec
DELETED
data/.travis.yml
DELETED
@@ -1,21 +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: truffleruby
|
15
|
-
- rvm: jruby-head
|
16
|
-
env: JRUBY_OPTS="--debug -X+O"
|
17
|
-
- rvm: ruby-head
|
18
|
-
allow_failures:
|
19
|
-
- rvm: truffleruby
|
20
|
-
- rvm: ruby-head
|
21
|
-
- rvm: jruby-head
|
data/Gemfile
DELETED
data/README.md
DELETED
@@ -1,92 +0,0 @@
|
|
1
|
-
# Protocol::HTTP1
|
2
|
-
|
3
|
-
Provides a low-level implementation of the HTTP/1 protocol.
|
4
|
-
|
5
|
-
[](https://travis-ci.com/socketry/protocol-http1)
|
6
|
-
|
7
|
-
## Installation
|
8
|
-
|
9
|
-
Add this line to your application's Gemfile:
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
gem 'protocol-http1'
|
13
|
-
```
|
14
|
-
|
15
|
-
And then execute:
|
16
|
-
|
17
|
-
$ bundle
|
18
|
-
|
19
|
-
Or install it yourself as:
|
20
|
-
|
21
|
-
$ gem install protocol-http1
|
22
|
-
|
23
|
-
## Usage
|
24
|
-
|
25
|
-
Here is a basic HTTP/1.1 client:
|
26
|
-
|
27
|
-
```ruby
|
28
|
-
require 'async'
|
29
|
-
require 'async/io/stream'
|
30
|
-
require 'async/http/endpoint'
|
31
|
-
require 'protocol/http1/connection'
|
32
|
-
|
33
|
-
Async do
|
34
|
-
endpoint = Async::HTTP::Endpoint.parse("https://www.google.com/search?q=kittens", alpn_protocols: ["http/1.1"])
|
35
|
-
|
36
|
-
peer = endpoint.connect
|
37
|
-
|
38
|
-
puts "Connected to #{peer} #{peer.remote_address.inspect}"
|
39
|
-
|
40
|
-
# IO Buffering...
|
41
|
-
stream = Async::IO::Stream.new(peer)
|
42
|
-
client = Protocol::HTTP1::Connection.new(stream)
|
43
|
-
|
44
|
-
def client.read_line
|
45
|
-
@stream.read_until(Protocol::HTTP1::Connection::CRLF) or raise EOFError
|
46
|
-
end
|
47
|
-
|
48
|
-
puts "Writing request..."
|
49
|
-
client.write_request("www.google.com", "GET", "/search?q=kittens", "HTTP/1.1", [["Accept", "*/*"]])
|
50
|
-
client.write_body(nil)
|
51
|
-
|
52
|
-
puts "Reading response..."
|
53
|
-
response = client.read_response("GET")
|
54
|
-
|
55
|
-
puts "Got response: #{response.inspect}"
|
56
|
-
|
57
|
-
puts "Closing client..."
|
58
|
-
client.close
|
59
|
-
end
|
60
|
-
```
|
61
|
-
|
62
|
-
## Contributing
|
63
|
-
|
64
|
-
1. Fork it
|
65
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
66
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
67
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
68
|
-
5. Create new Pull Request
|
69
|
-
|
70
|
-
## License
|
71
|
-
|
72
|
-
Released under the MIT license.
|
73
|
-
|
74
|
-
Copyright, 2019, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
|
75
|
-
|
76
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
77
|
-
of this software and associated documentation files (the "Software"), to deal
|
78
|
-
in the Software without restriction, including without limitation the rights
|
79
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
80
|
-
copies of the Software, and to permit persons to whom the Software is
|
81
|
-
furnished to do so, subject to the following conditions:
|
82
|
-
|
83
|
-
The above copyright notice and this permission notice shall be included in
|
84
|
-
all copies or substantial portions of the Software.
|
85
|
-
|
86
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
87
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
88
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
89
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
90
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
91
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
92
|
-
THE SOFTWARE.
|
data/examples/http1/request.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
4
|
-
|
5
|
-
require 'async'
|
6
|
-
require 'async/io/stream'
|
7
|
-
require 'async/http/endpoint'
|
8
|
-
require 'protocol/http1/connection'
|
9
|
-
require 'pry'
|
10
|
-
|
11
|
-
Async do
|
12
|
-
endpoint = Async::HTTP::Endpoint.parse("https://www.google.com/search?q=kittens", alpn_protocols: ["http/1.1"])
|
13
|
-
|
14
|
-
peer = endpoint.connect
|
15
|
-
|
16
|
-
puts "Connected to #{peer} #{peer.remote_address.inspect}"
|
17
|
-
|
18
|
-
# IO Buffering...
|
19
|
-
stream = Async::IO::Stream.new(peer)
|
20
|
-
client = Protocol::HTTP1::Connection.new(stream)
|
21
|
-
|
22
|
-
def client.read_line
|
23
|
-
@stream.read_until(Protocol::HTTP1::Connection::CRLF) or raise EOFError
|
24
|
-
end
|
25
|
-
|
26
|
-
puts "Writing request..."
|
27
|
-
client.write_request("www.google.com", "GET", "/search?q=kittens", "HTTP/1.1", [["Accept", "*/*"]])
|
28
|
-
client.write_body(nil)
|
29
|
-
|
30
|
-
puts "Reading response..."
|
31
|
-
response = client.read_response("GET")
|
32
|
-
|
33
|
-
puts "Got response: #{response.inspect}"
|
34
|
-
|
35
|
-
puts "Closing client..."
|
36
|
-
client.close
|
37
|
-
end
|
38
|
-
|
39
|
-
puts "Exiting."
|
data/protocol-http1.gemspec
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
|
2
|
-
require_relative 'lib/protocol/http1/version'
|
3
|
-
|
4
|
-
Gem::Specification.new do |spec|
|
5
|
-
spec.name = "protocol-http1"
|
6
|
-
spec.version = Protocol::HTTP1::VERSION
|
7
|
-
spec.authors = ["Samuel Williams"]
|
8
|
-
spec.email = ["samuel.williams@oriontransfer.co.nz"]
|
9
|
-
|
10
|
-
spec.summary = "A low level implementation of the HTTP/1 protocol."
|
11
|
-
spec.homepage = "https://github.com/socketry/protocol-http1"
|
12
|
-
spec.license = "MIT"
|
13
|
-
|
14
|
-
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
15
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
-
end
|
17
|
-
|
18
|
-
spec.required_ruby_version = "~> 2.4"
|
19
|
-
|
20
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
-
spec.require_paths = ["lib"]
|
22
|
-
|
23
|
-
spec.add_dependency "protocol-http", "~> 0.17"
|
24
|
-
|
25
|
-
spec.add_development_dependency "covered"
|
26
|
-
spec.add_development_dependency "bundler"
|
27
|
-
spec.add_development_dependency "bake-bundler"
|
28
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
29
|
-
spec.add_development_dependency "rspec-memory", "~> 1.0"
|
30
|
-
spec.add_development_dependency "rspec-files", "~> 1.0"
|
31
|
-
end
|