mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-09-01 00:00:35 -04:00
added the options module, similar to http
This commit is contained in:
parent
70a2d7ad82
commit
c7319964c0
@ -3,6 +3,7 @@
|
||||
|
||||
require "httpx/version"
|
||||
require "httpx/callbacks"
|
||||
require "httpx/options"
|
||||
require "httpx/connection"
|
||||
require "httpx/headers"
|
||||
require "httpx/request"
|
||||
|
@ -3,8 +3,12 @@
|
||||
module HTTPX
|
||||
class Client
|
||||
def initialize(**options)
|
||||
@connection = Connection.new(**options)
|
||||
@default_options = options
|
||||
@default_options = Options.new(options)
|
||||
@connection = Connection.new(@default_options)
|
||||
end
|
||||
|
||||
def close
|
||||
@connection.close
|
||||
end
|
||||
|
||||
def request(verb, uri, **options)
|
||||
|
@ -7,11 +7,9 @@ require "httpx/channel"
|
||||
|
||||
module HTTPX
|
||||
class Connection
|
||||
CONNECTION_TIMEOUT = 2
|
||||
|
||||
def initialize(**options)
|
||||
@options = options
|
||||
@connection_timeout = options.fetch(:connection_timeout, CONNECTION_TIMEOUT)
|
||||
def initialize(options)
|
||||
@options = Options.new(options)
|
||||
@operation_timeout = options.operation_timeout
|
||||
@channels = []
|
||||
@responses = {}
|
||||
end
|
||||
@ -42,10 +40,10 @@ module HTTPX
|
||||
end
|
||||
|
||||
def response(request)
|
||||
@responses[request]
|
||||
@responses.delete(request)
|
||||
end
|
||||
|
||||
def process_events(timeout: @connection_timeout)
|
||||
def process_events(timeout: @operation_timeout)
|
||||
rmonitors = @channels
|
||||
wmonitors = rmonitors.reject(&:empty?)
|
||||
readers, writers = IO.select(rmonitors, wmonitors, nil, timeout)
|
||||
@ -60,9 +58,15 @@ module HTTPX
|
||||
end if writers
|
||||
end
|
||||
|
||||
def close(channel)
|
||||
@channels.delete(channel)
|
||||
channel.close
|
||||
def close(channel = nil)
|
||||
if channel
|
||||
@channels.delete(channel)
|
||||
channel.close
|
||||
else
|
||||
while ch = @channels.shift
|
||||
ch.close
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -4,6 +4,13 @@ module HTTPX
|
||||
class Headers
|
||||
EMPTY = [].freeze # :nodoc:
|
||||
|
||||
class << self
|
||||
def new(h = nil)
|
||||
return h if h.is_a?(self)
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(h = nil)
|
||||
@headers = {}
|
||||
return unless h
|
||||
@ -90,6 +97,10 @@ module HTTPX
|
||||
end
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
to_hash == Headers.new(other).to_hash
|
||||
end
|
||||
|
||||
# the headers store in Hash format
|
||||
def to_hash
|
||||
Hash[to_a]
|
||||
@ -133,7 +144,7 @@ module HTTPX
|
||||
end
|
||||
|
||||
def downcased(field)
|
||||
field.downcase
|
||||
String(field).downcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
104
lib/httpx/options.rb
Normal file
104
lib/httpx/options.rb
Normal file
@ -0,0 +1,104 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module HTTPX
|
||||
class Options
|
||||
KEEP_ALIVE_TIMEOUT = 5
|
||||
OPERATION_TIMEOUT = 5
|
||||
CONNECT_TIMEOUT = 5
|
||||
|
||||
class << self
|
||||
def new(options = {})
|
||||
return options if options.is_a?(self)
|
||||
super
|
||||
end
|
||||
|
||||
def defined_options
|
||||
@defined_options ||= []
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def def_option(name, &interpreter)
|
||||
defined_options << name.to_sym
|
||||
interpreter ||= lambda { |v| v }
|
||||
|
||||
attr_accessor name
|
||||
protected :"#{name}="
|
||||
|
||||
define_method(:"with_#{name}") do |value|
|
||||
dup { |opts| opts.send(:"#{name}=", instance_exec(value, &interpreter)) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(options = {})
|
||||
defaults = {
|
||||
:proxy => {},
|
||||
:ssl => {},
|
||||
:keep_alive_timeout => KEEP_ALIVE_TIMEOUT,
|
||||
:operation_timeout => OPERATION_TIMEOUT,
|
||||
:connect_timeout => CONNECT_TIMEOUT,
|
||||
:headers => {},
|
||||
:cookies => {},
|
||||
}
|
||||
|
||||
defaults.merge!(options)
|
||||
defaults[:headers] = Headers.new(defaults[:headers])
|
||||
defaults.each { |(k, v)| self[k] = v }
|
||||
end
|
||||
|
||||
def_option(:headers) do |headers|
|
||||
self.headers.merge(headers)
|
||||
end
|
||||
|
||||
def_option(:cookies) do |cookies|
|
||||
cookies.each_with_object self.cookies.dup do |(k, v), jar|
|
||||
cookie = k.is_a?(Cookie) ? k : Cookie.new(k.to_s, v.to_s)
|
||||
jar[cookie.name] = cookie.cookie_value
|
||||
end
|
||||
end
|
||||
|
||||
%w[
|
||||
proxy params form json body follow
|
||||
ssl_context ssl
|
||||
keep_alive_timeout connect_timeout operation_timeout
|
||||
].each do |method_name|
|
||||
def_option(method_name)
|
||||
end
|
||||
|
||||
def merge(other)
|
||||
h1 = to_hash
|
||||
h2 = other.to_hash
|
||||
|
||||
merged = h1.merge(h2) do |k, v1, v2|
|
||||
case k
|
||||
when :headers
|
||||
v1.merge(v2)
|
||||
else
|
||||
v2
|
||||
end
|
||||
end
|
||||
|
||||
self.class.new(merged)
|
||||
end
|
||||
|
||||
def to_hash
|
||||
hash_pairs = self.class.
|
||||
defined_options.
|
||||
flat_map { |opt_name| [opt_name, send(opt_name)] }
|
||||
Hash[*hash_pairs]
|
||||
end
|
||||
|
||||
def dup
|
||||
dupped = super
|
||||
yield(dupped) if block_given?
|
||||
dupped
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def []=(option, val)
|
||||
send(:"#{option}=", val)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user