This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
module Typhoeus
|
||||
class Request
|
||||
|
||||
# Module containing logic about shortcuts to
|
||||
# http methods. Like
|
||||
# Typhoeus.get("www.example.com")
|
||||
module Actions
|
||||
|
||||
# Make a get request.
|
||||
#
|
||||
# @example Make get request.
|
||||
# Typhoeus.get("www.example.com")
|
||||
#
|
||||
# @param (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @option (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @return (see Typhoeus::Response#initialize)
|
||||
#
|
||||
# @note (see Typhoeus::Request#initialize)
|
||||
def get(base_url, options = {})
|
||||
Request.new(base_url, options.merge(:method => :get)).run
|
||||
end
|
||||
|
||||
# Make a post request.
|
||||
#
|
||||
# @example Make post request.
|
||||
# Typhoeus.post("www.example.com")
|
||||
#
|
||||
# @param (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @option (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @return (see Typhoeus::Response#initialize)
|
||||
#
|
||||
# @note (see Typhoeus::Request#initialize)
|
||||
def post(base_url, options = {})
|
||||
Request.new(base_url, options.merge(:method => :post)).run
|
||||
end
|
||||
|
||||
# Make a put request.
|
||||
#
|
||||
# @example Make put request.
|
||||
# Typhoeus.put("www.example.com")
|
||||
#
|
||||
# @param (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @option options :params [ Hash ] Params hash which
|
||||
# is attached to the base_url.
|
||||
# @option options :body [ Hash ] Body hash which
|
||||
# becomes a PUT request body.
|
||||
#
|
||||
# @return (see Typhoeus::Response#initialize)
|
||||
#
|
||||
# @note (see Typhoeus::Request#initialize)
|
||||
def put(base_url, options = {})
|
||||
Request.new(base_url, options.merge(:method => :put)).run
|
||||
end
|
||||
|
||||
# Make a delete request.
|
||||
#
|
||||
# @example Make delete request.
|
||||
# Typhoeus.delete("www.example.com")
|
||||
#
|
||||
# @param (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @option (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @return (see Typhoeus::Response#initialize)
|
||||
#
|
||||
# @note (see Typhoeus::Request#initialize)
|
||||
def delete(base_url, options = {})
|
||||
Request.new(base_url, options.merge(:method => :delete)).run
|
||||
end
|
||||
|
||||
# Make a head request.
|
||||
#
|
||||
# @example Make head request.
|
||||
# Typhoeus.head("www.example.com")
|
||||
#
|
||||
# @param (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @option (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @return (see Typhoeus::Response#initialize)
|
||||
#
|
||||
# @note (see Typhoeus::Request#initialize)
|
||||
def head(base_url, options = {})
|
||||
Request.new(base_url, options.merge(:method => :head)).run
|
||||
end
|
||||
|
||||
# Make a patch request.
|
||||
#
|
||||
# @example Make patch request.
|
||||
# Typhoeus.patch("www.example.com")
|
||||
#
|
||||
# @param (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @option (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @return (see Typhoeus::Response#initialize)
|
||||
#
|
||||
# @note (see Typhoeus::Request#initialize)
|
||||
def patch(base_url, options = {})
|
||||
Request.new(base_url, options.merge(:method => :patch)).run
|
||||
end
|
||||
|
||||
# Make a options request.
|
||||
#
|
||||
# @example Make options request.
|
||||
# Typhoeus.options("www.example.com")
|
||||
#
|
||||
# @param (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @option (see Typhoeus::Request#initialize)
|
||||
#
|
||||
# @return (see Typhoeus::Response#initialize)
|
||||
#
|
||||
# @note (see Typhoeus::Request#initialize)
|
||||
def options(base_url, options = {})
|
||||
Request.new(base_url, options.merge(:method => :options)).run
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
module Typhoeus
|
||||
class Request
|
||||
|
||||
# This module provides a way to hook into before
|
||||
# a request runs. This is very powerful
|
||||
# and you should be careful because when you accidently
|
||||
# return a falsy value the request won't be executed.
|
||||
#
|
||||
# @api private
|
||||
module Before
|
||||
|
||||
# Overrride run in order to execute callbacks in
|
||||
# Typhoeus.before. Will break and return when a
|
||||
# callback returns nil or false. Calls super
|
||||
# otherwise.
|
||||
#
|
||||
# @example Run the request.
|
||||
# request.run
|
||||
def run
|
||||
Typhoeus.before.each do |callback|
|
||||
value = callback.call(self)
|
||||
if value.nil? || value == false || value.is_a?(Response)
|
||||
return response
|
||||
end
|
||||
end
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
module Typhoeus
|
||||
class Request
|
||||
|
||||
# This module handles the blocked connection request mode on
|
||||
# the request side, where only stubbed requests
|
||||
# are allowed.
|
||||
# Connection blocking needs to be turned on:
|
||||
# Typhoeus.configure do |config|
|
||||
# config.block_connection = true
|
||||
# end
|
||||
#
|
||||
# When trying to do real requests a NoStub error
|
||||
# is raised.
|
||||
#
|
||||
# @api private
|
||||
module BlockConnection
|
||||
|
||||
# Overrides run in order to check before if block connection
|
||||
# is turned on. If thats the case a NoStub error is
|
||||
# raised.
|
||||
#
|
||||
# @example Run request.
|
||||
# request.run
|
||||
#
|
||||
# @raise [Typhoeus::Errors::NoStub] If connection is blocked
|
||||
# and no stub defined.
|
||||
def run
|
||||
if blocked?
|
||||
raise Typhoeus::Errors::NoStub.new(self)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
# Returns wether a request is blocked or not. Takes
|
||||
# request.block_connection and Typhoeus::Config.block_connection
|
||||
# into consideration.
|
||||
#
|
||||
# @example Blocked?
|
||||
# request.blocked?
|
||||
#
|
||||
# @return [ Boolean ] True if blocked, false else.
|
||||
def blocked?
|
||||
if block_connection.nil?
|
||||
Typhoeus::Config.block_connection
|
||||
else
|
||||
block_connection
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,38 @@
|
||||
module Typhoeus
|
||||
class Request
|
||||
module Cacheable
|
||||
def response=(response)
|
||||
cache.set(self, response) if cacheable? && !response.cached?
|
||||
super
|
||||
end
|
||||
|
||||
def cacheable?
|
||||
cache
|
||||
end
|
||||
|
||||
def run
|
||||
if response = cached_response
|
||||
response.cached = true
|
||||
finish(response)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def cached_response
|
||||
cacheable? && cache.get(self)
|
||||
end
|
||||
|
||||
def cache_ttl
|
||||
options[:cache_ttl]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cache
|
||||
return nil if options[:cache] === false
|
||||
options[:cache] || Typhoeus::Config.cache
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,151 @@
|
||||
module Typhoeus
|
||||
class Request
|
||||
|
||||
# This module contains the logic for the response callbacks.
|
||||
#
|
||||
# You can set multiple callbacks, which are then executed
|
||||
# in the same order.
|
||||
#
|
||||
# request.on_complete { |response| p 1 }
|
||||
# request.on_complete { |response| p 2 }
|
||||
# request.execute_callbacks
|
||||
# #=> 1
|
||||
# #=> 2
|
||||
#
|
||||
# You can clear the callbacks:
|
||||
#
|
||||
# request.on_complete { |response| p 1 }
|
||||
# request.on_complete { |response| p 2 }
|
||||
# request.on_complete.clear
|
||||
# request.execute_callbacks
|
||||
# #=> nil
|
||||
#
|
||||
# @note If you're using the Hydra to execute multiple
|
||||
# requests, then callbacks are delaying the
|
||||
# request execution.
|
||||
module Callbacks
|
||||
|
||||
module Types # :nodoc:
|
||||
# Set on_complete callback.
|
||||
#
|
||||
# @example Set on_complete.
|
||||
# request.on_complete { |response| p "yay" }
|
||||
#
|
||||
# @param [ Block ] block The block to execute.
|
||||
#
|
||||
# @yield [ Typhoeus::Response ]
|
||||
#
|
||||
# @return [ Array<Block> ] All on_complete blocks.
|
||||
def on_complete(&block)
|
||||
@on_complete ||= []
|
||||
@on_complete << block if block_given?
|
||||
@on_complete
|
||||
end
|
||||
|
||||
# Set on_success callback.
|
||||
#
|
||||
# @example Set on_success.
|
||||
# request.on_success { |response| p "yay" }
|
||||
#
|
||||
# @param [ Block ] block The block to execute.
|
||||
#
|
||||
# @yield [ Typhoeus::Response ]
|
||||
#
|
||||
# @return [ Array<Block> ] All on_success blocks.
|
||||
def on_success(&block)
|
||||
@on_success ||= []
|
||||
@on_success << block if block_given?
|
||||
@on_success
|
||||
end
|
||||
|
||||
# Set on_failure callback.
|
||||
#
|
||||
# @example Set on_failure.
|
||||
# request.on_failure { |response| p "yay" }
|
||||
#
|
||||
# @param [ Block ] block The block to execute.
|
||||
#
|
||||
# @yield [ Typhoeus::Response ]
|
||||
#
|
||||
# @return [ Array<Block> ] All on_failure blocks.
|
||||
def on_failure(&block)
|
||||
@on_failure ||= []
|
||||
@on_failure << block if block_given?
|
||||
@on_failure
|
||||
end
|
||||
|
||||
# Set on_headers callback.
|
||||
#
|
||||
# @example Set on_headers.
|
||||
# request.on_headers { |response| p "yay" }
|
||||
#
|
||||
# @param [ Block ] block The block to execute.
|
||||
#
|
||||
# @yield [ Typhoeus::Response ]
|
||||
#
|
||||
# @return [ Array<Block> ] All on_headers blocks.
|
||||
def on_headers(&block)
|
||||
@on_headers ||= []
|
||||
@on_headers << block if block_given?
|
||||
@on_headers
|
||||
end
|
||||
|
||||
# Set on_progress callback.
|
||||
#
|
||||
# @example Set on_progress.
|
||||
# request.on_progress do |dltotal, dlnow, ultotal, ulnow|
|
||||
# puts "dltotal (#{dltotal}), dlnow (#{dlnow}), ultotal (#{ultotal}), ulnow (#{ulnow})"
|
||||
# end
|
||||
#
|
||||
# @param [ Block ] block The block to execute.
|
||||
#
|
||||
# @yield [ Typhoeus::Response ]
|
||||
#
|
||||
# @return [ Array<Block> ] All on_progress blocks.
|
||||
def on_progress(&block)
|
||||
@on_progress ||= []
|
||||
@on_progress << block if block_given?
|
||||
@on_progress
|
||||
end
|
||||
end
|
||||
|
||||
# Execute the headers callbacks and yields response.
|
||||
#
|
||||
# @example Execute callbacks.
|
||||
# request.execute_headers_callbacks
|
||||
#
|
||||
# @return [ Array<Object> ] The results of the on_headers callbacks.
|
||||
#
|
||||
# @api private
|
||||
def execute_headers_callbacks(response)
|
||||
(Typhoeus.on_headers + on_headers).map do |callback|
|
||||
callback.call(response)
|
||||
end
|
||||
end
|
||||
|
||||
# Execute necessary callback and yields response. This
|
||||
# include in every case on_complete and on_progress, on_success
|
||||
# if successful and on_failure if not.
|
||||
#
|
||||
# @example Execute callbacks.
|
||||
# request.execute_callbacks
|
||||
#
|
||||
# @return [ void ]
|
||||
#
|
||||
# @api private
|
||||
def execute_callbacks
|
||||
callbacks = Typhoeus.on_complete + Typhoeus.on_progress + on_complete + on_progress
|
||||
|
||||
if response && response.success?
|
||||
callbacks += Typhoeus.on_success + on_success
|
||||
elsif response
|
||||
callbacks += Typhoeus.on_failure + on_failure
|
||||
end
|
||||
|
||||
callbacks.each do |callback|
|
||||
self.response.handled_response = callback.call(self.response)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
module Typhoeus
|
||||
class Request
|
||||
|
||||
# This module contains custom serializer.
|
||||
module Marshal
|
||||
|
||||
# Return the important data needed to serialize this Request, except the
|
||||
# request callbacks and `hydra`, since they cannot be marshalled.
|
||||
def marshal_dump
|
||||
unmarshallable = %w(@on_complete @on_success @on_failure @on_progress @on_headers @on_body @hydra)
|
||||
(instance_variables - unmarshallable - unmarshallable.map(&:to_sym)).map do |name|
|
||||
[name, instance_variable_get(name)]
|
||||
end
|
||||
end
|
||||
|
||||
# Load.
|
||||
def marshal_load(attributes)
|
||||
attributes.each { |name, value| instance_variable_set(name, value) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,38 @@
|
||||
module Typhoeus
|
||||
class Request
|
||||
|
||||
# This module handles the GET request memoization
|
||||
# on the request side. Memoization needs to be turned
|
||||
# on:
|
||||
# Typhoeus.configure do |config|
|
||||
# config.memoize = true
|
||||
# end
|
||||
#
|
||||
# @api private
|
||||
module Memoizable
|
||||
|
||||
# Override response setter and memoizes response
|
||||
# if the request is memoizable.
|
||||
#
|
||||
# @param [ Response ] response The response to set.
|
||||
#
|
||||
# @example Set response.
|
||||
# request.response = response
|
||||
def response=(response)
|
||||
hydra.memory[self] = response if memoizable?
|
||||
super
|
||||
end
|
||||
|
||||
# Return whether a request is memoizable.
|
||||
#
|
||||
# @example Is request memoizable?
|
||||
# request.memoizable?
|
||||
#
|
||||
# @return [ Boolean ] Return true if memoizable, false else.
|
||||
def memoizable?
|
||||
Typhoeus::Config.memoize &&
|
||||
(options[:method].nil? || options[:method] == :get)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
module Typhoeus
|
||||
class Request
|
||||
|
||||
# This module contains everything what is necessary
|
||||
# to make a single request.
|
||||
module Operations
|
||||
|
||||
# Run a request.
|
||||
#
|
||||
# @example Run a request.
|
||||
# Typhoeus::Request.new("www.example.com").run
|
||||
#
|
||||
# @return [ Response ] The response.
|
||||
def run
|
||||
easy = EasyFactory.new(self).get
|
||||
easy.perform
|
||||
response
|
||||
end
|
||||
|
||||
# Sets a response, the request on the response
|
||||
# and executes the callbacks.
|
||||
#
|
||||
# @param [Typhoeus::Response] response The response.
|
||||
# @param [Boolean] bypass_memoization Wether to bypass
|
||||
# memoization or not. Decides how the response is set.
|
||||
#
|
||||
# @return [Typhoeus::Response] The response.
|
||||
def finish(response, bypass_memoization = nil)
|
||||
if bypass_memoization
|
||||
@response = response
|
||||
else
|
||||
self.response = response
|
||||
end
|
||||
self.response.request = self
|
||||
execute_callbacks
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
module Typhoeus
|
||||
class Request
|
||||
|
||||
# This module contains logic for having a reponse
|
||||
# getter and setter.
|
||||
module Responseable
|
||||
|
||||
# Set the response.
|
||||
#
|
||||
# @example Set response.
|
||||
# request.response = response
|
||||
#
|
||||
# @param [ Response ] value The response to set.
|
||||
def response=(value)
|
||||
@response = value
|
||||
end
|
||||
|
||||
# Return the response.
|
||||
#
|
||||
# @example Return response.
|
||||
# request.response
|
||||
#
|
||||
# @return [ Response ] The response.
|
||||
def response
|
||||
@response ||= nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
module Typhoeus
|
||||
class Request
|
||||
|
||||
# This module contians the logic for response streaming.
|
||||
module Streamable
|
||||
|
||||
# Set on_body callback.
|
||||
#
|
||||
# This callback will be called each time a portion of the body is read from the socket.
|
||||
# Setting an on_body callback will cause the response body to be empty.
|
||||
#
|
||||
# @example Set on_body.
|
||||
# request.on_body { |body_chunk, response| puts "Got #{body_chunk.bytesize} bytes" }
|
||||
#
|
||||
# @param [ Block ] block The block to execute.
|
||||
#
|
||||
# @yield [ Typhoeus::Response, String ]
|
||||
#
|
||||
# @return [ Array<Block> ] All on_body blocks.
|
||||
def on_body(&block)
|
||||
@on_body ||= []
|
||||
@on_body << block if block_given?
|
||||
@on_body
|
||||
end
|
||||
|
||||
# Is this request using streaming?
|
||||
#
|
||||
# @return [ Boolean ] True if any on_body blocks have been set.
|
||||
def streaming?
|
||||
defined?(@on_body) && @on_body.any?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
module Typhoeus
|
||||
class Request
|
||||
|
||||
# This module handles stubbing on the request side.
|
||||
# It plays well with the block_connection configuration,
|
||||
# which raises when you make a request which is not stubbed.
|
||||
#
|
||||
# @api private
|
||||
module Stubbable
|
||||
|
||||
# Override run in order to check for matching expectations.
|
||||
# When an expectation is found, super is not called. Instead a
|
||||
# canned response is assigned to the request.
|
||||
#
|
||||
# @example Run the request.
|
||||
# request.run
|
||||
#
|
||||
# @return [ Response ] The response.
|
||||
def run
|
||||
if response = Expectation.response_for(self)
|
||||
execute_headers_callbacks(response)
|
||||
self.on_body.each{ |callback| callback.call(response.body, response) }
|
||||
finish(response)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user