require "httpi/request"
require "akami"
require "savon/wasabi/document"
require "savon/soap/xml"
require "savon/soap/request"
require "savon/soap/response"
module Savon
class Client
def initialize(wsdl_document = nil, &block)
self.config = Savon.config.clone
wsdl.document = wsdl_document if wsdl_document
process 1, &block if block
wsdl.request = http
end
attr_accessor :config
def wsdl
@wsdl ||= Wasabi::Document.new
end
def http
@http ||= HTTPI::Request.new
end
def wsse
@wsse ||= Akami.wsse
end
attr_reader :soap
def request(*args, &block)
raise ArgumentError, "Savon::Client#request requires at least one argument" if args.empty?
self.soap = SOAP::XML.new(config)
preconfigure (args)
process &block if block
soap.wsse = wsse
response = SOAP::Request.new(config, http, soap).response
set_cookie response.http.
if wsse.verify_response
WSSE::VerifySignature.new(response.http.body).verify!
end
response
end
private
attr_writer :soap
attr_accessor :original_self
def set_cookie()
if ["Set-Cookie"]
@cookies ||= {}
set_cookies = [["Set-Cookie"]].flatten
set_cookies.each do |set_cookie|
@cookies[set_cookie.split('=').first] = set_cookie.split(';').first
end
http.["Cookie"] = @cookies.values.join(';')
end
end
def (args)
attributes = Hash === args.last ? args.pop : {}
namespace = args.size > 1 ? args.shift.to_sym : nil
input = args.first
[namespace, input, attributes]
end
def preconfigure(args)
soap.endpoint = wsdl.endpoint
soap.element_form_default = wsdl.element_form_default
body = args[2].delete(:body)
soap.body = body if body
wsdl.type_namespaces.each do |path, uri|
soap.use_namespace(path, uri)
end
wsdl.type_definitions.each do |path, type|
soap.types[path] = type
end
soap_action = args[2].delete(:soap_action) || args[1]
set_soap_action soap_action
if wsdl.document? && (operation = wsdl.operations[args[1]]) && operation[:namespace_identifier]
soap.namespace_identifier = operation[:namespace_identifier].to_sym
soap.namespace = wsdl.parser.namespaces[soap.namespace_identifier.to_s]
args[0] = soap.namespace_identifier unless args[0]
else
soap.namespace_identifier = args[0]
soap.namespace = wsdl.namespace
end
set_soap_input *args
end
def set_soap_action(input_tag)
soap_action = wsdl.soap_action(input_tag.to_sym) if wsdl.document?
soap_action ||= Gyoku::XMLKey.create(input_tag).to_sym
http.["SOAPAction"] = %{"#{soap_action}"}
end
def set_soap_input(namespace, input, attributes)
new_input_tag = wsdl.soap_input(input.to_sym) if wsdl.document?
new_input_tag ||= Gyoku::XMLKey.create(input)
soap.input = [namespace, new_input_tag.to_sym, attributes]
end
def process(offset = 0, &block)
block.arity > 0 ? yield_objects(offset, &block) : evaluate(&block)
end
def yield_objects(offset, &block)
yield *[soap, wsdl, http, wsse][offset, block.arity]
end
def evaluate(&block)
self.original_self = eval "self", block.binding
instance_eval &block
end
def method_missing(method, *args, &block)
super unless original_self
original_self.send method, *args, &block
end
end
end