protocol-http 0.53.0 → 0.55.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/context/headers.md +94 -0
- data/context/index.yaml +3 -8
- data/lib/protocol/http/body/stream.rb +2 -1
- data/lib/protocol/http/cookie.rb +32 -29
- data/lib/protocol/http/header/accept.rb +9 -2
- data/lib/protocol/http/header/accept_charset.rb +1 -1
- data/lib/protocol/http/header/accept_encoding.rb +1 -1
- data/lib/protocol/http/header/accept_language.rb +1 -1
- data/lib/protocol/http/header/authorization.rb +7 -1
- data/lib/protocol/http/header/connection.rb +7 -0
- data/lib/protocol/http/header/cookie.rb +7 -0
- data/lib/protocol/http/header/date.rb +8 -1
- data/lib/protocol/http/header/digest.rb +70 -0
- data/lib/protocol/http/header/etag.rb +7 -0
- data/lib/protocol/http/header/multiple.rb +7 -0
- data/lib/protocol/http/header/server_timing.rb +92 -0
- data/lib/protocol/http/header/split.rb +7 -0
- data/lib/protocol/http/header/te.rb +131 -0
- data/lib/protocol/http/header/trailer.rb +23 -0
- data/lib/protocol/http/header/transfer_encoding.rb +78 -0
- data/lib/protocol/http/headers.rb +55 -7
- data/lib/protocol/http/quoted_string.rb +47 -0
- data/lib/protocol/http/version.rb +1 -1
- data/readme.md +17 -9
- data/releases.md +215 -0
- data.tar.gz.sig +0 -0
- metadata +10 -6
- metadata.gz.sig +3 -3
- data/lib/protocol/http/header/quoted_string.rb +0 -49
- data/lib/protocol/http/reference.rb +0 -253
- data/lib/protocol/http/url.rb +0 -149
data/lib/protocol/http/url.rb
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Released under the MIT License.
|
|
4
|
-
# Copyright, 2019-2024, by Samuel Williams.
|
|
5
|
-
# Copyright, 2022, by Herrick Fang.
|
|
6
|
-
|
|
7
|
-
module Protocol
|
|
8
|
-
module HTTP
|
|
9
|
-
# Helpers for working with URLs.
|
|
10
|
-
module URL
|
|
11
|
-
# Escapes a string using percent encoding, e.g. `a b` -> `a%20b`.
|
|
12
|
-
#
|
|
13
|
-
# @parameter string [String] The string to escape.
|
|
14
|
-
# @returns [String] The escaped string.
|
|
15
|
-
def self.escape(string, encoding = string.encoding)
|
|
16
|
-
string.b.gsub(/([^a-zA-Z0-9_.\-]+)/) do |m|
|
|
17
|
-
"%" + m.unpack("H2" * m.bytesize).join("%").upcase
|
|
18
|
-
end.force_encoding(encoding)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# Unescapes a percent encoded string, e.g. `a%20b` -> `a b`.
|
|
22
|
-
#
|
|
23
|
-
# @parameter string [String] The string to unescape.
|
|
24
|
-
# @returns [String] The unescaped string.
|
|
25
|
-
def self.unescape(string, encoding = string.encoding)
|
|
26
|
-
string.b.gsub(/%(\h\h)/) do |hex|
|
|
27
|
-
Integer($1, 16).chr
|
|
28
|
-
end.force_encoding(encoding)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Matches characters that are not allowed in a URI path segment. According to RFC 3986 Section 3.3 (https://tools.ietf.org/html/rfc3986#section-3.3), a valid path segment consists of "pchar" characters. This pattern identifies characters that must be percent-encoded when included in a URI path segment.
|
|
32
|
-
NON_PATH_CHARACTER_PATTERN = /([^a-zA-Z0-9_\-\.~!$&'()*+,;=:@\/]+)/.freeze
|
|
33
|
-
|
|
34
|
-
# Escapes non-path characters using percent encoding. In other words, this method escapes characters that are not allowed in a URI path segment. According to RFC 3986 Section 3.3 (https://tools.ietf.org/html/rfc3986#section-3.3), a valid path segment consists of "pchar" characters. This method percent-encodes characters that are not "pchar" characters.
|
|
35
|
-
#
|
|
36
|
-
# @parameter path [String] The path to escape.
|
|
37
|
-
# @returns [String] The escaped path.
|
|
38
|
-
def self.escape_path(path)
|
|
39
|
-
encoding = path.encoding
|
|
40
|
-
path.b.gsub(NON_PATH_CHARACTER_PATTERN) do |m|
|
|
41
|
-
"%" + m.unpack("H2" * m.bytesize).join("%").upcase
|
|
42
|
-
end.force_encoding(encoding)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Encodes a hash or array into a query string. This method is used to encode query parameters in a URL. For example, `{"a" => 1, "b" => 2}` is encoded as `a=1&b=2`.
|
|
46
|
-
#
|
|
47
|
-
# @parameter value [Hash | Array | Nil] The value to encode.
|
|
48
|
-
# @parameter prefix [String] The prefix to use for keys.
|
|
49
|
-
def self.encode(value, prefix = nil)
|
|
50
|
-
case value
|
|
51
|
-
when Array
|
|
52
|
-
return value.map {|v|
|
|
53
|
-
self.encode(v, "#{prefix}[]")
|
|
54
|
-
}.join("&")
|
|
55
|
-
when Hash
|
|
56
|
-
return value.map {|k, v|
|
|
57
|
-
self.encode(v, prefix ? "#{prefix}[#{escape(k.to_s)}]" : escape(k.to_s))
|
|
58
|
-
}.reject(&:empty?).join("&")
|
|
59
|
-
when nil
|
|
60
|
-
return prefix
|
|
61
|
-
else
|
|
62
|
-
raise ArgumentError, "value must be a Hash" if prefix.nil?
|
|
63
|
-
|
|
64
|
-
return "#{prefix}=#{escape(value.to_s)}"
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Scan a string for URL-encoded key/value pairs.
|
|
69
|
-
# @yields {|key, value| ...}
|
|
70
|
-
# @parameter key [String] The unescaped key.
|
|
71
|
-
# @parameter value [String] The unescaped key.
|
|
72
|
-
def self.scan(string)
|
|
73
|
-
string.split("&") do |assignment|
|
|
74
|
-
next if assignment.empty?
|
|
75
|
-
|
|
76
|
-
key, value = assignment.split("=", 2)
|
|
77
|
-
|
|
78
|
-
yield unescape(key), value.nil? ? value : unescape(value)
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# Split a key into parts, e.g. `a[b][c]` -> `["a", "b", "c"]`.
|
|
83
|
-
#
|
|
84
|
-
# @parameter name [String] The key to split.
|
|
85
|
-
# @returns [Array(String)] The parts of the key.
|
|
86
|
-
def self.split(name)
|
|
87
|
-
name.scan(/([^\[]+)|(?:\[(.*?)\])/)&.tap do |parts|
|
|
88
|
-
parts.flatten!
|
|
89
|
-
parts.compact!
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Assign a value to a nested hash.
|
|
94
|
-
#
|
|
95
|
-
# @parameter keys [Array(String)] The parts of the key.
|
|
96
|
-
# @parameter value [Object] The value to assign.
|
|
97
|
-
# @parameter parent [Hash] The parent hash.
|
|
98
|
-
def self.assign(keys, value, parent)
|
|
99
|
-
top, *middle = keys
|
|
100
|
-
|
|
101
|
-
middle.each_with_index do |key, index|
|
|
102
|
-
if key.nil? or key.empty?
|
|
103
|
-
parent = (parent[top] ||= Array.new)
|
|
104
|
-
top = parent.size
|
|
105
|
-
|
|
106
|
-
if nested = middle[index+1] and last = parent.last
|
|
107
|
-
top -= 1 unless last.include?(nested)
|
|
108
|
-
end
|
|
109
|
-
else
|
|
110
|
-
parent = (parent[top] ||= Hash.new)
|
|
111
|
-
top = key
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
parent[top] = value
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Decode a URL-encoded query string into a hash.
|
|
119
|
-
#
|
|
120
|
-
# @parameter string [String] The query string to decode.
|
|
121
|
-
# @parameter maximum [Integer] The maximum number of keys in a path.
|
|
122
|
-
# @parameter symbolize_keys [Boolean] Whether to symbolize keys.
|
|
123
|
-
# @returns [Hash] The decoded query string.
|
|
124
|
-
def self.decode(string, maximum = 8, symbolize_keys: false)
|
|
125
|
-
parameters = {}
|
|
126
|
-
|
|
127
|
-
self.scan(string) do |name, value|
|
|
128
|
-
keys = self.split(name)
|
|
129
|
-
|
|
130
|
-
if keys.empty?
|
|
131
|
-
raise ArgumentError, "Invalid key path: #{name.inspect}!"
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
if keys.size > maximum
|
|
135
|
-
raise ArgumentError, "Key length exceeded limit!"
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
if symbolize_keys
|
|
139
|
-
keys.collect!{|key| key.empty? ? nil : key.to_sym}
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
self.assign(keys, value, parameters)
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
return parameters
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|