net-ping 1.7.4-universal-mingw32 → 1.7.5-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,16 +1,16 @@
1
- ########################################################################
2
- # example_pingexternal.rb
3
- #
4
- # A short sample program demonstrating an external ping. You can run
5
- # this program via the example:external task. Modify as you see fit.
6
- ########################################################################
7
- require 'net/ping'
8
-
9
- good = 'www.rubyforge.org'
10
- bad = 'foo.bar.baz'
11
-
12
- p1 = Net::Ping::External.new(good)
13
- p p1.ping?
14
-
15
- p2 = Net::Ping::External.new(bad)
16
- p p2.ping?
1
+ ########################################################################
2
+ # example_pingexternal.rb
3
+ #
4
+ # A short sample program demonstrating an external ping. You can run
5
+ # this program via the example:external task. Modify as you see fit.
6
+ ########################################################################
7
+ require 'net/ping'
8
+
9
+ good = 'www.rubyforge.org'
10
+ bad = 'foo.bar.baz'
11
+
12
+ p1 = Net::Ping::External.new(good)
13
+ p p1.ping?
14
+
15
+ p2 = Net::Ping::External.new(bad)
16
+ p p2.ping?
@@ -1,22 +1,22 @@
1
- ########################################################################
2
- # example_pinghttp.rb
3
- #
4
- # A short sample program demonstrating an http ping. You can run
5
- # this program via the example:http task. Modify as you see fit.
6
- ########################################################################
7
- require 'net/ping'
8
-
9
- good = 'http://www.google.com/index.html'
10
- bad = 'http://www.ruby-lang.org/index.html'
11
-
12
- puts "== Good ping, no redirect"
13
-
14
- p1 = Net::Ping::HTTP.new(good)
15
- p p1.ping?
16
-
17
- puts "== Bad ping"
18
-
19
- p2 = Net::Ping::HTTP.new(bad)
20
- p p2.ping?
21
- p p2.warning
22
- p p2.exception
1
+ ########################################################################
2
+ # example_pinghttp.rb
3
+ #
4
+ # A short sample program demonstrating an http ping. You can run
5
+ # this program via the example:http task. Modify as you see fit.
6
+ ########################################################################
7
+ require 'net/ping'
8
+
9
+ good = 'http://www.google.com/index.html'
10
+ bad = 'http://www.ruby-lang.org/index.html'
11
+
12
+ puts "== Good ping, no redirect"
13
+
14
+ p1 = Net::Ping::HTTP.new(good)
15
+ p p1.ping?
16
+
17
+ puts "== Bad ping"
18
+
19
+ p2 = Net::Ping::HTTP.new(bad)
20
+ p p2.ping?
21
+ p p2.warning
22
+ p p2.exception
@@ -1,16 +1,16 @@
1
- ########################################################################
2
- # example_pingtcp.rb
3
- #
4
- # A short sample program demonstrating a tcp ping. You can run
5
- # this program via the example:tcp task. Modify as you see fit.
6
- ########################################################################
7
- require 'net/ping'
8
-
9
- good = 'www.google.com'
10
- bad = 'foo.bar.baz'
11
-
12
- p1 = Net::Ping::TCP.new(good, 'http')
13
- p p1.ping?
14
-
15
- p2 = Net::Ping::TCP.new(bad)
16
- p p2.ping?
1
+ ########################################################################
2
+ # example_pingtcp.rb
3
+ #
4
+ # A short sample program demonstrating a tcp ping. You can run
5
+ # this program via the example:tcp task. Modify as you see fit.
6
+ ########################################################################
7
+ require 'net/ping'
8
+
9
+ good = 'www.google.com'
10
+ bad = 'foo.bar.baz'
11
+
12
+ p1 = Net::Ping::TCP.new(good, 'http')
13
+ p p1.ping?
14
+
15
+ p2 = Net::Ping::TCP.new(bad)
16
+ p p2.ping?
@@ -1,12 +1,12 @@
1
- ########################################################################
2
- # example_pingudp.rb
3
- #
4
- # A short sample program demonstrating a UDP ping. You can run
5
- # this program via the example:udp task. Modify as you see fit.
6
- ########################################################################
7
- require 'net/ping'
8
-
9
- host = 'www.google.com'
10
-
11
- u = Net::Ping::UDP.new(host)
12
- p u.ping?
1
+ ########################################################################
2
+ # example_pingudp.rb
3
+ #
4
+ # A short sample program demonstrating a UDP ping. You can run
5
+ # this program via the example:udp task. Modify as you see fit.
6
+ ########################################################################
7
+ require 'net/ping'
8
+
9
+ host = 'www.google.com'
10
+
11
+ u = Net::Ping::UDP.new(host)
12
+ p u.ping?
data/lib/net/ping.rb CHANGED
@@ -1,17 +1,17 @@
1
- # By doing a "require 'net/ping'" you are requiring every subclass. If you
2
- # want to require a specific ping type only, do "require 'net/ping/tcp'",
3
- # for example.
4
- #
5
- require 'rbconfig'
6
-
7
- require File.join(File.dirname(__FILE__), 'ping/tcp')
8
- require File.join(File.dirname(__FILE__), 'ping/udp')
9
- require File.join(File.dirname(__FILE__), 'ping/icmp')
10
- require File.join(File.dirname(__FILE__), 'ping/external')
11
- require File.join(File.dirname(__FILE__), 'ping/http')
12
-
13
- RbConfig = Config unless Object.const_defined?(:RbConfig)
14
-
15
- if File::ALT_SEPARATOR
16
- require File.join(File.dirname(__FILE__), 'ping/wmi')
17
- end
1
+ # By doing a "require 'net/ping'" you are requiring every subclass. If you
2
+ # want to require a specific ping type only, do "require 'net/ping/tcp'",
3
+ # for example.
4
+ #
5
+ require 'rbconfig'
6
+
7
+ require File.join(File.dirname(__FILE__), 'ping/tcp')
8
+ require File.join(File.dirname(__FILE__), 'ping/udp')
9
+ require File.join(File.dirname(__FILE__), 'ping/icmp')
10
+ require File.join(File.dirname(__FILE__), 'ping/external')
11
+ require File.join(File.dirname(__FILE__), 'ping/http')
12
+
13
+ RbConfig = Config unless Object.const_defined?(:RbConfig)
14
+
15
+ if File::ALT_SEPARATOR
16
+ require File.join(File.dirname(__FILE__), 'ping/wmi')
17
+ end
@@ -1,93 +1,101 @@
1
- require 'open3'
2
- require 'rbconfig'
3
-
4
- require File.join(File.dirname(__FILE__), 'ping')
5
-
6
- # The Net module serves as a namespace only.
7
- module Net
8
-
9
- # The Ping::External class encapsulates methods for external (system) pings.
10
- class Ping::External < Ping
11
- # Pings the host using your system's ping utility and checks for any
12
- # errors or warnings. Returns true if successful, or false if not.
13
- #
14
- # If the ping failed then the Ping::External#exception method should
15
- # contain a string indicating what went wrong. If the ping succeeded then
16
- # the Ping::External#warning method may or may not contain a value.
17
- #
18
- def ping(host = @host)
19
- super(host)
20
-
21
- pcmd = ['ping']
22
- bool = false
23
-
24
- case RbConfig::CONFIG['host_os']
25
- when /linux/i
26
- pcmd += ['-c', '1', '-W', @timeout.to_s, host]
27
- when /aix/i
28
- pcmd += ['-c', '1', '-w', @timeout.to_s, host]
29
- when /bsd|osx|mach|darwin/i
30
- pcmd += ['-c', '1', '-t', @timeout.to_s, host]
31
- when /solaris|sunos/i
32
- pcmd += [host, @timeout.to_s]
33
- when /hpux/i
34
- pcmd += [host, '-n1', '-m', @timeout.to_s]
35
- when /win32|windows|msdos|mswin|cygwin|mingw/i
36
- pcmd += ['-n', '1', '-w', (@timeout * 1000).to_s, host]
37
- else
38
- pcmd += [host]
39
- end
40
-
41
- start_time = Time.now
42
-
43
- begin
44
- err = nil
45
-
46
- Open3.popen3(*pcmd) do |stdin, stdout, stderr, thread|
47
- stdin.close
48
- err = stderr.gets # Can't chomp yet, might be nil
49
-
50
- case thread.value.exitstatus
51
- when 0
52
- info = stdout.read
53
- if info =~ /unreachable/ix # Windows
54
- bool = false
55
- @exception = "host unreachable"
56
- else
57
- bool = true # Success, at least one response.
58
- end
59
-
60
- if err & err =~ /warning/i
61
- @warning = err.chomp
62
- end
63
- when 2
64
- bool = false # Transmission successful, no response.
65
- @exception = err.chomp if err
66
- else
67
- bool = false # An error occurred
68
- if err
69
- @exception = err.chomp
70
- else
71
- stdout.each_line do |line|
72
- if line =~ /(timed out|could not find host|packet loss)/i
73
- @exception = line.chomp
74
- break
75
- end
76
- end
77
- end
78
- end
79
- end
80
- rescue Exception => error
81
- @exception = error.message
82
- end
83
-
84
- # There is no duration if the ping failed
85
- @duration = Time.now - start_time if bool
86
-
87
- bool
88
- end
89
-
90
- alias ping? ping
91
- alias pingecho ping
92
- end
93
- end
1
+ require 'open3'
2
+ require 'rbconfig'
3
+
4
+ require File.join(File.dirname(__FILE__), 'ping')
5
+
6
+ # The Net module serves as a namespace only.
7
+ module Net
8
+
9
+ # The Ping::External class encapsulates methods for external (system) pings.
10
+ class Ping::External < Ping
11
+ # Pings the host using your system's ping utility and checks for any
12
+ # errors or warnings. Returns true if successful, or false if not.
13
+ #
14
+ # If the ping failed then the Ping::External#exception method should
15
+ # contain a string indicating what went wrong. If the ping succeeded then
16
+ # the Ping::External#warning method may or may not contain a value.
17
+ #
18
+ def ping(host = @host, count = 1, interval = 1, timeout = @timeout)
19
+
20
+ raise "Count must be an integer" unless count.is_a? Integer
21
+ raise "Timeout must be a number" unless timeout.is_a? Numeric
22
+
23
+ unless interval.is_a?(Numeric) && interval >= 0.2
24
+ raise "Interval must be a decimal greater than or equal to 0.2"
25
+ end
26
+
27
+ super(host)
28
+
29
+ pcmd = ['ping']
30
+ bool = false
31
+
32
+ case RbConfig::CONFIG['host_os']
33
+ when /linux/i
34
+ pcmd += ['-c', count.to_s, '-W', timeout.to_s, host, '-i', interval.to_s]
35
+ when /aix/i
36
+ pcmd += ['-c', count.to_s, '-w', timeout.to_s, host]
37
+ when /bsd|osx|mach|darwin/i
38
+ pcmd += ['-c', count.to_s, '-t', timeout.to_s, host]
39
+ when /solaris|sunos/i
40
+ pcmd += [host, timeout.to_s]
41
+ when /hpux/i
42
+ pcmd += [host, "-n#{count.to_s}", '-m', timeout.to_s]
43
+ when /win32|windows|msdos|mswin|cygwin|mingw/i
44
+ pcmd += ['-n', count.to_s, '-w', (timeout * 1000).to_s, host]
45
+ else
46
+ pcmd += [host]
47
+ end
48
+
49
+ start_time = Time.now
50
+
51
+ begin
52
+ err = nil
53
+
54
+ Open3.popen3(*pcmd) do |stdin, stdout, stderr, thread|
55
+ stdin.close
56
+ err = stderr.gets # Can't chomp yet, might be nil
57
+
58
+ case thread.value.exitstatus
59
+ when 0
60
+ info = stdout.read
61
+ if info =~ /unreachable/ix # Windows
62
+ bool = false
63
+ @exception = "host unreachable"
64
+ else
65
+ bool = true # Success, at least one response.
66
+ end
67
+
68
+ if err & err =~ /warning/i
69
+ @warning = err.chomp
70
+ end
71
+ when 2
72
+ bool = false # Transmission successful, no response.
73
+ @exception = err.chomp if err
74
+ else
75
+ bool = false # An error occurred
76
+ if err
77
+ @exception = err.chomp
78
+ else
79
+ stdout.each_line do |line|
80
+ if line =~ /(timed out|could not find host|packet loss)/i
81
+ @exception = line.chomp
82
+ break
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ rescue Exception => error
89
+ @exception = error.message
90
+ end
91
+
92
+ # There is no duration if the ping failed
93
+ @duration = Time.now - start_time if bool
94
+
95
+ bool
96
+ end
97
+
98
+ alias ping? ping
99
+ alias pingecho ping
100
+ end
101
+ end
data/lib/net/ping/http.rb CHANGED
@@ -1,188 +1,188 @@
1
- require File.join(File.dirname(__FILE__), 'ping')
2
- require 'net/http'
3
- require 'net/https'
4
- require 'uri'
5
- require 'open-uri'
6
-
7
- # Force non-blocking Socket.getaddrinfo on Unix systems. Do not use on
8
- # Windows because it (ironically) causes blocking problems.
9
- unless File::ALT_SEPARATOR or RUBY_VERSION >= "1.9.3"
10
- require 'resolv-replace'
11
- end
12
-
13
- # The Net module serves as a namespace only.
14
- module Net
15
-
16
- # The Ping::HTTP class encapsulates methods for HTTP pings.
17
- class Ping::HTTP < Ping
18
-
19
- # By default an http ping will follow a redirect and give you the result
20
- # of the final URI. If this value is set to false, then it will not
21
- # follow a redirect and will return false immediately on a redirect.
22
- #
23
- attr_accessor :follow_redirect
24
-
25
- # The maximum number of redirects allowed. The default is 5.
26
- attr_accessor :redirect_limit
27
-
28
- # The user agent used for the HTTP request. The default is nil.
29
- attr_accessor :user_agent
30
-
31
- # OpenSSL certificate verification mode. The default is VERIFY_NONE.
32
- attr_accessor :ssl_verify_mode
33
-
34
- # Use GET request instead HEAD. The default is false.
35
- attr_accessor :get_request
36
-
37
- # was this ping proxied?
38
- attr_accessor :proxied
39
-
40
- # For unsuccessful requests that return a server error, it is
41
- # useful to know the HTTP status code of the response.
42
- attr_reader :code
43
-
44
- # Creates and returns a new Ping::HTTP object. The default port is the
45
- # port associated with the URI or 80. The default timeout is 5 seconds.
46
- #
47
- def initialize(uri=nil, port=nil, timeout=5)
48
- @follow_redirect = true
49
- @redirect_limit = 5
50
- @ssl_verify_mode = OpenSSL::SSL::VERIFY_NONE
51
- @get_request = false
52
- @code = nil
53
-
54
- port ||= URI.parse(uri).port if uri
55
- port ||= 80
56
-
57
- @port = port
58
-
59
- super(uri, port, timeout)
60
- end
61
-
62
- # Looks for an HTTP response from the URI passed to the constructor.
63
- # If the result is a kind of Net::HTTPSuccess then the ping was
64
- # successful and true is returned. Otherwise, false is returned
65
- # and the Ping::HTTP#exception method should contain a string
66
- # indicating what went wrong.
67
- #
68
- # If the HTTP#follow_redirect accessor is set to true (which it is
69
- # by default) and a redirect occurs during the ping, then the
70
- # HTTP#warning attribute is set to the redirect message, but the
71
- # return result is still true. If it's set to false then a redirect
72
- # response is considered a failed ping.
73
- #
74
- # If no file or path is specified in the URI, then '/' is assumed.
75
- # If no scheme is present in the URI, then 'http' is assumed.
76
- #
77
- def ping(host = @host)
78
- super(host)
79
- bool = false
80
-
81
- # See https://bugs.ruby-lang.org/issues/8645
82
- host = "http://#{host}" unless host.include?("http")
83
-
84
- uri = URI.parse(host)
85
-
86
- # A port provided here via the host argument overrides anything
87
- # provided in constructor.
88
- #
89
- port = URI.split(host)[3] || URI.parse(host).port || @port
90
- port = port.to_i
91
-
92
- start_time = Time.now
93
-
94
- response = do_ping(uri, port)
95
-
96
- if response.is_a?(Net::HTTPSuccess)
97
- bool = true
98
- elsif redirect?(response) # Check code, HTTPRedirection does not always work
99
- if @follow_redirect
100
- @warning = response.message
101
- rlimit = 0
102
-
103
- while redirect?(response)
104
- if rlimit >= redirect_limit
105
- @exception = "Redirect limit exceeded"
106
- break
107
- end
108
- redirect = URI.parse(response['location'])
109
- redirect = uri + redirect if redirect.relative?
110
- response = do_ping(redirect, port)
111
- rlimit += 1
112
- end
113
-
114
- if response.is_a?(Net::HTTPSuccess)
115
- bool = true
116
- else
117
- @warning = nil
118
- @exception ||= response.message
119
- end
120
-
121
- else
122
- @exception = response.message
123
- end
124
- else
125
- @exception ||= response.message
126
- end
127
-
128
- # There is no duration if the ping failed
129
- @duration = Time.now - start_time if bool
130
-
131
- bool
132
- end
133
-
134
- alias ping? ping
135
- alias pingecho ping
136
- alias follow_redirect? follow_redirect
137
- alias uri host
138
- alias uri= host=
139
-
140
- private
141
-
142
- def redirect?(response)
143
- response && response.code.to_i >= 300 && response.code.to_i < 400
144
- end
145
-
146
- def do_ping(uri, port)
147
- response = nil
148
- proxy = uri.find_proxy || URI.parse("")
149
-
150
- begin
151
- uri_path = uri.path.empty? ? '/' : uri.path
152
-
153
- headers = {}
154
- headers["User-Agent"] = user_agent if user_agent
155
-
156
- http = Net::HTTP::Proxy(proxy.host, proxy.port, proxy.user, proxy.password).new(uri.host, port)
157
-
158
- http.open_timeout = timeout
159
- http.read_timeout = timeout
160
-
161
- @proxied = http.proxy?
162
-
163
- if @get_request == true
164
- request = Net::HTTP::Get.new(uri_path)
165
- else
166
- request = Net::HTTP::Head.new(uri_path)
167
- end
168
-
169
- if uri.scheme == 'https'
170
- http.use_ssl = true
171
- http.verify_mode = @ssl_verify_mode
172
- end
173
-
174
- response = http.start{ |h|
175
- h.open_timeout = timeout
176
- h.read_timeout = timeout
177
- h.request(request)
178
- }
179
- rescue Exception => err
180
- @exception = err.message
181
- end
182
-
183
- @code = response.code if response
184
-
185
- response
186
- end
187
- end
188
- end
1
+ require File.join(File.dirname(__FILE__), 'ping')
2
+ require 'net/http'
3
+ require 'net/https'
4
+ require 'uri'
5
+ require 'open-uri'
6
+
7
+ # Force non-blocking Socket.getaddrinfo on Unix systems. Do not use on
8
+ # Windows because it (ironically) causes blocking problems.
9
+ unless File::ALT_SEPARATOR or RUBY_VERSION >= "1.9.3"
10
+ require 'resolv-replace'
11
+ end
12
+
13
+ # The Net module serves as a namespace only.
14
+ module Net
15
+
16
+ # The Ping::HTTP class encapsulates methods for HTTP pings.
17
+ class Ping::HTTP < Ping
18
+
19
+ # By default an http ping will follow a redirect and give you the result
20
+ # of the final URI. If this value is set to false, then it will not
21
+ # follow a redirect and will return false immediately on a redirect.
22
+ #
23
+ attr_accessor :follow_redirect
24
+
25
+ # The maximum number of redirects allowed. The default is 5.
26
+ attr_accessor :redirect_limit
27
+
28
+ # The user agent used for the HTTP request. The default is nil.
29
+ attr_accessor :user_agent
30
+
31
+ # OpenSSL certificate verification mode. The default is VERIFY_NONE.
32
+ attr_accessor :ssl_verify_mode
33
+
34
+ # Use GET request instead HEAD. The default is false.
35
+ attr_accessor :get_request
36
+
37
+ # was this ping proxied?
38
+ attr_accessor :proxied
39
+
40
+ # For unsuccessful requests that return a server error, it is
41
+ # useful to know the HTTP status code of the response.
42
+ attr_reader :code
43
+
44
+ # Creates and returns a new Ping::HTTP object. The default port is the
45
+ # port associated with the URI or 80. The default timeout is 5 seconds.
46
+ #
47
+ def initialize(uri=nil, port=nil, timeout=5)
48
+ @follow_redirect = true
49
+ @redirect_limit = 5
50
+ @ssl_verify_mode = OpenSSL::SSL::VERIFY_NONE
51
+ @get_request = false
52
+ @code = nil
53
+
54
+ port ||= URI.parse(uri).port if uri
55
+ port ||= 80
56
+
57
+ @port = port
58
+
59
+ super(uri, port, timeout)
60
+ end
61
+
62
+ # Looks for an HTTP response from the URI passed to the constructor.
63
+ # If the result is a kind of Net::HTTPSuccess then the ping was
64
+ # successful and true is returned. Otherwise, false is returned
65
+ # and the Ping::HTTP#exception method should contain a string
66
+ # indicating what went wrong.
67
+ #
68
+ # If the HTTP#follow_redirect accessor is set to true (which it is
69
+ # by default) and a redirect occurs during the ping, then the
70
+ # HTTP#warning attribute is set to the redirect message, but the
71
+ # return result is still true. If it's set to false then a redirect
72
+ # response is considered a failed ping.
73
+ #
74
+ # If no file or path is specified in the URI, then '/' is assumed.
75
+ # If no scheme is present in the URI, then 'http' is assumed.
76
+ #
77
+ def ping(host = @host)
78
+ super(host)
79
+ bool = false
80
+
81
+ # See https://bugs.ruby-lang.org/issues/8645
82
+ host = "http://#{host}" unless host.include?("http")
83
+
84
+ uri = URI.parse(host)
85
+
86
+ # A port provided here via the host argument overrides anything
87
+ # provided in constructor.
88
+ #
89
+ port = URI.split(host)[3] || URI.parse(host).port || @port
90
+ port = port.to_i
91
+
92
+ start_time = Time.now
93
+
94
+ response = do_ping(uri, port)
95
+
96
+ if response.is_a?(Net::HTTPSuccess)
97
+ bool = true
98
+ elsif redirect?(response) # Check code, HTTPRedirection does not always work
99
+ if @follow_redirect
100
+ @warning = response.message
101
+ rlimit = 0
102
+
103
+ while redirect?(response)
104
+ if rlimit >= redirect_limit
105
+ @exception = "Redirect limit exceeded"
106
+ break
107
+ end
108
+ redirect = URI.parse(response['location'])
109
+ redirect = uri + redirect if redirect.relative?
110
+ response = do_ping(redirect, port)
111
+ rlimit += 1
112
+ end
113
+
114
+ if response.is_a?(Net::HTTPSuccess)
115
+ bool = true
116
+ else
117
+ @warning = nil
118
+ @exception ||= response.message
119
+ end
120
+
121
+ else
122
+ @exception = response.message
123
+ end
124
+ else
125
+ @exception ||= response.message
126
+ end
127
+
128
+ # There is no duration if the ping failed
129
+ @duration = Time.now - start_time if bool
130
+
131
+ bool
132
+ end
133
+
134
+ alias ping? ping
135
+ alias pingecho ping
136
+ alias follow_redirect? follow_redirect
137
+ alias uri host
138
+ alias uri= host=
139
+
140
+ private
141
+
142
+ def redirect?(response)
143
+ response && response.code.to_i >= 300 && response.code.to_i < 400
144
+ end
145
+
146
+ def do_ping(uri, port)
147
+ response = nil
148
+ proxy = uri.find_proxy || URI.parse("")
149
+
150
+ begin
151
+ uri_path = uri.path.empty? ? '/' : uri.path
152
+
153
+ headers = {}
154
+ headers["User-Agent"] = user_agent if user_agent
155
+
156
+ http = Net::HTTP::Proxy(proxy.host, proxy.port, proxy.user, proxy.password).new(uri.host, port)
157
+
158
+ http.open_timeout = timeout
159
+ http.read_timeout = timeout
160
+
161
+ @proxied = http.proxy?
162
+
163
+ if @get_request == true
164
+ request = Net::HTTP::Get.new(uri_path)
165
+ else
166
+ request = Net::HTTP::Head.new(uri_path)
167
+ end
168
+
169
+ if uri.scheme == 'https'
170
+ http.use_ssl = true
171
+ http.verify_mode = @ssl_verify_mode
172
+ end
173
+
174
+ response = http.start{ |h|
175
+ h.open_timeout = timeout
176
+ h.read_timeout = timeout
177
+ h.request(request)
178
+ }
179
+ rescue Exception => err
180
+ @exception = err.message
181
+ end
182
+
183
+ @code = response.code if response
184
+
185
+ response
186
+ end
187
+ end
188
+ end