tickethub 0.3.51 → 0.3.52
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/lib/tickethub/connection.rb +66 -32
- data/lib/tickethub/exceptions.rb +44 -17
- data/lib/tickethub/helpers.rb +33 -1
- data/lib/tickethub/request.rb +72 -51
- data/lib/tickethub/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c3d2fbee50f8b1649c00ce062145feba07d6ad1
|
4
|
+
data.tar.gz: e5ab1ddb6e9503d8d3a7b77c834f04223765f96b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e148ff6eede8074c3b76be0f36f69f79c5143fcf20bba3f6ef79d2784c7c5a90dceebacc38543ff7b8bab5b141be45877f2d0d243fa197442606d5fda4ed639f
|
7
|
+
data.tar.gz: 67e18750bd49ba334f9092d31caa2642e412b9a8d67f0d654a27698608fcbd42deb867d6f7bf4f8b356d09ffa8545b1b5eb96ba258280f58f6e01ce5b5a0c455
|
data/lib/tickethub/connection.rb
CHANGED
@@ -40,6 +40,10 @@ module Tickethub
|
|
40
40
|
request(:head, path, headers, &block)
|
41
41
|
end
|
42
42
|
|
43
|
+
def put(path, body = '', headers = {}, &block)
|
44
|
+
request(:put, path, body, headers, &block)
|
45
|
+
end
|
46
|
+
|
43
47
|
def patch(path, body = '', headers = {}, &block)
|
44
48
|
request(:patch, path, body, headers, &block)
|
45
49
|
end
|
@@ -50,48 +54,72 @@ module Tickethub
|
|
50
54
|
|
51
55
|
protected
|
52
56
|
|
57
|
+
def request=(request)
|
58
|
+
@request = request
|
59
|
+
end
|
60
|
+
|
53
61
|
# Makes a request to the remote service.
|
54
62
|
def request(method, path, *arguments)
|
55
63
|
response = http.send(method, path, *arguments)
|
64
|
+
response.uri = URI.join(endpoint, path)
|
65
|
+
|
56
66
|
handle_response(response)
|
57
67
|
|
58
|
-
rescue Timeout::Error => e
|
59
|
-
raise TimeoutError.new(e.message)
|
68
|
+
rescue Timeout::Error, Net::OpenTimeout => e
|
69
|
+
raise TimeoutError.new(@request, e.message)
|
60
70
|
rescue OpenSSL::SSL::SSLError => e
|
61
|
-
raise SSLError.new(e.message)
|
71
|
+
raise SSLError.new(@request, e.message)
|
72
|
+
rescue SocketError,
|
73
|
+
EOFError,
|
74
|
+
Net::HTTPBadResponse,
|
75
|
+
Net::HTTPHeaderSyntaxError,
|
76
|
+
Net::HTTPServerException,
|
77
|
+
Net::ProtocolError,
|
78
|
+
Errno::ECONNABORTED,
|
79
|
+
Errno::ECONNREFUSED,
|
80
|
+
Errno::ECONNRESET,
|
81
|
+
Errno::ETIMEDOUT,
|
82
|
+
Errno::ENETUNREACH,
|
83
|
+
Errno::EHOSTUNREACH,
|
84
|
+
Errno::EINVAL,
|
85
|
+
Errno::ENOPROTOOPT => e
|
86
|
+
raise ErrnoError.new(@request, e.message)
|
87
|
+
rescue Zlib::DataError,
|
88
|
+
Zlib::BufError => e
|
89
|
+
raise ZlibError.new(@request, e.message)
|
62
90
|
end
|
63
91
|
|
64
92
|
# Handles response and error codes from the remote service.
|
65
93
|
def handle_response(response)
|
66
94
|
case response.code.to_i
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
+
when 200...299
|
96
|
+
response
|
97
|
+
when 300..399
|
98
|
+
raise Redirection.new(@request, response)
|
99
|
+
when 400
|
100
|
+
raise BadRequest.new(@request, response)
|
101
|
+
when 401
|
102
|
+
raise UnauthorizedAccess.new(@request, response)
|
103
|
+
when 403
|
104
|
+
raise ForbiddenAccess.new(@request, response)
|
105
|
+
when 404
|
106
|
+
raise ResourceNotFound.new(@request, response)
|
107
|
+
when 405
|
108
|
+
raise MethodNotAllowed.new(@request, response)
|
109
|
+
when 409
|
110
|
+
raise ResourceConflict.new(@request, response)
|
111
|
+
when 410
|
112
|
+
raise ResourceGone.new(@request, response)
|
113
|
+
when 422
|
114
|
+
raise ResourceInvalid.new(@request, response)
|
115
|
+
when 401...500
|
116
|
+
raise ClientError.new(@request, response)
|
117
|
+
when 500...600
|
118
|
+
raise ServerError.new(@request, response)
|
119
|
+
else
|
120
|
+
raise ResponseError.new(
|
121
|
+
@request, response, "Unknown response code: #{response.code}"
|
122
|
+
)
|
95
123
|
end
|
96
124
|
end
|
97
125
|
|
@@ -113,7 +141,13 @@ module Tickethub
|
|
113
141
|
|
114
142
|
def configure_http(http)
|
115
143
|
http = apply_ssl_options(http)
|
116
|
-
|
144
|
+
|
145
|
+
# Net::HTTP timeouts default to 60 seconds.
|
146
|
+
if timeout
|
147
|
+
http.open_timeout = timeout
|
148
|
+
http.read_timeout = timeout
|
149
|
+
end
|
150
|
+
|
117
151
|
http
|
118
152
|
end
|
119
153
|
|
data/lib/tickethub/exceptions.rb
CHANGED
@@ -1,44 +1,65 @@
|
|
1
1
|
module Tickethub
|
2
|
-
class
|
2
|
+
class Error < StandardError
|
3
|
+
attr_reader :request
|
4
|
+
|
5
|
+
def initialize(request = nil, message = nil)
|
6
|
+
super(message)
|
7
|
+
@request = request
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
ConnectionError = Error
|
12
|
+
RequestError = Error
|
13
|
+
|
14
|
+
class ResponseError < Error
|
3
15
|
attr_reader :response
|
4
16
|
|
5
|
-
def initialize(response, message = nil)
|
17
|
+
def initialize(request, response, message = nil)
|
18
|
+
super(request, message)
|
6
19
|
@response = response
|
7
|
-
@message = message
|
8
20
|
end
|
9
21
|
|
10
22
|
def to_s
|
11
23
|
message = "Failed."
|
12
24
|
message << " Response code = #{response.code}." if response.respond_to?(:code)
|
13
25
|
message << " Response message = #{response.message}." if response.respond_to?(:message)
|
14
|
-
|
26
|
+
|
27
|
+
if response.respond_to?(:body)
|
28
|
+
# Error messages need to be in UTF-8
|
29
|
+
body = response.body.dup.to_s
|
30
|
+
body = body.encode('UTF-8', :invalid => :replace, :undef => :replace, :replace => '?')
|
31
|
+
message << " Response Body = #{body}."
|
32
|
+
end
|
33
|
+
|
15
34
|
message
|
16
35
|
end
|
17
36
|
end
|
18
37
|
|
19
38
|
# Raised when a Timeout::Error occurs.
|
20
|
-
class TimeoutError <
|
21
|
-
def initialize(message)
|
22
|
-
@message = message
|
23
|
-
end
|
24
|
-
def to_s; @message ;end
|
39
|
+
class TimeoutError < RequestError
|
25
40
|
end
|
26
41
|
|
27
42
|
# Raised when a OpenSSL::SSL::SSLError occurs.
|
28
|
-
class SSLError <
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
43
|
+
class SSLError < RequestError
|
44
|
+
end
|
45
|
+
|
46
|
+
class ErrnoError < RequestError
|
47
|
+
end
|
48
|
+
|
49
|
+
class ZlibError < RequestError
|
33
50
|
end
|
34
51
|
|
35
52
|
# 3xx Redirection
|
36
|
-
class Redirection <
|
53
|
+
class Redirection < ResponseError # :nodoc:
|
54
|
+
def to_s; response['Location'] ? "#{super} => #{response['Location']}" : super; end
|
55
|
+
end
|
56
|
+
|
57
|
+
class RedirectionLoop < ResponseError # :nodoc:
|
37
58
|
def to_s; response['Location'] ? "#{super} => #{response['Location']}" : super; end
|
38
59
|
end
|
39
60
|
|
40
61
|
# 4xx Client Error
|
41
|
-
class ClientError <
|
62
|
+
class ClientError < ResponseError; end # :nodoc:
|
42
63
|
|
43
64
|
# 400 Bad Request
|
44
65
|
class BadRequest < ClientError; end # :nodoc
|
@@ -52,11 +73,17 @@ module Tickethub
|
|
52
73
|
# 404 Not Found
|
53
74
|
class ResourceNotFound < ClientError; end # :nodoc:
|
54
75
|
|
76
|
+
# 409 Conflict
|
77
|
+
class ResourceConflict < ClientError; end # :nodoc:
|
78
|
+
|
79
|
+
# 410 Gone
|
80
|
+
class ResourceGone < ClientError; end # :nodoc:
|
81
|
+
|
55
82
|
# 422 Invalid
|
56
83
|
class ResourceInvalid < ClientError; end # :nodoc:
|
57
84
|
|
58
85
|
# 5xx Server Error
|
59
|
-
class ServerError <
|
86
|
+
class ServerError < ResponseError; end # :nodoc:
|
60
87
|
|
61
88
|
# 405 Method Not Allowed
|
62
89
|
class MethodNotAllowed < ClientError # :nodoc:
|
data/lib/tickethub/helpers.rb
CHANGED
@@ -10,6 +10,14 @@ module Tickethub
|
|
10
10
|
value.to_s.split('_').map {|w| w.capitalize }.join
|
11
11
|
end
|
12
12
|
|
13
|
+
def deep_merge(hash, other_hash)
|
14
|
+
hash.merge(other_hash) do |key, oldval, newval|
|
15
|
+
oldval = oldval.to_hash if oldval.respond_to?(:to_hash)
|
16
|
+
newval = newval.to_hash if newval.respond_to?(:to_hash)
|
17
|
+
oldval.class.to_s == 'Hash' && newval.class.to_s == 'Hash' ? deep_merge(oldval, newval) : newval
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
13
21
|
# Stolen from Rack:
|
14
22
|
|
15
23
|
DEFAULT_SEP = /[&;] */n
|
@@ -30,6 +38,22 @@ module Tickethub
|
|
30
38
|
end
|
31
39
|
end
|
32
40
|
|
41
|
+
def to_url_param(value, prefix = nil)
|
42
|
+
case value
|
43
|
+
when Array
|
44
|
+
value.map { |v|
|
45
|
+
to_url_param(v, "#{prefix}[]")
|
46
|
+
}.join("&")
|
47
|
+
when Hash
|
48
|
+
value.map { |k, v|
|
49
|
+
to_url_param(v, prefix ? "#{prefix}[#{uri_escape(k)}]" : uri_escape(k))
|
50
|
+
}.join("&")
|
51
|
+
else
|
52
|
+
raise ArgumentError, "value must be a Hash" if prefix.nil?
|
53
|
+
"#{prefix}=#{uri_escape(value)}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
33
57
|
def from_param(param)
|
34
58
|
Rack::Utils.parse_nested_query(param)
|
35
59
|
(value || '').split('&').each do |res|
|
@@ -51,7 +75,15 @@ module Tickethub
|
|
51
75
|
end
|
52
76
|
|
53
77
|
def escape(s)
|
54
|
-
URI.encode_www_form_component(s)
|
78
|
+
URI.encode_www_form_component(s.to_s)
|
79
|
+
end
|
80
|
+
|
81
|
+
ESCAPE_RE = /[^a-zA-Z0-9 .~_-]/
|
82
|
+
|
83
|
+
def uri_escape(s)
|
84
|
+
s.to_s.gsub(ESCAPE_RE) {|match|
|
85
|
+
'%' + match.unpack('H2' * match.bytesize).join('%').upcase
|
86
|
+
}.tr(' ', '+')
|
55
87
|
end
|
56
88
|
|
57
89
|
if defined?(::Encoding)
|
data/lib/tickethub/request.rb
CHANGED
@@ -2,12 +2,12 @@ require 'securerandom'
|
|
2
2
|
|
3
3
|
module Tickethub
|
4
4
|
class Request
|
5
|
-
|
6
5
|
attr_reader :options, :format, :url
|
7
|
-
attr_accessor :params, :body, :method, :headers
|
8
6
|
|
9
|
-
|
10
|
-
|
7
|
+
attr_accessor :params, :body, :method, :headers,
|
8
|
+
:proxy, :user, :password, :retries,
|
9
|
+
:auth_type, :timeout, :ssl_options,
|
10
|
+
:max_attempts, :follow_redirection
|
11
11
|
|
12
12
|
def initialize(url, options = {})
|
13
13
|
@url = url.to_s
|
@@ -15,16 +15,19 @@ module Tickethub
|
|
15
15
|
@retries = 3
|
16
16
|
@timeout = 10
|
17
17
|
|
18
|
-
@options =
|
18
|
+
@options = {
|
19
|
+
:method => :get,
|
20
|
+
:params => {},
|
21
|
+
:headers => {},
|
22
|
+
:format => :form,
|
23
|
+
:max_attempts => 5,
|
24
|
+
:follow_redirection => true
|
25
|
+
}.merge(options)
|
26
|
+
|
19
27
|
@options.each do |key, val|
|
20
28
|
method = "#{key}="
|
21
29
|
send(method, val) if respond_to?(method)
|
22
30
|
end
|
23
|
-
|
24
|
-
self.method ||= :get
|
25
|
-
self.params ||= {}
|
26
|
-
self.headers ||= {}
|
27
|
-
self.format ||= :form
|
28
31
|
end
|
29
32
|
|
30
33
|
def format=(mime_or_format)
|
@@ -46,50 +49,86 @@ module Tickethub
|
|
46
49
|
@uri = URI.parse(url)
|
47
50
|
@uri.path = '/' if @uri.path.empty?
|
48
51
|
|
49
|
-
if @uri.query
|
50
|
-
@params.merge!(Helpers.from_param(@uri.query))
|
51
|
-
@uri.query = nil
|
52
|
-
end
|
53
|
-
|
54
52
|
@uri
|
55
53
|
end
|
56
54
|
|
55
|
+
def uri_params
|
56
|
+
uri.query ? Helpers.from_param(uri.query) : {}
|
57
|
+
end
|
58
|
+
|
57
59
|
def path
|
58
60
|
uri.path
|
59
61
|
end
|
60
62
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
def query_path
|
64
|
+
query_path = path.dup
|
65
|
+
query_params = uri_params.dup
|
66
|
+
query_params.merge!(params) unless encoded?
|
67
|
+
|
68
|
+
if query_params.any?
|
69
|
+
query_path += '?' + Helpers.to_url_param(query_params)
|
66
70
|
end
|
67
71
|
|
68
|
-
|
72
|
+
query_path
|
73
|
+
end
|
69
74
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
rescue Redirection => error
|
74
|
-
raise error unless error.response['Location']
|
75
|
-
location = URI.parse(error.response['Location'])
|
75
|
+
def encoded?
|
76
|
+
[:post, :put].include?(method)
|
77
|
+
end
|
76
78
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
end
|
79
|
+
def encoded
|
80
|
+
params.any? ? format.encode(params) : body
|
81
|
+
end
|
81
82
|
|
82
|
-
|
83
|
+
def execute
|
84
|
+
with_redirection do
|
85
|
+
if encoded?
|
86
|
+
result = connection.send(method, query_path, encoded, build_headers)
|
87
|
+
else
|
88
|
+
result = connection.send(method, query_path, build_headers)
|
89
|
+
end
|
90
|
+
|
91
|
+
Response.new(result, uri)
|
92
|
+
end
|
93
|
+
rescue ServerError, RequestError => err
|
94
|
+
raise err if (@retries -= 1) == 0
|
83
95
|
execute
|
84
96
|
end
|
85
97
|
|
86
98
|
protected
|
87
99
|
|
100
|
+
def with_redirection(&block)
|
101
|
+
attempts = 1
|
102
|
+
|
103
|
+
begin
|
104
|
+
yield
|
105
|
+
rescue Redirection => error
|
106
|
+
raise error unless follow_redirection
|
107
|
+
|
108
|
+
attempts += 1
|
109
|
+
|
110
|
+
raise error unless error.response['Location']
|
111
|
+
raise RedirectionLoop.new(self, error.response) if attempts > max_attempts
|
112
|
+
|
113
|
+
location = error.response['Location'].scrub
|
114
|
+
location = URI.parse(location)
|
115
|
+
|
116
|
+
# Path is relative
|
117
|
+
unless location.host
|
118
|
+
location = URI.join(uri, location)
|
119
|
+
end
|
120
|
+
|
121
|
+
self.url = location.to_s
|
122
|
+
retry
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
88
126
|
def connection
|
89
127
|
Connection.new(uri,
|
90
128
|
:proxy => proxy,
|
91
129
|
:timeout => timeout,
|
92
|
-
:ssl_options => ssl_options
|
130
|
+
:ssl_options => ssl_options,
|
131
|
+
:request => self
|
93
132
|
)
|
94
133
|
end
|
95
134
|
|
@@ -117,23 +156,5 @@ module Tickethub
|
|
117
156
|
.merge(headers)
|
118
157
|
.merge('X-Request-ID' => @id)
|
119
158
|
end
|
120
|
-
|
121
|
-
def query_path
|
122
|
-
query_path = path
|
123
|
-
|
124
|
-
if params.any?
|
125
|
-
query_path += '?' + Helpers.to_param(params)
|
126
|
-
end
|
127
|
-
|
128
|
-
query_path
|
129
|
-
end
|
130
|
-
|
131
|
-
def encoded?
|
132
|
-
[:post, :patch].include?(method)
|
133
|
-
end
|
134
|
-
|
135
|
-
def encoded
|
136
|
-
params.any? ? format.encode(params) : body
|
137
|
-
end
|
138
159
|
end
|
139
160
|
end
|
data/lib/tickethub/version.rb
CHANGED