protocol-http1 0.5.0 → 0.6.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/.gitignore +1 -0
- data/Gemfile +5 -0
- data/README.md +2 -2
- data/examples/http1/request.rb +2 -2
- data/lib/protocol/http1/body/chunked.rb +77 -0
- data/lib/protocol/http1/body/fixed.rb +72 -0
- data/lib/protocol/http1/body/remainder.rb +64 -0
- data/lib/protocol/http1/connection.rb +45 -79
- data/lib/protocol/http1/version.rb +21 -1
- data/protocol-http1.gemspec +1 -1
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 750f0922f84bc1790af1f042ffe720f1c2d7ffd50b3492522d3ace0362447d96
|
4
|
+
data.tar.gz: 5a4dc4316888e0ba157c4360c871945ea5f4533f86098486fbe0682865b9b2e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d347f96ce603c2721abe056862c07d2cca962735b150027177d1bca5fc1d869209f5840e55f241312c633c83c57a47c380e07cc4d815cba10224ecfcbf7962a
|
7
|
+
data.tar.gz: 858cb2dae8d2e93e3150ef8361e247cf7dfe2bba43dcd52e2cf8917da3e211f779446decca233f101666a5e4188b4a31764df03c229ff86f902eb90e3ce185ca
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -27,11 +27,11 @@ Here is a basic HTTP/1.1 client:
|
|
27
27
|
```ruby
|
28
28
|
require 'async'
|
29
29
|
require 'async/io/stream'
|
30
|
-
require 'async/http/
|
30
|
+
require 'async/http/endpoint'
|
31
31
|
require 'protocol/http1/connection'
|
32
32
|
|
33
33
|
Async.run do
|
34
|
-
endpoint = Async::HTTP::
|
34
|
+
endpoint = Async::HTTP::Endpoint.parse("https://www.google.com/search?q=kittens", alpn_protocols: ["http/1.1"])
|
35
35
|
|
36
36
|
peer = endpoint.connect
|
37
37
|
|
data/examples/http1/request.rb
CHANGED
@@ -3,12 +3,12 @@ $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
3
3
|
|
4
4
|
require 'async'
|
5
5
|
require 'async/io/stream'
|
6
|
-
require 'async/http/
|
6
|
+
require 'async/http/endpoint'
|
7
7
|
require 'protocol/http1/connection'
|
8
8
|
require 'pry'
|
9
9
|
|
10
10
|
Async.run do
|
11
|
-
endpoint = Async::HTTP::
|
11
|
+
endpoint = Async::HTTP::Endpoint.parse("https://www.google.com/search?q=kittens", alpn_protocols: ["http/1.1"])
|
12
12
|
|
13
13
|
peer = endpoint.connect
|
14
14
|
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'protocol/http/body/readable'
|
22
|
+
|
23
|
+
module Protocol
|
24
|
+
module HTTP1
|
25
|
+
module Body
|
26
|
+
class Chunked < HTTP::Body::Readable
|
27
|
+
# TODO maybe this should take a stream rather than a connection?
|
28
|
+
def initialize(connection)
|
29
|
+
@connection = connection
|
30
|
+
@finished = false
|
31
|
+
|
32
|
+
@length = 0
|
33
|
+
@count = 0
|
34
|
+
end
|
35
|
+
|
36
|
+
def empty?
|
37
|
+
@finished
|
38
|
+
end
|
39
|
+
|
40
|
+
def close(error = nil)
|
41
|
+
# We only close the connection if we haven't completed reading the entire body:
|
42
|
+
unless @finished
|
43
|
+
@connection.close
|
44
|
+
@finished = true
|
45
|
+
end
|
46
|
+
|
47
|
+
super
|
48
|
+
end
|
49
|
+
|
50
|
+
def read
|
51
|
+
return nil if @finished
|
52
|
+
|
53
|
+
length = @connection.read_line.to_i(16)
|
54
|
+
|
55
|
+
if length == 0
|
56
|
+
@finished = true
|
57
|
+
@connection.read_line
|
58
|
+
|
59
|
+
return nil
|
60
|
+
end
|
61
|
+
|
62
|
+
chunk = @connection.stream.read(length)
|
63
|
+
@connection.read_line # Consume the trailing CRLF
|
64
|
+
|
65
|
+
@length += length
|
66
|
+
@count += 1
|
67
|
+
|
68
|
+
return chunk
|
69
|
+
end
|
70
|
+
|
71
|
+
def inspect
|
72
|
+
"\#<#{self.class} #{@length} bytes read in #{@count} chunks>"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'protocol/http/body/readable'
|
22
|
+
|
23
|
+
module Protocol
|
24
|
+
module HTTP1
|
25
|
+
module Body
|
26
|
+
class Fixed < HTTP::Body::Readable
|
27
|
+
def initialize(stream, length)
|
28
|
+
@stream = stream
|
29
|
+
@length = length
|
30
|
+
@remaining = length
|
31
|
+
end
|
32
|
+
|
33
|
+
attr :length
|
34
|
+
attr :remaining
|
35
|
+
|
36
|
+
def empty?
|
37
|
+
@remaining == 0
|
38
|
+
end
|
39
|
+
|
40
|
+
def close(error = nil)
|
41
|
+
if @remaining != 0
|
42
|
+
@stream.close
|
43
|
+
end
|
44
|
+
|
45
|
+
super
|
46
|
+
end
|
47
|
+
|
48
|
+
def read
|
49
|
+
if @remaining > 0
|
50
|
+
if chunk = @stream.read_partial(@remaining)
|
51
|
+
@remaining -= chunk.bytesize
|
52
|
+
|
53
|
+
return chunk
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def join
|
59
|
+
buffer = @stream.read(@remaining)
|
60
|
+
|
61
|
+
@remaining = 0
|
62
|
+
|
63
|
+
return buffer
|
64
|
+
end
|
65
|
+
|
66
|
+
def inspect
|
67
|
+
"\#<#{self.class} length=#{@length} remaining=#{@remaining}>"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'protocol/http/body/readable'
|
22
|
+
|
23
|
+
module Protocol
|
24
|
+
module HTTP1
|
25
|
+
module Body
|
26
|
+
class Remainder < HTTP::Body::Readable
|
27
|
+
def initialize(stream)
|
28
|
+
@stream = stream
|
29
|
+
end
|
30
|
+
|
31
|
+
def empty?
|
32
|
+
@stream.closed?
|
33
|
+
end
|
34
|
+
|
35
|
+
def close(error = nil)
|
36
|
+
# We can't really do anything in this case except close the connection.
|
37
|
+
@stream.close
|
38
|
+
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
def read
|
43
|
+
@stream.read_partial
|
44
|
+
end
|
45
|
+
|
46
|
+
def call(stream)
|
47
|
+
self.each do |chunk|
|
48
|
+
stream.write(chunk)
|
49
|
+
end
|
50
|
+
|
51
|
+
stream.flush
|
52
|
+
end
|
53
|
+
|
54
|
+
def join
|
55
|
+
read
|
56
|
+
end
|
57
|
+
|
58
|
+
def inspect
|
59
|
+
"\#<#{self.class} #{@stream.closed? ? 'closed' : 'open'}>"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -22,6 +22,10 @@ require 'protocol/http/headers'
|
|
22
22
|
|
23
23
|
require_relative 'error'
|
24
24
|
|
25
|
+
require_relative 'body/chunked'
|
26
|
+
require_relative 'body/fixed'
|
27
|
+
require_relative 'body/remainder'
|
28
|
+
|
25
29
|
module Protocol
|
26
30
|
module HTTP1
|
27
31
|
CONTENT_LENGTH = 'content-length'.freeze
|
@@ -45,7 +49,6 @@ module Protocol
|
|
45
49
|
@stream = stream
|
46
50
|
|
47
51
|
@persistent = persistent
|
48
|
-
@upgrade = nil
|
49
52
|
|
50
53
|
@count = 0
|
51
54
|
end
|
@@ -55,15 +58,12 @@ module Protocol
|
|
55
58
|
# Whether the connection is persistent.
|
56
59
|
attr :persistent
|
57
60
|
|
58
|
-
# Whether the connection has been upgraded, and to what.
|
59
|
-
attr :upgrade
|
60
|
-
|
61
61
|
# The number of requests processed.
|
62
62
|
attr :count
|
63
63
|
|
64
64
|
def upgrade?(headers)
|
65
65
|
if upgrade = headers[UPGRADE]
|
66
|
-
return upgrade
|
66
|
+
return upgrade
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
@@ -83,27 +83,19 @@ module Protocol
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
def upgrade!(protocol)
|
87
|
-
@persistent = false
|
88
|
-
|
89
|
-
@upgrade = protocol
|
90
|
-
|
91
|
-
return @stream
|
92
|
-
end
|
93
|
-
|
94
86
|
# Write the appropriate header for connection persistence.
|
95
87
|
def write_connection_header(version)
|
96
|
-
if
|
97
|
-
@stream.write("connection:
|
88
|
+
if version == HTTP10
|
89
|
+
@stream.write("connection: keep-alive\r\n") if @persistent
|
98
90
|
else
|
99
|
-
|
100
|
-
@stream.write("connection: keep-alive\r\n") if @persistent
|
101
|
-
else
|
102
|
-
@stream.write("connection: close\r\n") unless @persistent
|
103
|
-
end
|
91
|
+
@stream.write("connection: close\r\n") unless @persistent
|
104
92
|
end
|
105
93
|
end
|
106
94
|
|
95
|
+
def write_upgrade_header(upgrade)
|
96
|
+
@stream.write("connection: upgrade\r\nupgrade: #{upgrade}\r\n")
|
97
|
+
end
|
98
|
+
|
107
99
|
# Effectively close the connection and return the underlying IO.
|
108
100
|
# @return [IO] the underlying non-blocking IO.
|
109
101
|
def hijack!
|
@@ -124,15 +116,13 @@ module Protocol
|
|
124
116
|
@stream.write("host: #{authority}\r\n")
|
125
117
|
|
126
118
|
write_headers(headers)
|
127
|
-
write_connection_header(version)
|
128
119
|
end
|
129
120
|
|
130
|
-
def write_response(version, status, headers,
|
131
|
-
|
121
|
+
def write_response(version, status, headers, reason = "With Honour.")
|
122
|
+
# Safari WebSockets break if no reason is given.
|
123
|
+
@stream.write("#{version} #{status} #{reason}\r\n")
|
132
124
|
|
133
125
|
write_headers(headers)
|
134
|
-
write_connection_header(version)
|
135
|
-
write_body(body, version == HTTP11, head)
|
136
126
|
end
|
137
127
|
|
138
128
|
def write_headers(headers)
|
@@ -156,7 +146,6 @@ module Protocol
|
|
156
146
|
headers = read_headers
|
157
147
|
|
158
148
|
@persistent = persistent?(version, headers)
|
159
|
-
@upgrade = upgrade?(headers)
|
160
149
|
|
161
150
|
body = read_request_body(headers)
|
162
151
|
|
@@ -195,32 +184,20 @@ module Protocol
|
|
195
184
|
return HTTP::Headers.new(fields)
|
196
185
|
end
|
197
186
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
if length == 0
|
202
|
-
self.read_line
|
203
|
-
|
204
|
-
return nil
|
205
|
-
end
|
206
|
-
|
207
|
-
# Read the data:
|
208
|
-
chunk = @stream.read(length)
|
209
|
-
|
210
|
-
# Consume the trailing CRLF:
|
211
|
-
@stream.read(2)
|
212
|
-
|
213
|
-
return chunk
|
214
|
-
end
|
215
|
-
|
216
|
-
def write_upgrade_body(body = nil)
|
217
|
-
# Any time we are potentially closing the stream, we should ensure no further requests are processed:
|
187
|
+
# @param protocol [String] the protocol to upgrade to.
|
188
|
+
def write_upgrade_body(protocol, body = nil)
|
189
|
+
# Once we upgrade the connection, it can no longer handle other requests:
|
218
190
|
@persistent = false
|
219
191
|
|
192
|
+
write_upgrade_header(protocol)
|
193
|
+
|
220
194
|
@stream.write("\r\n")
|
221
|
-
@stream.flush
|
195
|
+
@stream.flush # Don't remove me!
|
222
196
|
|
223
|
-
body
|
197
|
+
body&.each do |chunk|
|
198
|
+
@stream.write(chunk)
|
199
|
+
@stream.flush
|
200
|
+
end
|
224
201
|
|
225
202
|
return @stream
|
226
203
|
end
|
@@ -229,9 +206,7 @@ module Protocol
|
|
229
206
|
@stream.write("content-length: 0\r\n\r\n")
|
230
207
|
@stream.flush
|
231
208
|
|
232
|
-
|
233
|
-
body.close if body.respond_to?(:close)
|
234
|
-
end
|
209
|
+
body&.close
|
235
210
|
end
|
236
211
|
|
237
212
|
def write_fixed_length_body(body, length, head)
|
@@ -239,7 +214,7 @@ module Protocol
|
|
239
214
|
@stream.flush
|
240
215
|
|
241
216
|
if head
|
242
|
-
body.close
|
217
|
+
body.close
|
243
218
|
|
244
219
|
return
|
245
220
|
end
|
@@ -267,7 +242,7 @@ module Protocol
|
|
267
242
|
@stream.flush
|
268
243
|
|
269
244
|
if head
|
270
|
-
body.close
|
245
|
+
body.close
|
271
246
|
|
272
247
|
return
|
273
248
|
end
|
@@ -288,11 +263,12 @@ module Protocol
|
|
288
263
|
def write_body_and_close(body, head)
|
289
264
|
# We can't be persistent because we don't know the data length:
|
290
265
|
@persistent = false
|
266
|
+
|
291
267
|
@stream.write("\r\n")
|
292
268
|
@stream.flush
|
293
269
|
|
294
270
|
if head
|
295
|
-
body.close
|
271
|
+
body.close
|
296
272
|
else
|
297
273
|
body.each do |chunk|
|
298
274
|
@stream.write(chunk)
|
@@ -303,48 +279,42 @@ module Protocol
|
|
303
279
|
@stream.close_write
|
304
280
|
end
|
305
281
|
|
306
|
-
def write_body(
|
282
|
+
def write_body(version, body, head = false)
|
307
283
|
if body.nil? or body.empty?
|
284
|
+
write_connection_header(version)
|
308
285
|
write_empty_body(body)
|
309
|
-
elsif body.respond_to?(:call)
|
310
|
-
write_upgrade_body(body)
|
311
286
|
elsif length = body.length
|
287
|
+
write_connection_header(version)
|
312
288
|
write_fixed_length_body(body, length, head)
|
313
|
-
elsif @persistent and
|
289
|
+
elsif @persistent and version == HTTP11
|
290
|
+
write_connection_header(version)
|
314
291
|
# We specifically ensure that non-persistent connections do not use chunked response, so that hijacking works as expected.
|
315
292
|
write_chunked_body(body, head)
|
316
293
|
else
|
294
|
+
@persistent = false
|
295
|
+
write_connection_header(version)
|
317
296
|
write_body_and_close(body, head)
|
318
297
|
end
|
319
|
-
|
320
|
-
@stream.flush
|
321
298
|
end
|
322
299
|
|
323
300
|
def read_chunked_body
|
324
|
-
|
325
|
-
|
326
|
-
while chunk = read_chunk
|
327
|
-
buffer << chunk
|
328
|
-
chunk.clear
|
329
|
-
end
|
330
|
-
|
331
|
-
return buffer
|
301
|
+
Body::Chunked.new(self)
|
332
302
|
end
|
333
303
|
|
334
304
|
def read_fixed_body(length)
|
335
|
-
@stream
|
305
|
+
Body::Fixed.new(@stream, length)
|
336
306
|
end
|
337
307
|
|
338
|
-
def
|
339
|
-
|
308
|
+
def read_remainder_body
|
309
|
+
Body::Remainder.new(@stream)
|
340
310
|
end
|
341
311
|
|
342
|
-
def
|
312
|
+
def read_tunnel_body
|
343
313
|
read_remainder_body
|
344
314
|
end
|
345
315
|
|
346
|
-
def
|
347
|
-
|
316
|
+
def read_upgrade_body(protocol)
|
317
|
+
read_remainder_body
|
348
318
|
end
|
349
319
|
|
350
320
|
HEAD = "HEAD".freeze
|
@@ -428,11 +398,7 @@ module Protocol
|
|
428
398
|
end
|
429
399
|
end
|
430
400
|
|
431
|
-
|
432
|
-
@upgrade = upgrade
|
433
|
-
return read_upgrade_body
|
434
|
-
end
|
435
|
-
|
401
|
+
# http://tools.ietf.org/html/rfc2068#section-19.7.1.1
|
436
402
|
if remainder
|
437
403
|
# 7. Otherwise, this is a response message without a declared message
|
438
404
|
# body length, so the message body length is determined by the
|
@@ -1,5 +1,25 @@
|
|
1
|
+
# Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
1
21
|
module Protocol
|
2
22
|
module HTTP1
|
3
|
-
VERSION = "0.
|
23
|
+
VERSION = "0.6.0"
|
4
24
|
end
|
5
25
|
end
|
data/protocol-http1.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "protocol-http", "~> 0.
|
21
|
+
spec.add_dependency "protocol-http", "~> 0.5"
|
22
22
|
|
23
23
|
spec.add_development_dependency "covered"
|
24
24
|
spec.add_development_dependency "bundler"
|
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.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-05-
|
11
|
+
date: 2019-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: protocol-http
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.5'
|
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.
|
26
|
+
version: '0.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: covered
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -96,6 +96,9 @@ files:
|
|
96
96
|
- Rakefile
|
97
97
|
- examples/http1/request.rb
|
98
98
|
- lib/protocol/http1.rb
|
99
|
+
- lib/protocol/http1/body/chunked.rb
|
100
|
+
- lib/protocol/http1/body/fixed.rb
|
101
|
+
- lib/protocol/http1/body/remainder.rb
|
99
102
|
- lib/protocol/http1/connection.rb
|
100
103
|
- lib/protocol/http1/error.rb
|
101
104
|
- lib/protocol/http1/version.rb
|
@@ -119,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
122
|
- !ruby/object:Gem::Version
|
120
123
|
version: '0'
|
121
124
|
requirements: []
|
122
|
-
rubygems_version: 3.0.
|
125
|
+
rubygems_version: 3.0.2
|
123
126
|
signing_key:
|
124
127
|
specification_version: 4
|
125
128
|
summary: A low level implementation of the HTTP/1 protocol.
|