alinta-rest-client 2.2.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.mailmap +10 -0
  4. data/.rspec +2 -0
  5. data/.rubocop +2 -0
  6. data/.rubocop-disables.yml +393 -0
  7. data/.rubocop.yml +8 -0
  8. data/.travis.yml +49 -0
  9. data/AUTHORS +106 -0
  10. data/Gemfile +11 -0
  11. data/LICENSE +21 -0
  12. data/README.md +896 -0
  13. data/Rakefile +140 -0
  14. data/bin/restclient +92 -0
  15. data/history.md +357 -0
  16. data/lib/rest-client.rb +2 -0
  17. data/lib/rest_client.rb +2 -0
  18. data/lib/restclient.rb +183 -0
  19. data/lib/restclient/abstract_response.rb +252 -0
  20. data/lib/restclient/exceptions.rb +244 -0
  21. data/lib/restclient/params_array.rb +72 -0
  22. data/lib/restclient/payload.rb +234 -0
  23. data/lib/restclient/platform.rb +49 -0
  24. data/lib/restclient/raw_response.rb +49 -0
  25. data/lib/restclient/request.rb +875 -0
  26. data/lib/restclient/resource.rb +178 -0
  27. data/lib/restclient/response.rb +90 -0
  28. data/lib/restclient/utils.rb +274 -0
  29. data/lib/restclient/version.rb +8 -0
  30. data/lib/restclient/windows.rb +8 -0
  31. data/lib/restclient/windows/root_certs.rb +105 -0
  32. data/rest-client.gemspec +32 -0
  33. data/rest-client.windows.gemspec +19 -0
  34. data/spec/ISS.jpg +0 -0
  35. data/spec/helpers.rb +54 -0
  36. data/spec/integration/_lib.rb +1 -0
  37. data/spec/integration/capath_digicert/244b5494.0 +19 -0
  38. data/spec/integration/capath_digicert/81b9768f.0 +19 -0
  39. data/spec/integration/capath_digicert/README +8 -0
  40. data/spec/integration/capath_digicert/digicert.crt +19 -0
  41. data/spec/integration/capath_verisign/415660c1.0 +14 -0
  42. data/spec/integration/capath_verisign/7651b327.0 +14 -0
  43. data/spec/integration/capath_verisign/README +8 -0
  44. data/spec/integration/capath_verisign/verisign.crt +14 -0
  45. data/spec/integration/certs/digicert.crt +19 -0
  46. data/spec/integration/certs/verisign.crt +14 -0
  47. data/spec/integration/httpbin_spec.rb +128 -0
  48. data/spec/integration/integration_spec.rb +118 -0
  49. data/spec/integration/request_spec.rb +127 -0
  50. data/spec/spec_helper.rb +29 -0
  51. data/spec/unit/_lib.rb +1 -0
  52. data/spec/unit/abstract_response_spec.rb +145 -0
  53. data/spec/unit/exceptions_spec.rb +108 -0
  54. data/spec/unit/params_array_spec.rb +36 -0
  55. data/spec/unit/payload_spec.rb +295 -0
  56. data/spec/unit/raw_response_spec.rb +22 -0
  57. data/spec/unit/request2_spec.rb +54 -0
  58. data/spec/unit/request_spec.rb +1238 -0
  59. data/spec/unit/resource_spec.rb +134 -0
  60. data/spec/unit/response_spec.rb +252 -0
  61. data/spec/unit/restclient_spec.rb +80 -0
  62. data/spec/unit/utils_spec.rb +147 -0
  63. data/spec/unit/windows/root_certs_spec.rb +22 -0
  64. metadata +318 -0
@@ -0,0 +1,2 @@
1
+ # More logical way to require 'rest-client'
2
+ require File.dirname(__FILE__) + '/restclient'
@@ -0,0 +1,2 @@
1
+ # This file exists for backward compatbility with require 'rest_client'
2
+ require File.dirname(__FILE__) + '/restclient'
@@ -0,0 +1,183 @@
1
+ require 'net/http'
2
+ require 'openssl'
3
+ require 'stringio'
4
+ require 'uri'
5
+
6
+ require File.dirname(__FILE__) + '/restclient/version'
7
+ require File.dirname(__FILE__) + '/restclient/platform'
8
+ require File.dirname(__FILE__) + '/restclient/exceptions'
9
+ require File.dirname(__FILE__) + '/restclient/utils'
10
+ require File.dirname(__FILE__) + '/restclient/request'
11
+ require File.dirname(__FILE__) + '/restclient/abstract_response'
12
+ require File.dirname(__FILE__) + '/restclient/response'
13
+ require File.dirname(__FILE__) + '/restclient/raw_response'
14
+ require File.dirname(__FILE__) + '/restclient/resource'
15
+ require File.dirname(__FILE__) + '/restclient/params_array'
16
+ require File.dirname(__FILE__) + '/restclient/payload'
17
+ require File.dirname(__FILE__) + '/restclient/windows'
18
+
19
+ # This module's static methods are the entry point for using the REST client.
20
+ #
21
+ # # GET
22
+ # xml = RestClient.get 'http://example.com/resource'
23
+ # jpg = RestClient.get 'http://example.com/resource', :accept => 'image/jpg'
24
+ #
25
+ # # authentication and SSL
26
+ # RestClient.get 'https://user:password@example.com/private/resource'
27
+ #
28
+ # # POST or PUT with a hash sends parameters as a urlencoded form body
29
+ # RestClient.post 'http://example.com/resource', :param1 => 'one'
30
+ #
31
+ # # nest hash parameters
32
+ # RestClient.post 'http://example.com/resource', :nested => { :param1 => 'one' }
33
+ #
34
+ # # POST and PUT with raw payloads
35
+ # RestClient.post 'http://example.com/resource', 'the post body', :content_type => 'text/plain'
36
+ # RestClient.post 'http://example.com/resource.xml', xml_doc
37
+ # RestClient.put 'http://example.com/resource.pdf', File.read('my.pdf'), :content_type => 'application/pdf'
38
+ #
39
+ # # DELETE
40
+ # RestClient.delete 'http://example.com/resource'
41
+ #
42
+ # # retreive the response http code and headers
43
+ # res = RestClient.get 'http://example.com/some.jpg'
44
+ # res.code # => 200
45
+ # res.headers[:content_type] # => 'image/jpg'
46
+ #
47
+ # # HEAD
48
+ # RestClient.head('http://example.com').headers
49
+ #
50
+ # To use with a proxy, just set RestClient.proxy to the proper http proxy:
51
+ #
52
+ # RestClient.proxy = "http://proxy.example.com/"
53
+ #
54
+ # Or inherit the proxy from the environment:
55
+ #
56
+ # RestClient.proxy = ENV['http_proxy']
57
+ #
58
+ # For live tests of RestClient, try using http://rest-test.heroku.com, which echoes back information about the rest call:
59
+ #
60
+ # >> RestClient.put 'http://rest-test.heroku.com/resource', :foo => 'baz'
61
+ # => "PUT http://rest-test.heroku.com/resource with a 7 byte payload, content type application/x-www-form-urlencoded {\"foo\"=>\"baz\"}"
62
+ #
63
+ module RestClient
64
+
65
+ def self.get(url, headers={}, &block)
66
+ Request.execute(:method => :get, :url => url, :headers => headers, &block)
67
+ end
68
+
69
+ def self.post(url, payload, headers={}, &block)
70
+ Request.execute(:method => :post, :url => url, :payload => payload, :headers => headers, &block)
71
+ end
72
+
73
+ def self.patch(url, payload, headers={}, &block)
74
+ Request.execute(:method => :patch, :url => url, :payload => payload, :headers => headers, &block)
75
+ end
76
+
77
+ def self.put(url, payload, headers={}, &block)
78
+ Request.execute(:method => :put, :url => url, :payload => payload, :headers => headers, &block)
79
+ end
80
+
81
+ def self.delete(url, headers={}, &block)
82
+ Request.execute(:method => :delete, :url => url, :headers => headers, &block)
83
+ end
84
+
85
+ def self.head(url, headers={}, &block)
86
+ Request.execute(:method => :head, :url => url, :headers => headers, &block)
87
+ end
88
+
89
+ def self.options(url, headers={}, &block)
90
+ Request.execute(:method => :options, :url => url, :headers => headers, &block)
91
+ end
92
+
93
+ # A global proxy URL to use for all requests. This can be overridden on a
94
+ # per-request basis by passing `:proxy` to RestClient::Request.
95
+ def self.proxy
96
+ @proxy ||= nil
97
+ end
98
+
99
+ def self.proxy=(value)
100
+ @proxy = value
101
+ @proxy_set = true
102
+ end
103
+
104
+ # Return whether RestClient.proxy was set explicitly. We use this to
105
+ # differentiate between no value being set and a value explicitly set to nil.
106
+ #
107
+ # @return [Boolean]
108
+ #
109
+ def self.proxy_set?
110
+ @proxy_set ||= false
111
+ end
112
+
113
+ # Setup the log for RestClient calls.
114
+ # Value should be a logger but can can be stdout, stderr, or a filename.
115
+ # You can also configure logging by the environment variable RESTCLIENT_LOG.
116
+ def self.log= log
117
+ @@log = create_log log
118
+ end
119
+
120
+ # Create a log that respond to << like a logger
121
+ # param can be 'stdout', 'stderr', a string (then we will log to that file) or a logger (then we return it)
122
+ def self.create_log param
123
+ if param
124
+ if param.is_a? String
125
+ if param == 'stdout'
126
+ stdout_logger = Class.new do
127
+ def << obj
128
+ STDOUT.puts obj
129
+ end
130
+ end
131
+ stdout_logger.new
132
+ elsif param == 'stderr'
133
+ stderr_logger = Class.new do
134
+ def << obj
135
+ STDERR.puts obj
136
+ end
137
+ end
138
+ stderr_logger.new
139
+ else
140
+ file_logger = Class.new do
141
+ attr_writer :target_file
142
+
143
+ def << obj
144
+ File.open(@target_file, 'a') { |f| f.puts obj }
145
+ end
146
+ end
147
+ logger = file_logger.new
148
+ logger.target_file = param
149
+ logger
150
+ end
151
+ else
152
+ param
153
+ end
154
+ end
155
+ end
156
+
157
+ @@env_log = create_log ENV['RESTCLIENT_LOG']
158
+
159
+ @@log = nil
160
+
161
+ def self.log # :nodoc:
162
+ @@env_log || @@log
163
+ end
164
+
165
+ @@before_execution_procs = []
166
+
167
+ # Add a Proc to be called before each request in executed.
168
+ # The proc parameters will be the http request and the request params.
169
+ def self.add_before_execution_proc &proc
170
+ raise ArgumentError.new('block is required') unless proc
171
+ @@before_execution_procs << proc
172
+ end
173
+
174
+ # Reset the procs to be called before each request is executed.
175
+ def self.reset_before_execution_procs
176
+ @@before_execution_procs = []
177
+ end
178
+
179
+ def self.before_execution_procs # :nodoc:
180
+ @@before_execution_procs
181
+ end
182
+
183
+ end
@@ -0,0 +1,252 @@
1
+ require 'cgi'
2
+ require 'http-cookie'
3
+
4
+ module RestClient
5
+
6
+ module AbstractResponse
7
+
8
+ attr_reader :net_http_res, :request, :start_time, :end_time, :duration
9
+
10
+ def inspect
11
+ raise NotImplementedError.new('must override in subclass')
12
+ end
13
+
14
+ # Logger from the request, potentially nil.
15
+ def log
16
+ request.log
17
+ end
18
+
19
+ def log_response
20
+ return unless log
21
+
22
+ code = net_http_res.code
23
+ res_name = net_http_res.class.to_s.gsub(/\ANet::HTTP/, '')
24
+ content_type = (net_http_res['Content-type'] || '').gsub(/;.*\z/, '')
25
+
26
+ log << "# => #{code} #{res_name} | #{content_type} #{size} bytes, #{sprintf('%.2f', duration)}s\n"
27
+ end
28
+
29
+ # HTTP status code
30
+ def code
31
+ @code ||= @net_http_res.code.to_i
32
+ end
33
+
34
+ def history
35
+ @history ||= request.redirection_history || []
36
+ end
37
+
38
+ # A hash of the headers, beautified with symbols and underscores.
39
+ # e.g. "Content-type" will become :content_type.
40
+ def headers
41
+ @headers ||= AbstractResponse.beautify_headers(@net_http_res.to_hash)
42
+ end
43
+
44
+ # The raw headers.
45
+ def raw_headers
46
+ @raw_headers ||= @net_http_res.to_hash
47
+ end
48
+
49
+ # @param [Net::HTTPResponse] net_http_res
50
+ # @param [RestClient::Request] request
51
+ # @param [Time] start_time
52
+ def response_set_vars(net_http_res, request, start_time)
53
+ @net_http_res = net_http_res
54
+ @request = request
55
+ @start_time = start_time
56
+ @end_time = Time.now
57
+
58
+ if @start_time
59
+ @duration = @end_time - @start_time
60
+ else
61
+ @duration = nil
62
+ end
63
+
64
+ # prime redirection history
65
+ history
66
+ end
67
+
68
+ # Hash of cookies extracted from response headers.
69
+ #
70
+ # NB: This will return only cookies whose domain matches this request, and
71
+ # may not even return all of those cookies if there are duplicate names.
72
+ # Use the full cookie_jar for more nuanced access.
73
+ #
74
+ # @see #cookie_jar
75
+ #
76
+ # @return [Hash]
77
+ #
78
+ def cookies
79
+ hash = {}
80
+
81
+ cookie_jar.cookies(@request.uri).each do |cookie|
82
+ hash[cookie.name] = cookie.value
83
+ end
84
+
85
+ hash
86
+ end
87
+
88
+ # Cookie jar extracted from response headers.
89
+ #
90
+ # @return [HTTP::CookieJar]
91
+ #
92
+ def cookie_jar
93
+ return @cookie_jar if defined?(@cookie_jar) && @cookie_jar
94
+
95
+ jar = @request.cookie_jar.dup
96
+ headers.fetch(:set_cookie, []).each do |cookie|
97
+ jar.parse(cookie, @request.uri)
98
+ end
99
+
100
+ @cookie_jar = jar
101
+ end
102
+
103
+ # Return the default behavior corresponding to the response code:
104
+ #
105
+ # For 20x status codes: return the response itself
106
+ #
107
+ # For 30x status codes:
108
+ # 301, 302, 307: redirect GET / HEAD if there is a Location header
109
+ # 303: redirect, changing method to GET, if there is a Location header
110
+ #
111
+ # For all other responses, raise a response exception
112
+ #
113
+ def return!(&block)
114
+ case code
115
+ when 200..207
116
+ self
117
+ when 301, 302, 307
118
+ case request.method
119
+ when 'get', 'head'
120
+ check_max_redirects
121
+ follow_redirection(&block)
122
+ else
123
+ raise exception_with_response
124
+ end
125
+ when 303
126
+ check_max_redirects
127
+ follow_get_redirection(&block)
128
+ else
129
+ raise exception_with_response
130
+ end
131
+ end
132
+
133
+ def to_i
134
+ warn('warning: calling Response#to_i is not recommended')
135
+ super
136
+ end
137
+
138
+ def description
139
+ "#{code} #{STATUSES[code]} | #{(headers[:content_type] || '').gsub(/;.*$/, '')} #{size} bytes\n"
140
+ end
141
+
142
+ # Follow a redirection response by making a new HTTP request to the
143
+ # redirection target.
144
+ def follow_redirection(&block)
145
+ _follow_redirection(request.args.dup, &block)
146
+ end
147
+
148
+ # Follow a redirection response, but change the HTTP method to GET and drop
149
+ # the payload from the original request.
150
+ def follow_get_redirection(&block)
151
+ new_args = request.args.dup
152
+ new_args[:method] = :get
153
+ new_args.delete(:payload)
154
+
155
+ _follow_redirection(new_args, &block)
156
+ end
157
+
158
+ # Convert headers hash into canonical form.
159
+ #
160
+ # Header names will be converted to lowercase symbols with underscores
161
+ # instead of hyphens.
162
+ #
163
+ # Headers specified multiple times will be joined by comma and space,
164
+ # except for Set-Cookie, which will always be an array.
165
+ #
166
+ # Per RFC 2616, if a server sends multiple headers with the same key, they
167
+ # MUST be able to be joined into a single header by a comma. However,
168
+ # Set-Cookie (RFC 6265) cannot because commas are valid within cookie
169
+ # definitions. The newer RFC 7230 notes (3.2.2) that Set-Cookie should be
170
+ # handled as a special case.
171
+ #
172
+ # http://tools.ietf.org/html/rfc2616#section-4.2
173
+ # http://tools.ietf.org/html/rfc7230#section-3.2.2
174
+ # http://tools.ietf.org/html/rfc6265
175
+ #
176
+ # @param headers [Hash]
177
+ # @return [Hash]
178
+ #
179
+ def self.beautify_headers(headers)
180
+ headers.inject({}) do |out, (key, value)|
181
+ key_sym = key.tr('-', '_').downcase.to_sym
182
+
183
+ # Handle Set-Cookie specially since it cannot be joined by comma.
184
+ if key.downcase == 'set-cookie'
185
+ out[key_sym] = value
186
+ else
187
+ out[key_sym] = value.join(', ')
188
+ end
189
+
190
+ out
191
+ end
192
+ end
193
+
194
+ private
195
+
196
+ # Follow a redirection
197
+ #
198
+ # @param new_args [Hash] Start with this hash of arguments for the
199
+ # redirection request. The hash will be mutated, so be sure to dup any
200
+ # existing hash that should not be modified.
201
+ #
202
+ def _follow_redirection(new_args, &block)
203
+
204
+ # parse location header and merge into existing URL
205
+ url = headers[:location]
206
+
207
+ # cannot follow redirection if there is no location header
208
+ unless url
209
+ raise exception_with_response
210
+ end
211
+
212
+ # handle relative redirects
213
+ unless url.start_with?('http')
214
+ url = URI.parse(request.url).merge(url).to_s
215
+ end
216
+ new_args[:url] = url
217
+
218
+ new_args[:password] = request.password
219
+ new_args[:user] = request.user
220
+ new_args[:headers] = request.headers
221
+ new_args[:max_redirects] = request.max_redirects - 1
222
+
223
+ # pass through our new cookie jar
224
+ new_args[:cookies] = cookie_jar
225
+
226
+ # prepare new request
227
+ new_req = Request.new(new_args)
228
+
229
+ # append self to redirection history
230
+ new_req.redirection_history = history + [self]
231
+
232
+ # execute redirected request
233
+ new_req.execute(&block)
234
+ end
235
+
236
+ def check_max_redirects
237
+ if request.max_redirects <= 0
238
+ raise exception_with_response
239
+ end
240
+ end
241
+
242
+ def exception_with_response
243
+ begin
244
+ klass = Exceptions::EXCEPTIONS_MAP.fetch(code)
245
+ rescue KeyError
246
+ raise RequestFailed.new(self, code)
247
+ end
248
+
249
+ raise klass.new(self, code)
250
+ end
251
+ end
252
+ end
@@ -0,0 +1,244 @@
1
+ module RestClient
2
+
3
+ # Hash of HTTP status code => message.
4
+ #
5
+ # 1xx: Informational - Request received, continuing process
6
+ # 2xx: Success - The action was successfully received, understood, and
7
+ # accepted
8
+ # 3xx: Redirection - Further action must be taken in order to complete the
9
+ # request
10
+ # 4xx: Client Error - The request contains bad syntax or cannot be fulfilled
11
+ # 5xx: Server Error - The server failed to fulfill an apparently valid
12
+ # request
13
+ #
14
+ # @see
15
+ # http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
16
+ #
17
+ STATUSES = {100 => 'Continue',
18
+ 101 => 'Switching Protocols',
19
+ 102 => 'Processing', #WebDAV
20
+
21
+ 200 => 'OK',
22
+ 201 => 'Created',
23
+ 202 => 'Accepted',
24
+ 203 => 'Non-Authoritative Information', # http/1.1
25
+ 204 => 'No Content',
26
+ 205 => 'Reset Content',
27
+ 206 => 'Partial Content',
28
+ 207 => 'Multi-Status', #WebDAV
29
+ 208 => 'Already Reported', # RFC5842
30
+ 226 => 'IM Used', # RFC3229
31
+
32
+ 300 => 'Multiple Choices',
33
+ 301 => 'Moved Permanently',
34
+ 302 => 'Found',
35
+ 303 => 'See Other', # http/1.1
36
+ 304 => 'Not Modified',
37
+ 305 => 'Use Proxy', # http/1.1
38
+ 306 => 'Switch Proxy', # no longer used
39
+ 307 => 'Temporary Redirect', # http/1.1
40
+ 308 => 'Permanent Redirect', # RFC7538
41
+
42
+ 400 => 'Bad Request',
43
+ 401 => 'Unauthorized',
44
+ 402 => 'Payment Required',
45
+ 403 => 'Forbidden',
46
+ 404 => 'Not Found',
47
+ 405 => 'Method Not Allowed',
48
+ 406 => 'Not Acceptable',
49
+ 407 => 'Proxy Authentication Required',
50
+ 408 => 'Request Timeout',
51
+ 409 => 'Conflict',
52
+ 410 => 'Gone',
53
+ 411 => 'Length Required',
54
+ 412 => 'Precondition Failed',
55
+ 413 => 'Payload Too Large', # RFC7231 (renamed, see below)
56
+ 414 => 'URI Too Long', # RFC7231 (renamed, see below)
57
+ 415 => 'Unsupported Media Type',
58
+ 416 => 'Range Not Satisfiable', # RFC7233 (renamed, see below)
59
+ 417 => 'Expectation Failed',
60
+ 418 => 'I\'m A Teapot', #RFC2324
61
+ 421 => 'Too Many Connections From This IP',
62
+ 422 => 'Unprocessable Entity', #WebDAV
63
+ 423 => 'Locked', #WebDAV
64
+ 424 => 'Failed Dependency', #WebDAV
65
+ 425 => 'Unordered Collection', #WebDAV
66
+ 426 => 'Upgrade Required',
67
+ 428 => 'Precondition Required', #RFC6585
68
+ 429 => 'Too Many Requests', #RFC6585
69
+ 431 => 'Request Header Fields Too Large', #RFC6585
70
+ 449 => 'Retry With', #Microsoft
71
+ 450 => 'Blocked By Windows Parental Controls', #Microsoft
72
+
73
+ 500 => 'Internal Server Error',
74
+ 501 => 'Not Implemented',
75
+ 502 => 'Bad Gateway',
76
+ 503 => 'Service Unavailable',
77
+ 504 => 'Gateway Timeout',
78
+ 505 => 'HTTP Version Not Supported',
79
+ 506 => 'Variant Also Negotiates',
80
+ 507 => 'Insufficient Storage', #WebDAV
81
+ 508 => 'Loop Detected', # RFC5842
82
+ 509 => 'Bandwidth Limit Exceeded', #Apache
83
+ 510 => 'Not Extended',
84
+ 511 => 'Network Authentication Required', # RFC6585
85
+ }
86
+
87
+ STATUSES_COMPATIBILITY = {
88
+ # The RFCs all specify "Not Found", but "Resource Not Found" was used in
89
+ # earlier RestClient releases.
90
+ 404 => ['ResourceNotFound'],
91
+
92
+ # HTTP 413 was renamed to "Payload Too Large" in RFC7231.
93
+ 413 => ['RequestEntityTooLarge'],
94
+
95
+ # HTTP 414 was renamed to "URI Too Long" in RFC7231.
96
+ 414 => ['RequestURITooLong'],
97
+
98
+ # HTTP 416 was renamed to "Range Not Satisfiable" in RFC7233.
99
+ 416 => ['RequestedRangeNotSatisfiable'],
100
+ }
101
+
102
+
103
+ # This is the base RestClient exception class. Rescue it if you want to
104
+ # catch any exception that your request might raise
105
+ # You can get the status code by e.http_code, or see anything about the
106
+ # response via e.response.
107
+ # For example, the entire result body (which is
108
+ # probably an HTML error page) is e.response.
109
+ class Exception < RuntimeError
110
+ attr_accessor :response
111
+ attr_accessor :original_exception
112
+ attr_writer :message
113
+
114
+ def initialize response = nil, initial_response_code = nil
115
+ @response = response
116
+ @message = nil
117
+ @initial_response_code = initial_response_code
118
+ end
119
+
120
+ def http_code
121
+ # return integer for compatibility
122
+ if @response
123
+ @response.code.to_i
124
+ else
125
+ @initial_response_code
126
+ end
127
+ end
128
+
129
+ def http_headers
130
+ @response.headers if @response
131
+ end
132
+
133
+ def http_body
134
+ @response.body if @response
135
+ end
136
+
137
+ def to_s
138
+ message
139
+ end
140
+
141
+ def message
142
+ @message || default_message
143
+ end
144
+
145
+ def default_message
146
+ self.class.name
147
+ end
148
+ end
149
+
150
+ # Compatibility
151
+ class ExceptionWithResponse < RestClient::Exception
152
+ end
153
+
154
+ # The request failed with an error code not managed by the code
155
+ class RequestFailed < ExceptionWithResponse
156
+
157
+ def default_message
158
+ "HTTP status code #{http_code}"
159
+ end
160
+
161
+ def to_s
162
+ message
163
+ end
164
+ end
165
+
166
+ # RestClient exception classes. TODO: move all exceptions into this module.
167
+ #
168
+ # We will a create an exception for each status code, see
169
+ # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
170
+ #
171
+ module Exceptions
172
+ # Map http status codes to the corresponding exception class
173
+ EXCEPTIONS_MAP = {}
174
+ end
175
+
176
+ # Create HTTP status exception classes
177
+ STATUSES.each_pair do |code, message|
178
+ klass = Class.new(RequestFailed) do
179
+ send(:define_method, :default_message) {"#{http_code ? "#{http_code} " : ''}#{message}"}
180
+ end
181
+ klass_constant = const_set(message.delete(' \-\''), klass)
182
+ Exceptions::EXCEPTIONS_MAP[code] = klass_constant
183
+ end
184
+
185
+ # Create HTTP status exception classes used for backwards compatibility
186
+ STATUSES_COMPATIBILITY.each_pair do |code, compat_list|
187
+ klass = Exceptions::EXCEPTIONS_MAP.fetch(code)
188
+ compat_list.each do |old_name|
189
+ const_set(old_name, klass)
190
+ end
191
+ end
192
+
193
+ module Exceptions
194
+ # We have to split the Exceptions module like we do here because the
195
+ # EXCEPTIONS_MAP is under Exceptions, but we depend on
196
+ # RestClient::RequestTimeout below.
197
+
198
+ # Base class for request timeouts.
199
+ #
200
+ # NB: Previous releases of rest-client would raise RequestTimeout both for
201
+ # HTTP 408 responses and for actual connection timeouts.
202
+ class Timeout < RestClient::RequestTimeout
203
+ def initialize(message=nil, original_exception=nil)
204
+ super(nil, nil)
205
+ self.message = message if message
206
+ self.original_exception = original_exception if original_exception
207
+ end
208
+ end
209
+
210
+ # Timeout when connecting to a server. Typically wraps Net::OpenTimeout (in
211
+ # ruby 2.0 or greater).
212
+ class OpenTimeout < Timeout
213
+ def default_message
214
+ 'Timed out connecting to server'
215
+ end
216
+ end
217
+
218
+ # Timeout when reading from a server. Typically wraps Net::ReadTimeout (in
219
+ # ruby 2.0 or greater).
220
+ class ReadTimeout < Timeout
221
+ def default_message
222
+ 'Timed out reading data from server'
223
+ end
224
+ end
225
+ end
226
+
227
+
228
+ # The server broke the connection prior to the request completing. Usually
229
+ # this means it crashed, or sometimes that your network connection was
230
+ # severed before it could complete.
231
+ class ServerBrokeConnection < RestClient::Exception
232
+ def initialize(message = 'Server broke connection')
233
+ super nil, nil
234
+ self.message = message
235
+ end
236
+ end
237
+
238
+ class SSLCertificateNotVerified < RestClient::Exception
239
+ def initialize(message = 'SSL certificate not verified')
240
+ super nil, nil
241
+ self.message = message
242
+ end
243
+ end
244
+ end