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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f7b1b04def12b6d6a9f842167374739dd6210e7d
|
4
|
+
data.tar.gz: 71c6a0a0f8c575c91b6feef757f586833e9b12f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc7eace9da8196a66d914e0e337193c236dc5f2fbcfcff1a1d2ea94e8eace45d485050d88417046e12ada16f34321b658f56df3587f74f2ec533836eb9a984de
|
7
|
+
data.tar.gz: 2e6c6e45eb6361ef0b316860f2dcfde64d5372fec663470c4bc2c4d1fe446b056ef01e16b0bd0c87a441ee1345b395242811edb5980401aef227a446dcf620bc
|
data/CHANGELOG.sabre.md
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
ChangeLog
|
2
2
|
=========
|
3
3
|
|
4
|
+
4.2.1 (2016-01-06)
|
5
|
+
------------------
|
6
|
+
|
7
|
+
* #56: `getBodyAsString` now returns at most as many bytes as the contents of
|
8
|
+
the `Content-Length` header. This allows users to pass much larger strings
|
9
|
+
without having to copy and truncate them.
|
10
|
+
|
11
|
+
|
12
|
+
4.2.0 (2016-01-04)
|
13
|
+
------------------
|
14
|
+
|
15
|
+
* This package now supports sabre/event 3.0.
|
16
|
+
* The client now sets a default `User-Agent` header identifying this library.
|
17
|
+
|
18
|
+
|
4
19
|
4.1.0 (2015-09-04)
|
5
20
|
------------------
|
6
21
|
|
data/Gemfile
CHANGED
@@ -1,14 +1,6 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
|
4
|
-
gem 'tilia-event', '~> 2.0'
|
5
|
-
gem 'tilia-uri', '~> 1.0'
|
6
|
-
|
7
|
-
# External dependencies
|
8
|
-
gem 'activesupport', '~> 4.2'
|
9
|
-
gem 'typhoeus', '~> 0.8'
|
10
|
-
gem 'rchardet', '~>1.6'
|
11
|
-
gem 'rack', '~> 1.6'
|
3
|
+
gemspec
|
12
4
|
|
13
5
|
# Testing
|
14
6
|
gem 'rake'
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,18 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
tilia-http (4.2.1)
|
5
|
+
activesupport (>= 4.0)
|
6
|
+
rack (~> 1.6)
|
7
|
+
rchardet (~> 1.6)
|
8
|
+
tilia-event (~> 2.0)
|
9
|
+
tilia-uri (~> 1.0)
|
10
|
+
typhoeus (~> 0.8)
|
11
|
+
|
1
12
|
GEM
|
2
13
|
remote: https://rubygems.org/
|
3
14
|
specs:
|
4
|
-
activesupport (4.2.5)
|
15
|
+
activesupport (4.2.5.1)
|
5
16
|
i18n (~> 0.7)
|
6
17
|
json (~> 1.7, >= 1.7.7)
|
7
18
|
minitest (~> 5.1)
|
@@ -11,7 +22,7 @@ GEM
|
|
11
22
|
astrolabe (1.3.1)
|
12
23
|
parser (~> 2.2)
|
13
24
|
docile (1.1.5)
|
14
|
-
ethon (0.8.
|
25
|
+
ethon (0.8.1)
|
15
26
|
ffi (>= 1.3.0)
|
16
27
|
ffi (1.9.10)
|
17
28
|
i18n (0.7.0)
|
@@ -40,8 +51,8 @@ GEM
|
|
40
51
|
thread_safe (0.3.5)
|
41
52
|
tilia-event (2.0.2)
|
42
53
|
activesupport (~> 4.2)
|
43
|
-
tilia-uri (1.0.1)
|
44
|
-
activesupport (
|
54
|
+
tilia-uri (1.0.1.1)
|
55
|
+
activesupport (>= 4.0)
|
45
56
|
tins (1.6.0)
|
46
57
|
typhoeus (0.8.0)
|
47
58
|
ethon (>= 0.8.0)
|
@@ -53,16 +64,11 @@ PLATFORMS
|
|
53
64
|
ruby
|
54
65
|
|
55
66
|
DEPENDENCIES
|
56
|
-
activesupport (~> 4.2)
|
57
67
|
minitest (~> 5.8)
|
58
|
-
rack (~> 1.6)
|
59
68
|
rake
|
60
|
-
rchardet (~> 1.6)
|
61
69
|
rubocop (~> 0.34)
|
62
70
|
simplecov (~> 0.10)
|
63
|
-
tilia-
|
64
|
-
tilia-uri (~> 1.0)
|
65
|
-
typhoeus (~> 0.8)
|
71
|
+
tilia-http!
|
66
72
|
yard (~> 0.8)
|
67
73
|
|
68
74
|
BUNDLED WITH
|
data/examples/asyncclient.rb
CHANGED
@@ -3,13 +3,9 @@
|
|
3
3
|
#
|
4
4
|
# By default up to 10 requests will be executed in paralel. HTTP connections
|
5
5
|
# are re-used and DNS is cached, all thanks to the power of curl.
|
6
|
-
#
|
7
|
-
# @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
|
8
|
-
# @author Evert Pot (http://evertpot.com/)
|
9
|
-
# @license http://sabre.io/license/ Modified BSD License
|
10
6
|
|
11
7
|
# Expected to be called "bundle exec examples/asyncclient.rb"
|
12
|
-
require '
|
8
|
+
require 'tilia/http'
|
13
9
|
|
14
10
|
# This is the request we're repeating a 1000 times.
|
15
11
|
request = Tilia::Http::Request.new('GET', 'http://localhost/')
|
data/examples/basicauth.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# This example does not work because of rack ...
|
3
3
|
# This example shows how to do Basic authentication.
|
4
|
-
# *
|
5
|
-
# @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
|
6
|
-
# @author Evert Pot (http://evertpot.com/)
|
7
|
-
# @license http://sabre.io/license/ Modified BSD License
|
8
4
|
|
9
5
|
# Expected to be called "bundle exec examples/basicauth.rb"
|
10
|
-
require '
|
6
|
+
require 'tilia/http'
|
11
7
|
require 'rack'
|
12
8
|
|
13
9
|
app = proc do |env|
|
data/examples/client.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# This example shows how to make a HTTP request with the Request and Response
|
3
3
|
# objects.
|
4
|
-
#
|
5
|
-
# @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
|
6
|
-
# @author Evert Pot (http://evertpot.com/)
|
7
|
-
# @license http://sabre.io/license/ Modified BSD License
|
8
4
|
|
9
5
|
# Expected to be called "bundle exec examples/client.rb"
|
10
|
-
require '
|
6
|
+
require 'tilia/http'
|
11
7
|
|
12
8
|
# Constructing the request.
|
13
9
|
request = Tilia::Http::Request.new('GET', 'http://www.jakobsack.de/')
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This example does not work because of rack ...
|
3
|
+
# This example shows how to do Basic authentication.
|
4
|
+
|
5
|
+
# Expected to be called "bundle exec examples/basicauth.rb"
|
6
|
+
require 'tilia/http'
|
7
|
+
require 'rack'
|
8
|
+
|
9
|
+
app = proc do |env|
|
10
|
+
user_list = {
|
11
|
+
'user1' => 'password',
|
12
|
+
'user2' => 'password'
|
13
|
+
}
|
14
|
+
|
15
|
+
sapi = Tilia::Http::Sapi.new(env)
|
16
|
+
request = sapi.request
|
17
|
+
response = Tilia::Http::Response.new
|
18
|
+
|
19
|
+
digest_auth = Tilia::Http::Auth::Digest.new('Locked down area', request, response)
|
20
|
+
digest_auth.init
|
21
|
+
|
22
|
+
if !(user_name = digest_auth.username)
|
23
|
+
# No username or password given
|
24
|
+
digest_auth.require_login
|
25
|
+
elsif !user_list.key?(user_name) || !digest_auth.validate_password(userlist[user_name])
|
26
|
+
# Username or password are incorrect
|
27
|
+
digest_auth.require_login
|
28
|
+
else
|
29
|
+
# Success !
|
30
|
+
response.body = 'You are logged in!'
|
31
|
+
end
|
32
|
+
|
33
|
+
# Sending the response
|
34
|
+
sapi.send_response(response)
|
35
|
+
end
|
36
|
+
|
37
|
+
Rack::Handler::WEBrick.run app
|
data/examples/reverseproxy.rb
CHANGED
data/examples/stringify.rb
CHANGED
@@ -4,13 +4,9 @@ require 'json'
|
|
4
4
|
# serialize themselves as strings.
|
5
5
|
#
|
6
6
|
# This is mainly useful for debugging purposes.
|
7
|
-
#
|
8
|
-
# @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
|
9
|
-
# @author Evert Pot (http://evertpot.com/)
|
10
|
-
# @license http://sabre.io/license/ Modified BSD License
|
11
7
|
|
12
8
|
# Expected to be called "bundle exec examples/stringify.rb"
|
13
|
-
require '
|
9
|
+
require 'tilia/http'
|
14
10
|
|
15
11
|
request = Tilia::Http::Request.new('POST', '/foo')
|
16
12
|
request.update_headers(
|
@@ -5,25 +5,6 @@ module Tilia
|
|
5
5
|
#
|
6
6
|
# This class provides some common functionality for the various base classes.
|
7
7
|
class AbstractAuth
|
8
|
-
protected
|
9
|
-
|
10
|
-
# Authentication realm
|
11
|
-
#
|
12
|
-
# @return [String]
|
13
|
-
attr_accessor :realm
|
14
|
-
|
15
|
-
# Request object
|
16
|
-
#
|
17
|
-
# @return [RequestInterface]
|
18
|
-
attr_accessor :request
|
19
|
-
|
20
|
-
# Response object
|
21
|
-
#
|
22
|
-
# @return [ResponseInterface]
|
23
|
-
attr_accessor :response
|
24
|
-
|
25
|
-
public
|
26
|
-
|
27
8
|
# Creates the object
|
28
9
|
#
|
29
10
|
# @param [String] realm
|
data/lib/tilia/http/auth/aws.rb
CHANGED
@@ -8,20 +8,6 @@ module Tilia
|
|
8
8
|
#
|
9
9
|
# Use this class to leverage amazon's AWS authentication header
|
10
10
|
class Aws < Tilia::Http::Auth::AbstractAuth
|
11
|
-
protected
|
12
|
-
|
13
|
-
# The signature supplied by the HTTP client
|
14
|
-
#
|
15
|
-
# @return [String]
|
16
|
-
attr_accessor :signature
|
17
|
-
|
18
|
-
# The accesskey supplied by the HTTP client
|
19
|
-
#
|
20
|
-
# @return [String]
|
21
|
-
attr_accessor :access_key
|
22
|
-
|
23
|
-
public
|
24
|
-
|
25
11
|
# An error code, if any
|
26
12
|
#
|
27
13
|
# This value will be filled with one of the ERR_* constants
|
@@ -45,7 +31,7 @@ module Tilia
|
|
45
31
|
auth_header = auth_header.split(' ')
|
46
32
|
|
47
33
|
if auth_header[0] != 'AWS' || auth_header.size < 2
|
48
|
-
@error_code =
|
34
|
+
@error_code = ERR_NOAWSHEADER
|
49
35
|
return false
|
50
36
|
end
|
51
37
|
|
@@ -66,14 +52,14 @@ module Tilia
|
|
66
52
|
def validate(secret_key)
|
67
53
|
content_md5 = @request.header('Content-MD5')
|
68
54
|
|
69
|
-
if content_md5
|
55
|
+
if content_md5.present?
|
70
56
|
# We need to validate the integrity of the request
|
71
57
|
body = @request.body
|
72
58
|
@request.body = body
|
73
59
|
|
74
60
|
if content_md5 != Base64.strict_encode64(::Digest::MD5.digest(body.to_s))
|
75
61
|
# content-md5 header did not match md5 signature of body
|
76
|
-
@error_code =
|
62
|
+
@error_code = ERR_MD5CHECKSUMWRONG
|
77
63
|
return false
|
78
64
|
end
|
79
65
|
end
|
@@ -98,7 +84,7 @@ module Tilia
|
|
98
84
|
)
|
99
85
|
|
100
86
|
unless @signature == signature
|
101
|
-
@error_code =
|
87
|
+
@error_code = ERR_INVALIDSIGNATURE
|
102
88
|
return false
|
103
89
|
end
|
104
90
|
true
|
@@ -131,7 +117,7 @@ module Tilia
|
|
131
117
|
|
132
118
|
# Unknown format
|
133
119
|
unless date
|
134
|
-
@error_code =
|
120
|
+
@error_code = ERR_INVALIDDATEFORMAT
|
135
121
|
return false
|
136
122
|
end
|
137
123
|
|
@@ -140,7 +126,7 @@ module Tilia
|
|
140
126
|
|
141
127
|
# We allow 15 minutes around the current date/time
|
142
128
|
if date > max || date < min
|
143
|
-
@error_code =
|
129
|
+
@error_code = ERR_REQUESTTIMESKEWED
|
144
130
|
return false
|
145
131
|
end
|
146
132
|
|
@@ -180,7 +166,7 @@ module Tilia
|
|
180
166
|
OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), key, message)
|
181
167
|
end
|
182
168
|
|
183
|
-
#
|
169
|
+
# Initialize instance variables
|
184
170
|
def initialize(realm = 'TiliaTooth', request, response)
|
185
171
|
super
|
186
172
|
@error_code = 0
|
@@ -23,19 +23,9 @@ module Tilia
|
|
23
23
|
QOP_AUTH = 1
|
24
24
|
QOP_AUTHINT = 2
|
25
25
|
|
26
|
-
protected
|
27
|
-
|
28
|
-
attr_accessor :nonce
|
29
|
-
attr_accessor :opaque
|
30
|
-
attr_accessor :digest_parts
|
31
|
-
attr_accessor :a1
|
32
|
-
attr_reader :qop
|
33
|
-
|
34
|
-
public
|
35
|
-
|
36
26
|
# Initializes the object
|
37
27
|
def initialize(realm = 'TiliaTooth', request, response)
|
38
|
-
@qop =
|
28
|
+
@qop = QOP_AUTH
|
39
29
|
|
40
30
|
@nonce = ::Digest::SHA1.hexdigest((Time.now.to_f + rand).to_s)[0..14]
|
41
31
|
@opaque = ::Digest::MD5.hexdigest(realm)
|
@@ -49,7 +39,7 @@ module Tilia
|
|
49
39
|
# @return [void]
|
50
40
|
def init
|
51
41
|
digest = self.digest || ''
|
52
|
-
@digest_parts = parse_digest(digest)
|
42
|
+
@digest_parts = parse_digest(digest) || {}
|
53
43
|
end
|
54
44
|
|
55
45
|
# Sets the quality of protection value.
|
@@ -64,8 +54,7 @@ module Tilia
|
|
64
54
|
# supported by most HTTP clients. QOP_AUTHINT also requires the entire
|
65
55
|
# request body to be md5'ed, which can put strains on CPU and memory.
|
66
56
|
#
|
67
|
-
# @
|
68
|
-
# @return [void]
|
57
|
+
# @return [Fixnum]
|
69
58
|
attr_writer :qop
|
70
59
|
|
71
60
|
# Validates the user.
|
@@ -73,7 +62,7 @@ module Tilia
|
|
73
62
|
# The A1 parameter should be md5(username . ':' . realm . ':' . password)
|
74
63
|
#
|
75
64
|
# @param [String] a1
|
76
|
-
# @return
|
65
|
+
# @return [Boolean]
|
77
66
|
def validate_a1(a1)
|
78
67
|
@a1 = a1
|
79
68
|
validate
|
@@ -83,7 +72,7 @@ module Tilia
|
|
83
72
|
# It is strongly recommended not store the password in plain-text and use validateA1 instead.
|
84
73
|
#
|
85
74
|
# @param [String] password
|
86
|
-
# @return
|
75
|
+
# @return [Boolean]
|
87
76
|
def validate_password(password)
|
88
77
|
return false unless @digest_parts.any? # RUBY
|
89
78
|
|
@@ -102,7 +91,7 @@ module Tilia
|
|
102
91
|
|
103
92
|
# Validates the digest challenge
|
104
93
|
#
|
105
|
-
# @return
|
94
|
+
# @return [Boolean]
|
106
95
|
def validate
|
107
96
|
return false unless @digest_parts.any? # RUBY
|
108
97
|
|
@@ -110,7 +99,7 @@ module Tilia
|
|
110
99
|
|
111
100
|
if @digest_parts['qop'] == 'auth-int'
|
112
101
|
# Making sure we support this qop value
|
113
|
-
return false unless @qop &
|
102
|
+
return false unless @qop & QOP_AUTHINT
|
114
103
|
|
115
104
|
# We need to add an md5 of the entire request body to the A2 part of the hash
|
116
105
|
body = @request.body_as_string
|
@@ -119,7 +108,7 @@ module Tilia
|
|
119
108
|
a2 << ':' + ::Digest::MD5.hexdigest(body)
|
120
109
|
else
|
121
110
|
# We need to make sure we support this qop value
|
122
|
-
return false unless @qop &
|
111
|
+
return false unless @qop & QOP_AUTH
|
123
112
|
end
|
124
113
|
|
125
114
|
a2 = ::Digest::MD5.hexdigest(a2)
|
@@ -138,11 +127,11 @@ module Tilia
|
|
138
127
|
def require_login
|
139
128
|
qop = ''
|
140
129
|
case @qop
|
141
|
-
when
|
130
|
+
when QOP_AUTH
|
142
131
|
qop = 'auth'
|
143
|
-
when
|
132
|
+
when QOP_AUTHINT
|
144
133
|
qop = 'auth-int'
|
145
|
-
when
|
134
|
+
when QOP_AUTH | QOP_AUTHINT
|
146
135
|
qop = 'auth,auth-int'
|
147
136
|
end
|
148
137
|
|
@@ -156,7 +145,7 @@ module Tilia
|
|
156
145
|
#
|
157
146
|
# If the header could not be found, null will be returned
|
158
147
|
#
|
159
|
-
# @return
|
148
|
+
# @return [String, nil]
|
160
149
|
def digest
|
161
150
|
@request.header('Authorization')
|
162
151
|
end
|
@@ -165,10 +154,10 @@ module Tilia
|
|
165
154
|
|
166
155
|
# Parses the different pieces of the digest string into an array.
|
167
156
|
#
|
168
|
-
# This method returns
|
157
|
+
# This method returns nil if an incomplete digest was supplied
|
169
158
|
#
|
170
159
|
# @param [String] digest
|
171
|
-
# @return
|
160
|
+
# @return [Hash, nil]
|
172
161
|
def parse_digest(digest)
|
173
162
|
# protect against missing data
|
174
163
|
needed_parts = { 'nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1 }
|
@@ -179,7 +168,7 @@ module Tilia
|
|
179
168
|
needed_parts.delete m1
|
180
169
|
end
|
181
170
|
|
182
|
-
needed_parts.any? ?
|
171
|
+
needed_parts.any? ? nil : data
|
183
172
|
end
|
184
173
|
end
|
185
174
|
end
|
data/lib/tilia/http/client.rb
CHANGED
@@ -31,44 +31,26 @@ module Tilia
|
|
31
31
|
# It's also possible to intercept specific http errors, by subscribing to for
|
32
32
|
# example 'error:401'.
|
33
33
|
class Client < Tilia::Event::EventEmitter
|
34
|
-
protected
|
35
|
-
|
36
|
-
# List of curl settings
|
37
|
-
#
|
38
|
-
# @return array
|
39
|
-
attr_accessor :curl_settings
|
40
|
-
|
41
|
-
# Wether or not exceptions should be thrown when a HTTP error is returned.
|
42
|
-
#
|
43
|
-
# @return bool
|
44
|
-
attr_accessor :throw_exceptions
|
45
|
-
|
46
|
-
# The maximum number of times we'll follow a redirect.
|
47
|
-
#
|
48
|
-
# @return int
|
49
|
-
attr_accessor :max_redirects
|
50
|
-
|
51
|
-
public
|
52
|
-
|
53
34
|
# Initializes the client.
|
54
35
|
#
|
55
36
|
# @return [void]
|
56
37
|
def initialize
|
57
|
-
|
38
|
+
super
|
58
39
|
|
59
40
|
@hydra = nil
|
60
41
|
@throw_exceptions = false
|
61
42
|
@max_redirects = 5
|
62
43
|
@curl_settings = {
|
63
44
|
header: false, # RUBY otherwise header will be part of response.body
|
64
|
-
nobody: false
|
45
|
+
nobody: false,
|
46
|
+
useragent: "tilia-http/#{Version::VERSION} (http://sabre.io/)"
|
65
47
|
}
|
66
48
|
@client_map = {}
|
67
49
|
end
|
68
50
|
|
69
51
|
# Sends a request to a HTTP server, and returns a response.
|
70
52
|
#
|
71
|
-
# @param RequestInterface request
|
53
|
+
# @param [RequestInterface] request
|
72
54
|
# @return [ResponseInterface]
|
73
55
|
def send_request(request)
|
74
56
|
emit('beforeRequest', [request])
|
@@ -149,9 +131,9 @@ module Tilia
|
|
149
131
|
# After calling sendAsync, you must therefore occasionally call the poll
|
150
132
|
# method, or wait.
|
151
133
|
#
|
152
|
-
# @param RequestInterface request
|
153
|
-
# @param
|
154
|
-
# @param
|
134
|
+
# @param [RequestInterface] request
|
135
|
+
# @param [#call] success
|
136
|
+
# @param [#call] error
|
155
137
|
# @return [void]
|
156
138
|
def send_async(request, success = nil, error = nil)
|
157
139
|
emit('beforeRequest', [request])
|
@@ -166,7 +148,7 @@ module Tilia
|
|
166
148
|
# This method will return true if there are still requests waiting to
|
167
149
|
# return, and false if all the work is done.
|
168
150
|
#
|
169
|
-
# @return
|
151
|
+
# @return [Boolean]
|
170
152
|
def poll
|
171
153
|
# nothing to do?
|
172
154
|
return false if @client_map.empty?
|
@@ -186,7 +168,7 @@ module Tilia
|
|
186
168
|
curl_result = parse_curl_result(handler)
|
187
169
|
do_retry = false
|
188
170
|
|
189
|
-
if curl_result['status'] ==
|
171
|
+
if curl_result['status'] == STATUS_CURLERROR
|
190
172
|
e = Exception.new
|
191
173
|
|
192
174
|
box = Box.new(do_retry)
|
@@ -202,7 +184,7 @@ module Tilia
|
|
202
184
|
curl_result['request'] = request
|
203
185
|
|
204
186
|
error_callback.call(curl_result) if error_callback
|
205
|
-
elsif curl_result['status'] ==
|
187
|
+
elsif curl_result['status'] == STATUS_HTTPERROR
|
206
188
|
box = Box.new(do_retry)
|
207
189
|
emit('error', [request, curl_result['response'], box, retry_count])
|
208
190
|
emit("error:#{curl_result['http_code']}", [request, curl_result['response'], box, retry_count])
|
@@ -249,16 +231,15 @@ module Tilia
|
|
249
231
|
# This only works for the send method. Throwing exceptions for
|
250
232
|
# send_async is not supported.
|
251
233
|
#
|
252
|
-
# @
|
253
|
-
# @return [void]
|
234
|
+
# @return [Boolean]
|
254
235
|
attr_writer :throw_exceptions
|
255
236
|
|
256
237
|
# Adds a CURL setting.
|
257
238
|
#
|
258
239
|
# These settings will be included in every HTTP request.
|
259
240
|
#
|
260
|
-
# @param
|
261
|
-
# @param
|
241
|
+
# @param [Symbol] name
|
242
|
+
# @param value
|
262
243
|
# @return [void]
|
263
244
|
def add_curl_setting(name, value)
|
264
245
|
@curl_settings[name] = value
|
@@ -268,7 +249,7 @@ module Tilia
|
|
268
249
|
|
269
250
|
# This method is responsible for performing a single request.
|
270
251
|
#
|
271
|
-
# @param RequestInterface request
|
252
|
+
# @param [RequestInterface] request
|
272
253
|
# @return [ResponseInterface]
|
273
254
|
def do_request(request)
|
274
255
|
client = create_client(request)
|
@@ -276,36 +257,13 @@ module Tilia
|
|
276
257
|
|
277
258
|
response = parse_curl_result(client)
|
278
259
|
|
279
|
-
if response['status'] ==
|
260
|
+
if response['status'] == STATUS_CURLERROR
|
280
261
|
fail Tilia::Http::ClientException.new(response['curl_errno']), response['curl_errmsg']
|
281
262
|
end
|
282
263
|
|
283
264
|
response['response']
|
284
265
|
end
|
285
266
|
|
286
|
-
protected
|
287
|
-
|
288
|
-
# Cached curl handle.
|
289
|
-
#
|
290
|
-
# By keeping this resource around for the lifetime of this object, things
|
291
|
-
# like persistent connections are possible.
|
292
|
-
#
|
293
|
-
# @return resource
|
294
|
-
attr_accessor :curl_handle
|
295
|
-
|
296
|
-
# Handler for curl_multi requests.
|
297
|
-
#
|
298
|
-
# The first time sendAsync is used, this will be created.
|
299
|
-
#
|
300
|
-
# @return resource
|
301
|
-
attr_accessor :curl_multi_handle
|
302
|
-
|
303
|
-
# Has a list of curl handles, as well as their associated success and
|
304
|
-
# error callbacks.
|
305
|
-
#
|
306
|
-
# @return array
|
307
|
-
attr_accessor :curl_multi_map
|
308
|
-
|
309
267
|
public
|
310
268
|
|
311
269
|
STATUS_SUCCESS = 0
|
@@ -326,14 +284,13 @@ module Tilia
|
|
326
284
|
# * http_code - HTTP status code, as an int. Only set if Only set if
|
327
285
|
# status is STATUS_SUCCESS, or STATUS_HTTPERROR
|
328
286
|
#
|
329
|
-
# @param [
|
330
|
-
# @
|
331
|
-
# @return Response
|
287
|
+
# @param [Typhoeus::Request] client
|
288
|
+
# @return [Response]
|
332
289
|
def parse_curl_result(client)
|
333
290
|
client_response = client.response
|
334
291
|
unless client_response.return_code == :ok
|
335
292
|
return {
|
336
|
-
'status' =>
|
293
|
+
'status' => STATUS_CURLERROR,
|
337
294
|
'curl_errno' => client_response.return_code,
|
338
295
|
'curl_errmsg' => client_response.return_message
|
339
296
|
}
|
@@ -371,7 +328,7 @@ module Tilia
|
|
371
328
|
http_code = response.status.to_i
|
372
329
|
|
373
330
|
{
|
374
|
-
'status' => http_code >= 400 ?
|
331
|
+
'status' => http_code >= 400 ? STATUS_HTTPERROR : STATUS_SUCCESS,
|
375
332
|
'response' => response,
|
376
333
|
'http_code' => http_code
|
377
334
|
}
|
@@ -382,10 +339,10 @@ module Tilia
|
|
382
339
|
# We keep this in a separate method, so we can call it without triggering
|
383
340
|
# the beforeRequest event and don't do the poll.
|
384
341
|
#
|
385
|
-
# @param RequestInterface request
|
386
|
-
# @param
|
387
|
-
# @param
|
388
|
-
# @param
|
342
|
+
# @param [RequestInterface] request
|
343
|
+
# @param [#call] success
|
344
|
+
# @param [#call] error
|
345
|
+
# @param [Fixnum] retry_count
|
389
346
|
def send_async_internal(request, success, error, retry_count = 0)
|
390
347
|
@hydra = Typhoeus::Hydra.hydra unless @hydra
|
391
348
|
|
@@ -2,7 +2,7 @@ module Tilia
|
|
2
2
|
module Http
|
3
3
|
# This exception may be emitted by the HTTP\Client class, in case there was a
|
4
4
|
# problem emitting the request.
|
5
|
-
class ClientException <
|
5
|
+
class ClientException < StandardError
|
6
6
|
# TODO: document
|
7
7
|
def initialize(code)
|
8
8
|
@code = code.to_i
|
@@ -5,25 +5,16 @@ module Tilia
|
|
5
5
|
# By default the Client will not emit these, this has to be explicitly enabled
|
6
6
|
# with the setThrowExceptions method.
|
7
7
|
class ClientHttpException < Tilia::Http::HttpException
|
8
|
-
protected
|
9
|
-
|
10
|
-
# Response object
|
11
|
-
#
|
12
|
-
# @return [ResponseInterface]
|
13
|
-
attr_accessor :response
|
14
|
-
|
15
|
-
public
|
16
|
-
|
17
8
|
# Constructor
|
18
9
|
#
|
19
|
-
# @param ResponseInterface response
|
10
|
+
# @param [ResponseInterface] response
|
20
11
|
def initialize(response)
|
21
12
|
@response = response
|
22
13
|
end
|
23
14
|
|
24
15
|
# The http status code for the error.
|
25
16
|
#
|
26
|
-
# @return
|
17
|
+
# @return [Fixnum]
|
27
18
|
def http_status
|
28
19
|
@response.status
|
29
20
|
end
|