tilia-http 4.1.0.8 → 4.2.1
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
- data/CHANGELOG.sabre.md +15 -0
- data/Gemfile +1 -9
- data/Gemfile.lock +16 -10
- data/examples/asyncclient.rb +1 -5
- data/examples/basicauth.rb +1 -5
- data/examples/client.rb +1 -5
- data/examples/digestauth.rb +37 -0
- data/examples/reverseproxy.rb +1 -1
- data/examples/stringify.rb +1 -5
- data/lib/tilia/http/auth/abstract_auth.rb +0 -19
- data/lib/tilia/http/auth/aws.rb +7 -21
- data/lib/tilia/http/auth/digest.rb +15 -26
- data/lib/tilia/http/client.rb +23 -66
- data/lib/tilia/http/client_exception.rb +1 -1
- data/lib/tilia/http/client_http_exception.rb +2 -11
- data/lib/tilia/http/http_exception.rb +1 -1
- data/lib/tilia/http/message.rb +33 -140
- data/lib/tilia/http/message_decorator_trait.rb +15 -113
- data/lib/tilia/http/message_interface.rb +19 -18
- data/lib/tilia/http/request.rb +21 -121
- data/lib/tilia/http/request_decorator.rb +15 -77
- data/lib/tilia/http/request_interface.rb +11 -11
- data/lib/tilia/http/response.rb +13 -41
- data/lib/tilia/http/response_decorator.rb +4 -19
- data/lib/tilia/http/response_interface.rb +3 -3
- data/lib/tilia/http/sapi.rb +4 -4
- data/lib/tilia/http/url_util.rb +2 -2
- data/lib/tilia/http/util.rb +5 -5
- data/lib/tilia/http/version.rb +1 -1
- data/lib/tilia/http.rb +9 -9
- data/test/http/message_test.rb +24 -4
- data/test/http/url_util_test.rb +1 -1
- data/tilia-http.gemspec +1 -1
- metadata +7 -6
@@ -7,7 +7,7 @@ module Tilia
|
|
7
7
|
#
|
8
8
|
# If you'd like to use this, create a new exception class, extending Exception
|
9
9
|
# and implementing this interface.
|
10
|
-
class HttpException <
|
10
|
+
class HttpException < StandardError
|
11
11
|
# The http status code for the error.
|
12
12
|
#
|
13
13
|
# This may either be just the number, or a number and a human-readable
|
data/lib/tilia/http/message.rb
CHANGED
@@ -7,35 +7,9 @@ module Tilia
|
|
7
7
|
module Message
|
8
8
|
include Tilia::Http::MessageInterface
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
# Request body
|
13
|
-
#
|
14
|
-
# This should be a stream resource
|
15
|
-
#
|
16
|
-
# @return resource
|
17
|
-
attr_accessor :body
|
18
|
-
|
19
|
-
# Contains the list of HTTP headers
|
20
|
-
#
|
21
|
-
# @return array
|
22
|
-
attr_accessor :headers
|
23
|
-
|
24
|
-
# HTTP message version (1.0 or 1.1)
|
25
|
-
#
|
26
|
-
# @return [String]
|
27
|
-
attr_accessor :http_version
|
28
|
-
|
29
|
-
public
|
30
|
-
|
31
|
-
# Returns the body as a readable stream resource.
|
32
|
-
#
|
33
|
-
# Note that the stream may not be rewindable, and therefore may only be
|
34
|
-
# read once.
|
35
|
-
#
|
36
|
-
# @return resource
|
10
|
+
# (see MessageInterface#body_as_stream)
|
37
11
|
def body_as_stream
|
38
|
-
body =
|
12
|
+
body = @body
|
39
13
|
if body.is_a?(String) || body.nil?
|
40
14
|
stream = StringIO.new
|
41
15
|
stream.write body
|
@@ -45,44 +19,31 @@ module Tilia
|
|
45
19
|
body
|
46
20
|
end
|
47
21
|
|
48
|
-
#
|
49
|
-
#
|
50
|
-
# Note that because the underlying data may be based on a stream, this
|
51
|
-
# method could only work correctly the first time.
|
52
|
-
#
|
53
|
-
# @return [String]
|
22
|
+
# (see MessageInterface#body_as_string)
|
54
23
|
def body_as_string
|
55
|
-
body =
|
24
|
+
body = @body
|
56
25
|
if body.is_a?(String)
|
57
26
|
body
|
58
27
|
elsif body.nil?
|
59
28
|
''
|
60
29
|
else
|
61
|
-
|
30
|
+
content_length = header('Content-Length')
|
31
|
+
|
32
|
+
if content_length.present?
|
33
|
+
body.read(content_length.to_i)
|
34
|
+
else
|
35
|
+
body.read
|
36
|
+
end
|
62
37
|
end
|
63
38
|
end
|
64
39
|
|
65
|
-
#
|
66
|
-
|
67
|
-
# This could be either a string or a stream.
|
68
|
-
#
|
69
|
-
# @return resource|string
|
70
|
-
def body
|
71
|
-
@body
|
72
|
-
end
|
40
|
+
# (see MessageInterface#body)
|
41
|
+
attr_reader :body
|
73
42
|
|
74
|
-
#
|
75
|
-
|
76
|
-
# @param resource|string body
|
77
|
-
def body=(body)
|
78
|
-
@body = body
|
79
|
-
end
|
43
|
+
# (see MessageInterface#body=)
|
44
|
+
attr_writer :body
|
80
45
|
|
81
|
-
#
|
82
|
-
#
|
83
|
-
# Every header is returned as an array, with one or more values.
|
84
|
-
#
|
85
|
-
# @return array
|
46
|
+
# (see MessageInterface#headers)
|
86
47
|
def headers
|
87
48
|
result = {}
|
88
49
|
@headers.values.each do |header_info|
|
@@ -91,28 +52,12 @@ module Tilia
|
|
91
52
|
result
|
92
53
|
end
|
93
54
|
|
94
|
-
#
|
95
|
-
#
|
96
|
-
# @param [String] name
|
97
|
-
# @return bool
|
55
|
+
# (see MessageInterface#header?)
|
98
56
|
def header?(name)
|
99
57
|
@headers.key? name.downcase
|
100
58
|
end
|
101
59
|
|
102
|
-
#
|
103
|
-
#
|
104
|
-
# The name must be treated as case-insensitive.
|
105
|
-
# If the header does not exist, this method must return null.
|
106
|
-
#
|
107
|
-
# If a header appeared more than once in a HTTP request, this method will
|
108
|
-
# concatenate all the values with a comma.
|
109
|
-
#
|
110
|
-
# Note that this not make sense for all headers. Some, such as
|
111
|
-
# `Set-Cookie` cannot be logically combined with a comma. In those cases
|
112
|
-
# you *should* use header_as_array.
|
113
|
-
#
|
114
|
-
# @param [String] name
|
115
|
-
# @return [String, nil]
|
60
|
+
# (see MessageInterface#header)
|
116
61
|
def header(name)
|
117
62
|
name = name.downcase
|
118
63
|
|
@@ -121,15 +66,7 @@ module Tilia
|
|
121
66
|
nil
|
122
67
|
end
|
123
68
|
|
124
|
-
#
|
125
|
-
#
|
126
|
-
# For every time the HTTP header appeared in the request or response, an
|
127
|
-
# item will appear in the array.
|
128
|
-
#
|
129
|
-
# If the header did not exists, this method will return an empty array.
|
130
|
-
#
|
131
|
-
# @param [String] name
|
132
|
-
# @return [String][]
|
69
|
+
# (see MessageInterface#header_as_array)
|
133
70
|
def header_as_array(name)
|
134
71
|
name = name.downcase
|
135
72
|
|
@@ -138,44 +75,20 @@ module Tilia
|
|
138
75
|
[]
|
139
76
|
end
|
140
77
|
|
141
|
-
#
|
142
|
-
#
|
143
|
-
# The case-sensitity of the name value must be retained as-is.
|
144
|
-
#
|
145
|
-
# If the header already existed, it will be overwritten.
|
146
|
-
#
|
147
|
-
# @param [String] name
|
148
|
-
# @param [String, Array<String>] value
|
149
|
-
# @return [void]
|
78
|
+
# (see MessageInterface#update_header)
|
150
79
|
def update_header(name, value)
|
151
80
|
value = [value] unless value.is_a?(Array)
|
152
81
|
@headers[name.downcase] = [name, value]
|
153
82
|
end
|
154
83
|
|
155
|
-
#
|
156
|
-
#
|
157
|
-
# The headers array should contain headernames for keys, and their value
|
158
|
-
# should be specified as either a string or an array.
|
159
|
-
#
|
160
|
-
# Any header that already existed will be overwritten.
|
161
|
-
#
|
162
|
-
# @param array headers
|
163
|
-
# @return [void]
|
84
|
+
# (see MessageInterface#update_headers)
|
164
85
|
def update_headers(headers)
|
165
86
|
headers.each do |name, value|
|
166
87
|
update_header(name, value)
|
167
88
|
end
|
168
89
|
end
|
169
90
|
|
170
|
-
#
|
171
|
-
#
|
172
|
-
# This method will not overwrite any existing HTTP header, but instead add
|
173
|
-
# another value. Individual values can be retrieved with
|
174
|
-
# getHeadersAsArray.
|
175
|
-
#
|
176
|
-
# @param [String] name
|
177
|
-
# @param [String] value
|
178
|
-
# @return [void]
|
91
|
+
# (see MessageInterface#add_header)
|
179
92
|
def add_header(name, value)
|
180
93
|
l_name = name.downcase
|
181
94
|
value = [value] unless value.is_a?(Array)
|
@@ -187,25 +100,14 @@ module Tilia
|
|
187
100
|
end
|
188
101
|
end
|
189
102
|
|
190
|
-
#
|
191
|
-
#
|
192
|
-
# Any existing headers will not be overwritten.
|
193
|
-
#
|
194
|
-
# @param array headers
|
195
|
-
# @return [void]
|
103
|
+
# (see MessageInterface#add_headers)
|
196
104
|
def add_headers(headers)
|
197
105
|
headers.each do |name, value|
|
198
106
|
add_header(name, value)
|
199
107
|
end
|
200
108
|
end
|
201
109
|
|
202
|
-
#
|
203
|
-
#
|
204
|
-
# The specified header name must be treated as case-insenstive.
|
205
|
-
# This method should return true if the header was successfully deleted,
|
206
|
-
# and false if the header did not exist.
|
207
|
-
#
|
208
|
-
# @return bool
|
110
|
+
# (see MessageInterface#remove_header)
|
209
111
|
def remove_header(name)
|
210
112
|
name = name.downcase
|
211
113
|
return false unless @headers.key?(name)
|
@@ -213,31 +115,22 @@ module Tilia
|
|
213
115
|
true
|
214
116
|
end
|
215
117
|
|
216
|
-
#
|
217
|
-
|
218
|
-
# Should be 1.0 or 1.1.
|
219
|
-
#
|
220
|
-
# @param [String] version
|
221
|
-
# @return [void]
|
222
|
-
def http_version=(version)
|
223
|
-
@http_version = version
|
224
|
-
end
|
118
|
+
# (see MessageInterface#http_version)
|
119
|
+
attr_writer :http_version
|
225
120
|
|
226
|
-
#
|
227
|
-
|
228
|
-
# @return [String]
|
229
|
-
def http_version
|
230
|
-
@http_version
|
231
|
-
end
|
121
|
+
# (see MessageInterface#http_version=)
|
122
|
+
attr_reader :http_version
|
232
123
|
|
233
|
-
#
|
234
|
-
def
|
124
|
+
# Initializes the instance vars of Message
|
125
|
+
def initialize(*args)
|
235
126
|
@body = nil
|
236
127
|
@headers = {}
|
237
128
|
@http_version = '1.1'
|
129
|
+
|
130
|
+
super
|
238
131
|
end
|
239
132
|
|
240
|
-
#
|
133
|
+
# creates a deep copy of the headers hash when cloning
|
241
134
|
def initialize_copy(_original)
|
242
135
|
@headers = @headers.deep_dup
|
243
136
|
end
|
@@ -6,175 +6,77 @@ module Tilia
|
|
6
6
|
# Didn't seem needed to create a full class for this, so we're just
|
7
7
|
# implementing it as a trait.
|
8
8
|
module MessageDecoratorTrait
|
9
|
-
|
10
|
-
|
11
|
-
# The inner request object.
|
12
|
-
#
|
13
|
-
# All method calls will be forwarded here.
|
14
|
-
#
|
15
|
-
# @return MessageInterface
|
16
|
-
attr_accessor :inner
|
17
|
-
|
18
|
-
public
|
19
|
-
|
20
|
-
# Returns the body as a readable stream resource.
|
21
|
-
#
|
22
|
-
# Note that the stream may not be rewindable, and therefore may only be
|
23
|
-
# read once.
|
24
|
-
#
|
25
|
-
# @return resource
|
9
|
+
# (see MessageInterface#body_as_stream)
|
26
10
|
def body_as_stream
|
27
11
|
@inner.body_as_stream
|
28
12
|
end
|
29
13
|
|
30
|
-
#
|
31
|
-
#
|
32
|
-
# Note that because the underlying data may be based on a stream, this
|
33
|
-
# method could only work correctly the first time.
|
34
|
-
#
|
35
|
-
# @return [String]
|
14
|
+
# (see MessageInterface#body_as_string)
|
36
15
|
def body_as_string
|
37
16
|
@inner.body_as_string
|
38
17
|
end
|
39
18
|
|
40
|
-
#
|
41
|
-
#
|
42
|
-
# This could be either a string or a stream.
|
43
|
-
#
|
44
|
-
# @return resource|string
|
19
|
+
# (see MessageInterface#body)
|
45
20
|
def body
|
46
21
|
@inner.body
|
47
22
|
end
|
48
23
|
|
49
|
-
#
|
50
|
-
#
|
51
|
-
# @param resource body
|
52
|
-
# @return [void]
|
24
|
+
# (see MessageInterface#body=)
|
53
25
|
def body=(body)
|
54
26
|
@inner.body = body
|
55
27
|
end
|
56
28
|
|
57
|
-
#
|
58
|
-
#
|
59
|
-
# Every header is returned as an array, with one or more values.
|
60
|
-
#
|
61
|
-
# @return array
|
29
|
+
# (see MessageInterface#headers)
|
62
30
|
def headers
|
63
31
|
@inner.headers
|
64
32
|
end
|
65
33
|
|
66
|
-
#
|
67
|
-
#
|
68
|
-
# @param [String] name
|
69
|
-
# @return bool
|
34
|
+
# (see MessageInterface#header?)
|
70
35
|
def header?(name)
|
71
36
|
@inner.header?(name)
|
72
37
|
end
|
73
38
|
|
74
|
-
#
|
75
|
-
#
|
76
|
-
# The name must be treated as case-insensitive.
|
77
|
-
# If the header does not exist, this method must return null.
|
78
|
-
#
|
79
|
-
# If a header appeared more than once in a HTTP request, this method will
|
80
|
-
# concatenate all the values with a comma.
|
81
|
-
#
|
82
|
-
# Note that this not make sense for all headers. Some, such as
|
83
|
-
# `Set-Cookie` cannot be logically combined with a comma. In those cases
|
84
|
-
# you *should* use header_as_array.
|
85
|
-
#
|
86
|
-
# @param [String] name
|
87
|
-
# @return [String, nil]
|
39
|
+
# (see MessageInterface#header)
|
88
40
|
def header(name)
|
89
41
|
@inner.header(name)
|
90
42
|
end
|
91
43
|
|
92
|
-
#
|
93
|
-
#
|
94
|
-
# For every time the HTTP header appeared in the request or response, an
|
95
|
-
# item will appear in the array.
|
96
|
-
#
|
97
|
-
# If the header did not exists, this method will return an empty array.
|
98
|
-
#
|
99
|
-
# @param [String] name
|
100
|
-
# @return [String][]
|
44
|
+
# (see MessageInterface#header_as_array)
|
101
45
|
def header_as_array(name)
|
102
46
|
@inner.header_as_array(name)
|
103
47
|
end
|
104
48
|
|
105
|
-
#
|
106
|
-
#
|
107
|
-
# The case-sensitity of the name value must be retained as-is.
|
108
|
-
#
|
109
|
-
# If the header already existed, it will be overwritten.
|
110
|
-
#
|
111
|
-
# @param [String] name
|
112
|
-
# @param [String, Array<String>] value
|
113
|
-
# @return [void]
|
49
|
+
# (see MessageInterface#update_header)
|
114
50
|
def update_header(name, value)
|
115
51
|
@inner.update_header(name, value)
|
116
52
|
end
|
117
53
|
|
118
|
-
#
|
119
|
-
#
|
120
|
-
# The headers array should contain headernames for keys, and their value
|
121
|
-
# should be specified as either a string or an array.
|
122
|
-
#
|
123
|
-
# Any header that already existed will be overwritten.
|
124
|
-
#
|
125
|
-
# @param array headers
|
126
|
-
# @return [void]
|
54
|
+
# (see MessageInterface#update_headers)
|
127
55
|
def update_headers(headers)
|
128
56
|
@inner.update_headers(headers)
|
129
57
|
end
|
130
58
|
|
131
|
-
#
|
132
|
-
#
|
133
|
-
# This method will not overwrite any existing HTTP header, but instead add
|
134
|
-
# another value. Individual values can be retrieved with
|
135
|
-
# getHeadersAsArray.
|
136
|
-
#
|
137
|
-
# @param [String] name
|
138
|
-
# @param [String] value
|
139
|
-
# @return [void]
|
59
|
+
# (see MessageInterface#add_header)
|
140
60
|
def add_header(name, value)
|
141
61
|
@inner.add_header(name, value)
|
142
62
|
end
|
143
63
|
|
144
|
-
#
|
145
|
-
#
|
146
|
-
# Any existing headers will not be overwritten.
|
147
|
-
#
|
148
|
-
# @param array headers
|
149
|
-
# @return [void]
|
64
|
+
# (see MessageInterface#add_headers)
|
150
65
|
def add_headers(headers)
|
151
66
|
@inner.add_headers(headers)
|
152
67
|
end
|
153
68
|
|
154
|
-
#
|
155
|
-
#
|
156
|
-
# The specified header name must be treated as case-insenstive.
|
157
|
-
# This method should return true if the header was successfully deleted,
|
158
|
-
# and false if the header did not exist.
|
159
|
-
#
|
160
|
-
# @return bool
|
69
|
+
# (see MessageInterface#remove_header)
|
161
70
|
def remove_header(name)
|
162
71
|
@inner.remove_header(name)
|
163
72
|
end
|
164
73
|
|
165
|
-
#
|
166
|
-
#
|
167
|
-
# Should be 1.0 or 1.1.
|
168
|
-
#
|
169
|
-
# @param [String] version
|
170
|
-
# @return [void]
|
74
|
+
# (see MessageInterface#http_version=)
|
171
75
|
def http_version=(version)
|
172
76
|
@inner.http_version = version
|
173
77
|
end
|
174
78
|
|
175
|
-
#
|
176
|
-
#
|
177
|
-
# @return [String]
|
79
|
+
# (see MessageInterface#http_version)
|
178
80
|
def http_version
|
179
81
|
@inner.http_version
|
180
82
|
end
|
@@ -8,7 +8,7 @@ module Tilia
|
|
8
8
|
# Note that the stream may not be rewindable, and therefore may only be
|
9
9
|
# read once.
|
10
10
|
#
|
11
|
-
# @return
|
11
|
+
# @return [IO, StringIO]
|
12
12
|
def body_as_stream
|
13
13
|
end
|
14
14
|
|
@@ -25,30 +25,30 @@ module Tilia
|
|
25
25
|
#
|
26
26
|
# This could be either a string or a stream.
|
27
27
|
#
|
28
|
-
# @return
|
28
|
+
# @return [String, IO, StringIO]
|
29
29
|
def body
|
30
30
|
end
|
31
31
|
|
32
32
|
# Updates the body resource with a new stream.
|
33
33
|
#
|
34
|
-
# @param
|
34
|
+
# @param [String, #read] body
|
35
35
|
# @return [void]
|
36
|
-
def body=(
|
36
|
+
def body=(body)
|
37
37
|
end
|
38
38
|
|
39
39
|
# Returns all the HTTP headers as an array.
|
40
40
|
#
|
41
41
|
# Every header is returned as an array, with one or more values.
|
42
42
|
#
|
43
|
-
# @return
|
43
|
+
# @return [Hash]
|
44
44
|
def headers
|
45
45
|
end
|
46
46
|
|
47
47
|
# Will return true or false, depending on if a HTTP header exists.
|
48
48
|
#
|
49
49
|
# @param [String] name
|
50
|
-
# @return
|
51
|
-
def header?(
|
50
|
+
# @return [Boolean]
|
51
|
+
def header?(name)
|
52
52
|
end
|
53
53
|
|
54
54
|
# Returns a specific HTTP header, based on it's name.
|
@@ -65,7 +65,7 @@ module Tilia
|
|
65
65
|
#
|
66
66
|
# @param [String] name
|
67
67
|
# @return [String, nil]
|
68
|
-
def header(
|
68
|
+
def header(name)
|
69
69
|
end
|
70
70
|
|
71
71
|
# Returns a HTTP header as an array.
|
@@ -76,8 +76,8 @@ module Tilia
|
|
76
76
|
# If the header did not exists, this method will return an empty array.
|
77
77
|
#
|
78
78
|
# @param [String] name
|
79
|
-
# @return [String]
|
80
|
-
def header_as_array(
|
79
|
+
# @return [Array<String>]
|
80
|
+
def header_as_array(name)
|
81
81
|
end
|
82
82
|
|
83
83
|
# Updates a HTTP header.
|
@@ -89,7 +89,7 @@ module Tilia
|
|
89
89
|
# @param [String] name
|
90
90
|
# @param [String, Array<String>] value
|
91
91
|
# @return [void]
|
92
|
-
def update_header(
|
92
|
+
def update_header(name, value)
|
93
93
|
end
|
94
94
|
|
95
95
|
# Sets a new set of HTTP headers.
|
@@ -99,9 +99,9 @@ module Tilia
|
|
99
99
|
#
|
100
100
|
# Any header that already existed will be overwritten.
|
101
101
|
#
|
102
|
-
# @param
|
102
|
+
# @param [Hash] headers
|
103
103
|
# @return [void]
|
104
|
-
def update_headers(
|
104
|
+
def update_headers(headers)
|
105
105
|
end
|
106
106
|
|
107
107
|
# Adds a HTTP header.
|
@@ -113,16 +113,16 @@ module Tilia
|
|
113
113
|
# @param [String] name
|
114
114
|
# @param [String] value
|
115
115
|
# @return [void]
|
116
|
-
def add_header(
|
116
|
+
def add_header(name, value)
|
117
117
|
end
|
118
118
|
|
119
119
|
# Adds a new set of HTTP headers.
|
120
120
|
#
|
121
121
|
# Any existing headers will not be overwritten.
|
122
122
|
#
|
123
|
-
# @param
|
123
|
+
# @param [Hash] headers
|
124
124
|
# @return [void]
|
125
|
-
def add_headers(
|
125
|
+
def add_headers(headers)
|
126
126
|
end
|
127
127
|
|
128
128
|
# Removes a HTTP header.
|
@@ -131,8 +131,9 @@ module Tilia
|
|
131
131
|
# This method should return true if the header was successfully deleted,
|
132
132
|
# and false if the header did not exist.
|
133
133
|
#
|
134
|
+
# @param [String] name
|
134
135
|
# @return bool
|
135
|
-
def remove_header(
|
136
|
+
def remove_header(name)
|
136
137
|
end
|
137
138
|
|
138
139
|
# Sets the HTTP version.
|
@@ -141,7 +142,7 @@ module Tilia
|
|
141
142
|
#
|
142
143
|
# @param [String] version
|
143
144
|
# @return [void]
|
144
|
-
def http_version=(
|
145
|
+
def http_version=(version)
|
145
146
|
end
|
146
147
|
|
147
148
|
# Returns the HTTP version.
|