protocol-http1 0.10.1 → 0.10.2
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/Gemfile +2 -0
- data/README.md +1 -1
- data/Rakefile +2 -0
- data/examples/http1/request.rb +2 -1
- data/lib/protocol/http1.rb +2 -0
- data/lib/protocol/http1/body/chunked.rb +2 -0
- data/lib/protocol/http1/body/fixed.rb +2 -0
- data/lib/protocol/http1/body/remainder.rb +2 -0
- data/lib/protocol/http1/connection.rb +44 -19
- data/lib/protocol/http1/error.rb +5 -0
- data/lib/protocol/http1/reason.rb +2 -0
- data/lib/protocol/http1/version.rb +3 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7dbd1a16deecf77fd3b2b52f1081e87e0d6fff309660f6ea234c9be4af178aa4
|
4
|
+
data.tar.gz: f9dabc42905c0ae328d1a84523351f8d57da5551d86f591262849dbf7f5b83d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2536f9d4e4596319e51a1cbb9921a3f0394ca8d360c9281cc88e46be1c8efc66a81a9fc5a5cc4564e78cceb7e6f0a6aca4aaa507b5aa596e45d51f132f3aa047
|
7
|
+
data.tar.gz: fdef6a5ac396848f03a0043f5adb14e055b46edb697881edfbc5f15edfaa4a29173506e9fc51e363a8f29297e76b623b62c0f411718d69b588afb6f96d48d394
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -30,7 +30,7 @@ require 'async/io/stream'
|
|
30
30
|
require 'async/http/endpoint'
|
31
31
|
require 'protocol/http1/connection'
|
32
32
|
|
33
|
-
Async
|
33
|
+
Async do
|
34
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
|
data/Rakefile
CHANGED
data/examples/http1/request.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
3
4
|
|
@@ -7,7 +8,7 @@ require 'async/http/endpoint'
|
|
7
8
|
require 'protocol/http1/connection'
|
8
9
|
require 'pry'
|
9
10
|
|
10
|
-
Async
|
11
|
+
Async do
|
11
12
|
endpoint = Async::HTTP::Endpoint.parse("https://www.google.com/search?q=kittens", alpn_protocols: ["http/1.1"])
|
12
13
|
|
13
14
|
peer = endpoint.connect
|
data/lib/protocol/http1.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
4
|
#
|
3
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
@@ -31,26 +33,34 @@ require 'protocol/http/methods'
|
|
31
33
|
|
32
34
|
module Protocol
|
33
35
|
module HTTP1
|
34
|
-
CONTENT_LENGTH = 'content-length'
|
36
|
+
CONTENT_LENGTH = 'content-length'
|
35
37
|
|
36
|
-
TRANSFER_ENCODING = 'transfer-encoding'
|
37
|
-
CHUNKED = 'chunked'
|
38
|
+
TRANSFER_ENCODING = 'transfer-encoding'
|
39
|
+
CHUNKED = 'chunked'
|
38
40
|
|
39
|
-
CONNECTION = 'connection'
|
40
|
-
CLOSE = 'close'
|
41
|
-
KEEP_ALIVE = 'keep-alive'
|
41
|
+
CONNECTION = 'connection'
|
42
|
+
CLOSE = 'close'
|
43
|
+
KEEP_ALIVE = 'keep-alive'
|
42
44
|
|
43
|
-
HOST = 'host'
|
44
|
-
UPGRADE = 'upgrade'
|
45
|
+
HOST = 'host'
|
46
|
+
UPGRADE = 'upgrade'
|
45
47
|
|
46
48
|
# HTTP/1.x request line parser:
|
47
49
|
TOKEN = /[!#$%&'*+-\.^_`|~0-9a-zA-Z]+/.freeze
|
48
|
-
REQUEST_LINE =
|
50
|
+
REQUEST_LINE = /\A(#{TOKEN}) ([^\s]+) (HTTP\/\d.\d)\z/.freeze
|
51
|
+
|
52
|
+
# HTTP/1.x header parser:
|
53
|
+
FIELD_NAME = TOKEN
|
54
|
+
FIELD_VALUE = /[^\000-\037]*/.freeze
|
55
|
+
HEADER = /\A(#{FIELD_NAME}):\s*(#{FIELD_VALUE})\s*\z/.freeze
|
56
|
+
|
57
|
+
VALID_FIELD_NAME = /\A#{FIELD_NAME}\z/.freeze
|
58
|
+
VALID_FIELD_VALUE = /\A#{FIELD_VALUE}\z/.freeze
|
49
59
|
|
50
60
|
class Connection
|
51
|
-
CRLF = "\r\n"
|
52
|
-
HTTP10 = "HTTP/1.0"
|
53
|
-
HTTP11 = "HTTP/1.1"
|
61
|
+
CRLF = "\r\n"
|
62
|
+
HTTP10 = "HTTP/1.0"
|
63
|
+
HTTP11 = "HTTP/1.1"
|
54
64
|
|
55
65
|
def initialize(stream, persistent = true)
|
56
66
|
@stream = stream
|
@@ -132,7 +142,7 @@ module Protocol
|
|
132
142
|
end
|
133
143
|
|
134
144
|
def write_response(version, status, headers, reason = Reason::DESCRIPTIONS[status])
|
135
|
-
# Safari WebSockets break if no reason is given
|
145
|
+
# Safari WebSockets break if no reason is given:
|
136
146
|
@stream.write("#{version} #{status} #{reason}\r\n")
|
137
147
|
|
138
148
|
write_headers(headers)
|
@@ -140,8 +150,20 @@ module Protocol
|
|
140
150
|
|
141
151
|
def write_headers(headers)
|
142
152
|
headers.each do |name, value|
|
143
|
-
|
153
|
+
# Convert it to a string:
|
154
|
+
name = name.to_s
|
155
|
+
value = value.to_s
|
156
|
+
|
157
|
+
# Validate it:
|
158
|
+
unless name.match?(VALID_FIELD_NAME)
|
159
|
+
raise BadHeader, "Invalid header name: #{name.inspect}"
|
160
|
+
end
|
161
|
+
|
162
|
+
unless value.match?(VALID_FIELD_VALUE)
|
163
|
+
raise BadHeader, "Invalid header value for #{name}: #{value.inspect}"
|
164
|
+
end
|
144
165
|
|
166
|
+
# Write it:
|
145
167
|
@stream.write("#{name}: #{value}\r\n")
|
146
168
|
end
|
147
169
|
end
|
@@ -194,10 +216,13 @@ module Protocol
|
|
194
216
|
fields = []
|
195
217
|
|
196
218
|
while line = read_line
|
197
|
-
|
198
|
-
|
219
|
+
# Empty line indicates end of headers:
|
220
|
+
break if line.empty?
|
221
|
+
|
222
|
+
if match = line.match(HEADER)
|
223
|
+
fields << [match[1], match[2]]
|
199
224
|
else
|
200
|
-
|
225
|
+
raise BadHeader, "Could not parse header: #{line.dump}"
|
201
226
|
end
|
202
227
|
end
|
203
228
|
|
@@ -361,8 +386,8 @@ module Protocol
|
|
361
386
|
read_remainder_body
|
362
387
|
end
|
363
388
|
|
364
|
-
HEAD = "HEAD"
|
365
|
-
CONNECT = "CONNECT"
|
389
|
+
HEAD = "HEAD"
|
390
|
+
CONNECT = "CONNECT"
|
366
391
|
|
367
392
|
def read_response_body(method, status, headers)
|
368
393
|
# RFC 7230 3.3.3
|
data/lib/protocol/http1/error.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
4
|
#
|
3
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
@@ -32,6 +34,9 @@ module Protocol
|
|
32
34
|
class BadRequest < Error
|
33
35
|
end
|
34
36
|
|
37
|
+
class BadHeader < Error
|
38
|
+
end
|
39
|
+
|
35
40
|
class BadResponse < Error
|
36
41
|
end
|
37
42
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
4
|
#
|
3
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
@@ -20,6 +22,6 @@
|
|
20
22
|
|
21
23
|
module Protocol
|
22
24
|
module HTTP1
|
23
|
-
VERSION = "0.10.
|
25
|
+
VERSION = "0.10.2"
|
24
26
|
end
|
25
27
|
end
|
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.10.
|
4
|
+
version: 0.10.2
|
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-02-
|
11
|
+
date: 2020-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: protocol-http
|
@@ -151,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
requirements: []
|
154
|
-
rubygems_version: 3.
|
154
|
+
rubygems_version: 3.1.2
|
155
155
|
signing_key:
|
156
156
|
specification_version: 4
|
157
157
|
summary: A low level implementation of the HTTP/1 protocol.
|