require "httpi/version" require "httpi/logger" require "httpi/request" require "httpi/adapter/httpclient" require "httpi/adapter/curb" require "httpi/adapter/excon" require "httpi/adapter/net_http" require "httpi/adapter/net_http_persistent" require "httpi/adapter/em_http" require "httpi/adapter/rack" # = HTTPI # # Executes HTTP requests using a predefined adapter. # All request methods accept an HTTPI::Request and an optional adapter. # They may also offer shortcut methods for executing basic requests. # Also they all return an HTTPI::Response. # # == GET # # request = HTTPI::Request.new("http://example.com") # HTTPI.get(request, :httpclient) # # === Shortcuts # # HTTPI.get("http://example.com", :curb) # # == POST # # request = HTTPI::Request.new # request.url = "http://example.com" # request.body = "xml" # # HTTPI.post(request, :httpclient) # # === Shortcuts # # HTTPI.post("http://example.com", "xml", :curb) # # == HEAD # # request = HTTPI::Request.new("http://example.com") # HTTPI.head(request, :httpclient) # # === Shortcuts # # HTTPI.head("http://example.com", :curb) # # == PUT # # request = HTTPI::Request.new # request.url = "http://example.com" # request.body = "xml" # # HTTPI.put(request, :httpclient) # # === Shortcuts # # HTTPI.put("http://example.com", "xml", :curb) # # == DELETE # # request = HTTPI::Request.new("http://example.com") # HTTPI.delete(request, :httpclient) # # === Shortcuts # # HTTPI.delete("http://example.com", :curb) # # == More control # # If you need more control over your request, you can access the HTTP client # instance represented by your adapter in a block. # # HTTPI.get request do |http| # http.follow_redirect_count = 3 # HTTPClient example # end module HTTPI REQUEST_METHODS = [:get, :post, :head, :put, :delete] DEFAULT_LOG_LEVEL = :debug class Error < StandardError; end class TimeoutError < Error; end class NotSupportedError < Error; end class NotImplementedError < Error; end module ConnectionError; end class SSLError < Error def initialize(message = nil, original = $!) super(message || original.message) @original = original end attr_reader :original end class << self # Executes an HTTP GET request. def get(request, adapter = nil, &block) request = Request.new(request) if request.kind_of? String request(:get, request, adapter, &block) end # Executes an HTTP POST request. def post(*args, &block) request, adapter = request_and_adapter_from(args) request(:post, request, adapter, &block) end # Executes an HTTP HEAD request. def head(request, adapter = nil, &block) request = Request.new(request) if request.kind_of? String request(:head, request, adapter, &block) end # Executes an HTTP PUT request. def put(*args, &block) request, adapter = request_and_adapter_from(args) request(:put, request, adapter, &block) end # Executes an HTTP DELETE request. def delete(request, adapter = nil, &block) request = Request.new(request) if request.kind_of? String request(:delete, request, adapter, &block) end # Executes an HTTP request for the given +method+. def request(method, request, adapter = nil) adapter_class = load_adapter(adapter, request) yield adapter_class.client if block_given? log_request(method, request, Adapter.identify(adapter_class.class)) response = adapter_class.request(method) if response && HTTPI::Response::RedirectResponseCodes.member?(response.code) && request.follow_redirect? log("Following redirect: '#{response.headers['location']}'.") request.url = response.headers['location'] return request(method, request, adapter) end response end # Shortcut for setting the default adapter to use. def adapter=(adapter) Adapter.use = adapter end private def request_and_adapter_from(args) return args if args[0].kind_of? Request [Request.new(:url => args[0], :body => args[1]), args[2]] end def load_adapter(adapter, request) Adapter.load(adapter).new(request) end end end