tilia-http 4.1.0.8 → 4.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|