alinta-rest-client 2.2.0-x64-mingw32

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.
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