Object
Class to handle connections to remote web services. This class is used by ActiveResource::Base to interface with REST services.
The site parameter is required and will set the site attribute to the URI for the remote resource service.
# File lib/active_resource/connection.rb, line 31 31: def initialize(site, format = ActiveResource::Formats::XmlFormat) 32: raise ArgumentError, 'Missing site URI' unless site 33: @user = @password = nil 34: @uri_parser = URI.const_defined?(:Parser) ? URI::Parser.new : URI 35: self.site = site 36: self.format = format 37: end
Sets the auth type for remote service.
# File lib/active_resource/connection.rb, line 62 62: def auth_type=(auth_type) 63: @auth_type = legitimize_auth_type(auth_type) 64: end
Executes a DELETE request (see HTTP protocol documentation if unfamiliar). Used to delete resources.
# File lib/active_resource/connection.rb, line 84 84: def delete(path, headers = {}) 85: with_auth { request(:delete, path, build_request_headers(headers, :delete, self.site.merge(path))) } 86: end
Executes a GET request. Used to get (find) resources.
# File lib/active_resource/connection.rb, line 78 78: def get(path, headers = {}) 79: with_auth { format.decode(request(:get, path, build_request_headers(headers, :get, self.site.merge(path))).body) } 80: end
Executes a HEAD request. Used to obtain meta-information about resources, such as whether they exist and their size (via response headers).
# File lib/active_resource/connection.rb, line 102 102: def head(path, headers = {}) 103: with_auth { request(:head, path, build_request_headers(headers, :head, self.site.merge(path))) } 104: end
Sets the password for remote service.
# File lib/active_resource/connection.rb, line 57 57: def password=(password) 58: @password = password 59: end
Executes a POST request. Used to create new resources.
# File lib/active_resource/connection.rb, line 96 96: def post(path, body = '', headers = {}) 97: with_auth { request(:post, path, body.to_s, build_request_headers(headers, :post, self.site.merge(path))) } 98: end
Set the proxy for remote service.
# File lib/active_resource/connection.rb, line 47 47: def proxy=(proxy) 48: @proxy = proxy.is_a?(URI) ? proxy : @uri_parser.parse(proxy) 49: end
Executes a PUT request (see HTTP protocol documentation if unfamiliar). Used to update resources.
# File lib/active_resource/connection.rb, line 90 90: def put(path, body = '', headers = {}) 91: with_auth { request(:put, path, body.to_s, build_request_headers(headers, :put, self.site.merge(path))) } 92: end
Set URI for remote service.
# File lib/active_resource/connection.rb, line 40 40: def site=(site) 41: @site = site.is_a?(URI) ? site : @uri_parser.parse(site) 42: @user = @uri_parser.unescape(@site.user) if @site.user 43: @password = @uri_parser.unescape(@site.password) if @site.password 44: end
Hash of options applied to Net::HTTP instance when site protocol is ‘https’.
# File lib/active_resource/connection.rb, line 72 72: def ssl_options=(opts={}) 73: @ssl_options = opts 74: end
# File lib/active_resource/connection.rb, line 179 179: def apply_ssl_options(http) 180: return http unless @site.is_a?(URI::HTTPS) 181: 182: http.use_ssl = true 183: http.verify_mode = OpenSSL::SSL::VERIFY_NONE 184: return http unless defined?(@ssl_options) 185: 186: http.ca_path = @ssl_options[:ca_path] if @ssl_options[:ca_path] 187: http.ca_file = @ssl_options[:ca_file] if @ssl_options[:ca_file] 188: 189: http.cert = @ssl_options[:cert] if @ssl_options[:cert] 190: http.key = @ssl_options[:key] if @ssl_options[:key] 191: 192: http.cert_store = @ssl_options[:cert_store] if @ssl_options[:cert_store] 193: http.ssl_timeout = @ssl_options[:ssl_timeout] if @ssl_options[:ssl_timeout] 194: 195: http.verify_mode = @ssl_options[:verify_mode] if @ssl_options[:verify_mode] 196: http.verify_callback = @ssl_options[:verify_callback] if @ssl_options[:verify_callback] 197: http.verify_depth = @ssl_options[:verify_depth] if @ssl_options[:verify_depth] 198: 199: http 200: end
# File lib/active_resource/connection.rb, line 260 260: def auth_attributes_for(uri, request_digest, params) 261: [ 262: %(username="#{@user}"), 263: %(realm="#{params['realm']}"), 264: %(qop="#{params['qop']}"), 265: %(uri="#{uri.path}"), 266: %(nonce="#{params['nonce']}"), 267: %(nc="0"), 268: %(cnonce="#{params['cnonce']}"), 269: %(opaque="#{params['opaque']}"), 270: %(response="#{request_digest}")].join(", ") 271: end
Builds headers for request to remote service.
# File lib/active_resource/connection.rb, line 207 207: def build_request_headers(headers, http_method, uri) 208: authorization_header(http_method, uri).update(default_header).update(http_format_header(http_method)).update(headers) 209: end
# File lib/active_resource/connection.rb, line 248 248: def client_nonce 249: Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535))) 250: end
# File lib/active_resource/connection.rb, line 167 167: def configure_http(http) 168: http = apply_ssl_options(http) 169: 170: # Net::HTTP timeouts default to 60 seconds. 171: if @timeout 172: http.open_timeout = @timeout 173: http.read_timeout = @timeout 174: end 175: 176: http 177: end
# File lib/active_resource/connection.rb, line 202 202: def default_header 203: @default_header ||= {} 204: end
# File lib/active_resource/connection.rb, line 237 237: def digest_auth_header(http_method, uri) 238: params = extract_params_from_response 239: 240: ha1 = Digest::MD5.hexdigest("#{@user}:#{params['realm']}:#{@password}") 241: ha2 = Digest::MD5.hexdigest("#{http_method.to_s.upcase}:#{uri.path}") 242: 243: params.merge!('cnonce' => client_nonce) 244: request_digest = Digest::MD5.hexdigest([ha1, params['nonce'], "0", params['cnonce'], params['qop'], ha2].join(":")) 245: "Digest #{auth_attributes_for(uri, request_digest, params)}" 246: end
# File lib/active_resource/connection.rb, line 252 252: def extract_params_from_response 253: params = {} 254: if response_auth_header =~ /^(\w+) (.*)/ 255: $2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 } 256: end 257: params 258: end
Handles response and error codes from the remote service.
# File lib/active_resource/connection.rb, line 122 122: def handle_response(response) 123: case response.code.to_i 124: when 301,302 125: raise(Redirection.new(response)) 126: when 200...400 127: response 128: when 400 129: raise(BadRequest.new(response)) 130: when 401 131: raise(UnauthorizedAccess.new(response)) 132: when 403 133: raise(ForbiddenAccess.new(response)) 134: when 404 135: raise(ResourceNotFound.new(response)) 136: when 405 137: raise(MethodNotAllowed.new(response)) 138: when 409 139: raise(ResourceConflict.new(response)) 140: when 410 141: raise(ResourceGone.new(response)) 142: when 422 143: raise(ResourceInvalid.new(response)) 144: when 401...500 145: raise(ClientError.new(response)) 146: when 500...600 147: raise(ServerError.new(response)) 148: else 149: raise(ConnectionError.new(response, "Unknown response code: #{response.code}")) 150: end 151: end
# File lib/active_resource/http_mock.rb, line 296 296: def http 297: @http ||= HttpMock.new(@site) 298: end
Creates new Net::HTTP instance for communication with the remote service and resources.
# File lib/active_resource/connection.rb, line 155 155: def http 156: configure_http(new_http) 157: end
# File lib/active_resource/connection.rb, line 273 273: def http_format_header(http_method) 274: {HTTP_FORMAT_HEADER_NAMES[http_method] => format.mime_type} 275: end
# File lib/active_resource/connection.rb, line 277 277: def legitimize_auth_type(auth_type) 278: return :basic if auth_type.nil? 279: auth_type = auth_type.to_sym 280: [:basic, :digest].include?(auth_type) ? auth_type : :basic 281: end
# File lib/active_resource/connection.rb, line 159 159: def new_http 160: if @proxy 161: Net::HTTP.new(@site.host, @site.port, @proxy.host, @proxy.port, @proxy.user, @proxy.password) 162: else 163: Net::HTTP.new(@site.host, @site.port) 164: end 165: end
Makes a request to the remote service.
# File lib/active_resource/connection.rb, line 108 108: def request(method, path, *arguments) 109: result = ActiveSupport::Notifications.instrument("request.active_resource") do |payload| 110: payload[:method] = method 111: payload[:request_uri] = "#{site.scheme}://#{site.host}:#{site.port}#{path}" 112: payload[:result] = http.send(method, path, *arguments) 113: end 114: handle_response(result) 115: rescue Timeout::Error => e 116: raise TimeoutError.new(e.message) 117: rescue OpenSSL::SSL::SSLError => e 118: raise SSLError.new(e.message) 119: end
# File lib/active_resource/connection.rb, line 211 211: def response_auth_header 212: @response_auth_header ||= "" 213: end
# File lib/active_resource/connection.rb, line 215 215: def with_auth 216: retried ||= false 217: yield 218: rescue UnauthorizedAccess => e 219: raise if retried || auth_type != :digest 220: @response_auth_header = e.response['WWW-Authenticate'] 221: retried = true 222: retry 223: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.