diff options
74 files changed, 5479 insertions, 0 deletions
diff --git a/lib/soap/header/handler.rb b/lib/soap/header/handler.rb new file mode 100644 index 000000000..7da2836e2 --- /dev/null +++ b/lib/soap/header/handler.rb @@ -0,0 +1,57 @@ +# SOAP4R - SOAP Header handler item +# Copyright (C) 2003, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/element' + + +module SOAP +module Header + + +class Handler + attr_reader :elename + attr_reader :mustunderstand + attr_reader :encodingstyle + + def initialize(elename) + @elename = elename + @mustunderstand = false + @encodingstyle = nil + end + + # Should return a SOAP/OM, a SOAPHeaderItem or nil. + def on_outbound + nil + end + + # Given header is a SOAPHeaderItem or nil. + def on_inbound(header, mustunderstand = false) + # do something. + end + + def on_outbound_headeritem + item = on_outbound + if item.nil? + nil + elsif item.is_a?(::SOAP::SOAPHeaderItem) + item.elename = @elename + item + else + item.elename = @elename + ::SOAP::SOAPHeaderItem.new(item, @mustunderstand, @encodingstyle) + end + end + + def on_inbound_headeritem(header) + on_inbound(header.element, header.mustunderstand) + end +end + + +end +end diff --git a/lib/soap/header/handlerset.rb b/lib/soap/header/handlerset.rb new file mode 100644 index 000000000..499d6bb8a --- /dev/null +++ b/lib/soap/header/handlerset.rb @@ -0,0 +1,58 @@ +# SOAP4R - SOAP Header handler set +# Copyright (C) 2003, 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/namedelements' + + +module SOAP +module Header + + +class HandlerSet + def initialize + @store = XSD::NamedElements.new + end + + def add(handler) + @store << handler + end + alias << add + + def delete(handler) + @store.delete(handler) + end + + def include?(handler) + @store.include?(handler) + end + + # returns: Array of SOAPHeaderItem + def on_outbound + @store.collect { |handler| + handler.on_outbound_headeritem + }.compact + end + + # headers: SOAPHeaderItem enumerable object + def on_inbound(headers) + headers.each do |name, item| + handler = @store.find { |handler| + handler.elename == item.element.elename + } + if handler + handler.on_inbound_headeritem(item) + elsif item.mustunderstand + raise UnhandledMustUnderstandHeaderError.new(item.element.elename.to_s) + end + end + end +end + + +end +end diff --git a/lib/soap/header/simplehandler.rb b/lib/soap/header/simplehandler.rb new file mode 100644 index 000000000..e7268e04a --- /dev/null +++ b/lib/soap/header/simplehandler.rb @@ -0,0 +1,44 @@ +# SOAP4R - SOAP Simple header item handler +# Copyright (C) 2003, 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/header/handler' +require 'soap/baseData' + + +module SOAP +module Header + + +class SimpleHandler < SOAP::Header::Handler + def initialize(elename) + super(elename) + end + + # Should return a Hash or nil. + def on_simple_outbound + nil + end + + # Given header is a Hash or nil. + def on_simple_inbound(header, mustunderstand) + end + + def on_outbound + h = on_simple_outbound + h ? SOAPElement.from_obj(h) : nil + end + + def on_inbound(header, mustunderstand) + h = header.to_obj + on_simple_inbound(h, mustunderstand) + end +end + + +end +end diff --git a/lib/soap/rpc/httpserver.rb b/lib/soap/rpc/httpserver.rb new file mode 100644 index 000000000..7b1f961d9 --- /dev/null +++ b/lib/soap/rpc/httpserver.rb @@ -0,0 +1,105 @@ +# SOAP4R - WEBrick HTTP Server +# Copyright (C) 2003, 2004 by NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'logger' +require 'soap/rpc/soaplet' +require 'soap/streamHandler' +require 'webrick' + + +module SOAP +module RPC + + +class HTTPServer < Logger::Application + attr_reader :server + attr_accessor :default_namespace + + def initialize(config) + super(config[:SOAPHTTPServerApplicationName] || self.class.name) + @default_namespace = config[:SOAPDefaultNamespace] + @webrick_config = config.dup + @webrick_config[:Logger] ||= @log + @server = nil + @soaplet = ::SOAP::RPC::SOAPlet.new + self.level = Logger::Severity::INFO + on_init + end + + def on_init + # define extra methods in derived class. + end + + def status + if @server + @server.status + else + nil + end + end + + def shutdown + @server.shutdown if @server + end + + def mapping_registry + @soaplet.app_scope_router.mapping_registry + end + + def mapping_registry=(mapping_registry) + @soaplet.app_scope_router.mapping_registry = mapping_registry + end + + def add_rpc_request_servant(factory, namespace = @default_namespace, + mapping_registry = nil) + @soaplet.add_rpc_request_servant(factory, namespace, mapping_registry) + end + + def add_rpc_servant(obj, namespace = @default_namespace) + @soaplet.add_rpc_servant(obj, namespace) + end + + def add_rpc_request_headerhandler(factory) + @soaplet.add_rpc_request_headerhandler(factory) + end + + def add_rpc_headerhandler(obj) + @soaplet.add_rpc_headerhandler(obj) + end + + def add_method(obj, name, *param) + add_method_as(obj, name, name, *param) + end + + def add_method_as(obj, name, name_as, *param) + qname = XSD::QName.new(@default_namespace, name_as) + soapaction = nil + method = obj.method(name) + param_def = if param.size == 1 and param[0].is_a?(Array) + param[0] + elsif param.empty? + ::SOAP::RPC::SOAPMethod.create_param_def( + (1..method.arity.abs).collect { |i| "p#{ i }" }) + else + SOAP::RPC::SOAPMethod.create_param_def(param) + end + @soaplet.app_scope_router.add_method(obj, qname, soapaction, name, param_def) + end + +private + + def run + @server = WEBrick::HTTPServer.new(@webrick_config) + @server.mount('/', @soaplet) + @server.start + end +end + + +end +end diff --git a/lib/wsdl/soap/cgiStubCreator.rb b/lib/wsdl/soap/cgiStubCreator.rb new file mode 100644 index 000000000..e5b64336e --- /dev/null +++ b/lib/wsdl/soap/cgiStubCreator.rb @@ -0,0 +1,73 @@ +# WSDL4R - Creating CGI stub code from WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/mappingRegistryCreator' +require 'wsdl/soap/methodDefCreator' +require 'wsdl/soap/classDefCreatorSupport' + + +module WSDL +module SOAP + + +class CGIStubCreator + include ClassDefCreatorSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + end + + def dump(service_name) + STDERR.puts "!!! IMPORTANT !!!" + STDERR.puts "- CGI stub can only 1 port. Creating stub for the first port... Rests are ignored." + STDERR.puts "!!! IMPORTANT !!!" + port = @definitions.service(service_name).ports[0] + dump_porttype(port.porttype.name) + end + +private + + def dump_porttype(name) + class_name = create_class_name(name) + methoddef, types = MethodDefCreator.new(@definitions).dump(name) + mr_creator = MappingRegistryCreator.new(@definitions) + c1 = ::XSD::CodeGen::ClassDef.new(class_name) + c1.def_require("soap/rpc/cgistub") + c1.def_require("soap/mapping/registry") + c1.def_const("MappingRegistry", "::SOAP::Mapping::Registry.new") + c1.def_code(mr_creator.dump(types)) + c1.def_code <<-EOD +Methods = [ +#{ methoddef.gsub(/^/, " ") } +] + EOD + c2 = ::XSD::CodeGen::ClassDef.new(class_name + "App", + "::SOAP::RPC::CGIStub") + c2.def_method("initialize", "*arg") do + <<-EOD + super(*arg) + servant = #{class_name}.new + #{class_name}::Methods.each do |name_as, name, params, soapaction, ns| + add_method_with_namespace_as(ns, servant, name, name_as, params, soapaction) + end + self.mapping_registry = #{class_name}::MappingRegistry + self.level = Logger::Severity::ERROR + EOD + end + c1.dump + "\n" + c2.dump + format(<<-EOD) + #{class_name}App.new('app', nil).start + EOD + end +end + + +end +end diff --git a/lib/wsdl/soap/classDefCreator.rb b/lib/wsdl/soap/classDefCreator.rb new file mode 100644 index 000000000..6c7d38193 --- /dev/null +++ b/lib/wsdl/soap/classDefCreator.rb @@ -0,0 +1,112 @@ +# WSDL4R - Creating class definition from WSDL +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/data' +require 'wsdl/soap/classDefCreatorSupport' +require 'xsd/codegen' + + +module WSDL +module SOAP + + +class ClassDefCreator + include ClassDefCreatorSupport + + def initialize(definitions) + @simpletypes = definitions.collect_simpletypes + @complextypes = definitions.collect_complextypes + @faulttypes = definitions.collect_faulttypes + end + + def dump(class_name = nil) + result = "" + if class_name + result = dump_classdef(class_name) + else + @complextypes.each do |type| + case type.compoundtype + when :TYPE_STRUCT + result << dump_classdef(type) + when :TYPE_ARRAY + result << dump_arraydef(type) + else + raise RuntimeError.new("Unknown complexContent definition...") + end + result << "\n" + end + + result << @simpletypes.collect { |type| + dump_simpletypedef(type) + }.join("\n") + end + result + end + +private + + def dump_simpletypedef(simpletype) + qname = simpletype.name + if simpletype.restriction.enumeration.empty? + STDERR.puts("#{qname}: simpleType which is not enum type not supported.") + return "" + end + c = XSD::CodeGen::ModuleDef.new(create_class_name(qname)) + c.comment = "#{ qname.namespace }" + simpletype.restriction.enumeration.each do |value| + c.def_const(safeconstname(value), value.dump) + end + c.dump + end + + def dump_classdef(complextype) + qname = complextype.name + if @faulttypes.index(qname) + c = XSD::CodeGen::ClassDef.new(create_class_name(qname), + "::StandardError") + else + c = XSD::CodeGen::ClassDef.new(create_class_name(qname)) + end + c.comment = "#{ qname.namespace }" + c.def_classvar("schema_type", qname.name.dump) + c.def_classvar("schema_ns", qname.namespace.dump) + init_lines = "" + params = [] + complextype.each_element do |element| + name = element.name.name + varname = safevarname(name) + c.def_attr(name, true, varname) + init_lines << "@#{ varname } = #{ varname }\n" + params << "#{ varname } = nil" + end + complextype.attributes.each do |attribute| + name = "attr_" + attribute.name + varname = safevarname(name) + c.def_attr(name, true, varname) + init_lines << "@#{ varname } = #{ varname }\n" + params << "#{ varname } = nil" + end + c.def_method("initialize", *params) do + init_lines + end + c.dump + end + + def dump_arraydef(complextype) + qname = complextype.name + c = XSD::CodeGen::ClassDef.new(create_class_name(qname), "::Array") + c.comment = "#{ qname.namespace }" + c.def_classvar("schema_type", qname.name.dump) + c.def_classvar("schema_ns", qname.namespace.dump) + c.dump + end +end + + +end +end diff --git a/lib/wsdl/soap/classDefCreatorSupport.rb b/lib/wsdl/soap/classDefCreatorSupport.rb new file mode 100644 index 000000000..dbcc55f7b --- /dev/null +++ b/lib/wsdl/soap/classDefCreatorSupport.rb @@ -0,0 +1,106 @@ +# WSDL4R - Creating class code support from WSDL. +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'soap/mapping' +require 'soap/mapping/typeMap' +require 'xsd/codegen/gensupport' + + +module WSDL +module SOAP + + +module ClassDefCreatorSupport + include XSD::CodeGen::GenSupport + + def create_class_name(qname) + if klass = basetype_mapped_class(qname) + ::SOAP::Mapping::DefaultRegistry.find_mapped_obj_class(klass.name) + else + safeconstname(qname.name) + end + end + + def basetype_mapped_class(name) + ::SOAP::TypeMap[name] + end + + def dump_method_signature(operation) + name = operation.name.name + input = operation.input + output = operation.output + fault = operation.fault + signature = "#{ name }#{ dump_inputparam(input) }" + str = <<__EOD__ +# SYNOPSIS +# #{name}#{dump_inputparam(input)} +# +# ARGS +#{dump_inout_type(input).chomp} +# +# RETURNS +#{dump_inout_type(output).chomp} +# +__EOD__ + unless fault.empty? + faultstr = (fault.collect { |f| dump_inout_type(f).chomp }).join(', ') + str <<<<__EOD__ +# RAISES +# #{faultstr} +# +__EOD__ + end + str + end + +private + + def dump_inout_type(param) + if param + message = param.find_message + params = "" + message.parts.each do |part| + next unless part.type + name = safevarname(part.name) + typename = safeconstname(part.type.name) + params << add_at("# #{name}", "#{typename} - #{part.type}\n", 20) + end + unless params.empty? + return params + end + end + "# N/A\n" + end + + def dump_inputparam(input) + message = input.find_message + params = "" + message.parts.each do |part| + params << ", " unless params.empty? + params << safevarname(part.name) + end + if params.empty? + "" + else + "(#{ params })" + end + end + + def add_at(base, str, pos) + if base.size >= pos + base + ' ' + str + else + base + ' ' * (pos - base.size) + str + end + end +end + + +end +end diff --git a/lib/wsdl/soap/clientSkeltonCreator.rb b/lib/wsdl/soap/clientSkeltonCreator.rb new file mode 100644 index 000000000..9c538dd61 --- /dev/null +++ b/lib/wsdl/soap/clientSkeltonCreator.rb @@ -0,0 +1,78 @@ +# WSDL4R - Creating client skelton code from WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/classDefCreatorSupport' + + +module WSDL +module SOAP + + +class ClientSkeltonCreator + include ClassDefCreatorSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + end + + def dump(service_name) + result = "" + @definitions.service(service_name).ports.each do |port| + result << dump_porttype(port.porttype.name) + result << "\n" + end + result + end + +private + + def dump_porttype(name) + drv_name = create_class_name(name) + + result = "" + result << <<__EOD__ +endpoint_url = ARGV.shift +obj = #{ drv_name }.new(endpoint_url) + +# Uncomment the below line to see SOAP wiredumps. +# obj.wiredump_dev = STDERR + +__EOD__ + @definitions.porttype(name).operations.each do |operation| + result << dump_method_signature(operation) + result << dump_input_init(operation.input) << "\n" + result << dump_operation(operation) << "\n\n" + end + result + end + + def dump_operation(operation) + name = operation.name + input = operation.input + "puts obj.#{ safemethodname(name.name) }#{ dump_inputparam(input) }" + end + + def dump_input_init(input) + result = input.find_message.parts.collect { |part| + "#{ uncapitalize(part.name) }" + }.join(" = ") + if result.empty? + "" + else + result << " = nil" + end + result + end +end + + +end +end diff --git a/lib/wsdl/soap/driverCreator.rb b/lib/wsdl/soap/driverCreator.rb new file mode 100644 index 000000000..50be8ed1d --- /dev/null +++ b/lib/wsdl/soap/driverCreator.rb @@ -0,0 +1,84 @@ +# WSDL4R - Creating driver code from WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/mappingRegistryCreator' +require 'wsdl/soap/methodDefCreator' +require 'wsdl/soap/classDefCreatorSupport' +require 'xsd/codegen' + + +module WSDL +module SOAP + + +class DriverCreator + include ClassDefCreatorSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + end + + def dump(porttype = nil) + if porttype.nil? + result = "" + @definitions.porttypes.each do |type| + result << dump_porttype(type.name) + result << "\n" + end + else + result = dump_porttype(porttype) + end + result + end + +private + + def dump_porttype(name) + class_name = create_class_name(name) + methoddef, types = MethodDefCreator.new(@definitions).dump(name) + mr_creator = MappingRegistryCreator.new(@definitions) + binding = @definitions.bindings.find { |item| item.type == name } + addresses = @definitions.porttype(name).locations + + c = ::XSD::CodeGen::ClassDef.new(class_name, "::SOAP::RPC::Driver") + c.def_require("soap/rpc/driver") + c.def_const("MappingRegistry", "::SOAP::Mapping::Registry.new") + c.def_const("DefaultEndpointUrl", addresses[0].dump) + c.def_code(mr_creator.dump(types)) + c.def_code <<-EOD +Methods = [ +#{ methoddef.gsub(/^/, " ") } +] + EOD + c.def_method("initialize", "endpoint_url = nil") do + <<-EOD + endpoint_url ||= DefaultEndpointUrl + super(endpoint_url, nil) + self.mapping_registry = MappingRegistry + init_methods + EOD + end + c.def_privatemethod("init_methods") do + <<-EOD + Methods.each do |name_as, name, params, soapaction, namespace| + qname = ::XSD::QName.new(namespace, name_as) + @proxy.add_method(qname, soapaction, name, params) + add_rpc_method_interface(name, params) + end + EOD + end + c.dump + end +end + + +end +end diff --git a/lib/wsdl/soap/mappingRegistryCreator.rb b/lib/wsdl/soap/mappingRegistryCreator.rb new file mode 100644 index 000000000..d3b28f47e --- /dev/null +++ b/lib/wsdl/soap/mappingRegistryCreator.rb @@ -0,0 +1,90 @@ +# WSDL4R - Creating MappingRegistry code from WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/classDefCreatorSupport' + + +module WSDL +module SOAP + + +class MappingRegistryCreator + include ClassDefCreatorSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + @complextypes = @definitions.collect_complextypes + @types = nil + end + + def dump(types) + @types = types + map_cache = [] + map = "" + @types.each do |type| + if map_cache.index(type).nil? + map_cache << type + if type.namespace != XSD::Namespace + if typemap = dump_typemap(type) + map << typemap + end + end + end + end + return map + end + +private + + def dump_typemap(type) + if definedtype = @complextypes[type] + case definedtype.compoundtype + when :TYPE_STRUCT + dump_struct_typemap(definedtype) + when :TYPE_ARRAY + dump_array_typemap(definedtype) + else + raise NotImplementedError.new("Must not reach here.") + end + end + end + + def dump_struct_typemap(definedtype) + ele = definedtype.name + return <<__EOD__ +MappingRegistry.set( + #{ create_class_name(ele) }, + ::SOAP::SOAPStruct, + ::SOAP::Mapping::Registry::TypedStructFactory, + { :type => ::XSD::QName.new("#{ ele.namespace }", "#{ ele.name }") } +) +__EOD__ + end + + def dump_array_typemap(definedtype) + ele = definedtype.name + arytype = definedtype.find_arytype || XSD::AnyTypeName + type = XSD::QName.new(arytype.namespace, arytype.name.sub(/\[(?:,)*\]$/, '')) + @types << type + return <<__EOD__ +MappingRegistry.set( + #{ create_class_name(ele) }, + ::SOAP::SOAPArray, + ::SOAP::Mapping::Registry::TypedArrayFactory, + { :type => ::XSD::QName.new("#{ type.namespace }", "#{ type.name }") } +) +__EOD__ + end +end + + +end +end diff --git a/lib/wsdl/soap/methodDefCreator.rb b/lib/wsdl/soap/methodDefCreator.rb new file mode 100644 index 000000000..eded972cd --- /dev/null +++ b/lib/wsdl/soap/methodDefCreator.rb @@ -0,0 +1,148 @@ +# WSDL4R - Creating driver code from WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/classDefCreatorSupport' + + +module WSDL +module SOAP + + +class MethodDefCreator + include ClassDefCreatorSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + @simpletypes = @definitions.collect_simpletypes + @complextypes = @definitions.collect_complextypes + @elements = @definitions.collect_elements + @types = nil + end + + def dump(porttype) + @types = [] + result = "" + operations = @definitions.porttype(porttype).operations + binding = @definitions.porttype_binding(porttype) + operations.each do |operation| + op_bind = binding.operations[operation.name] + result << ",\n" unless result.empty? + result << dump_method(operation, op_bind).chomp + end + return result, @types + end + +private + + def dump_method(operation, binding) + name = safemethodname(operation.name.name) + name_as = operation.name.name + params = collect_parameter(operation) + soapaction = binding.soapoperation.soapaction + namespace = binding.input.soapbody.namespace + paramstr = param2str(params) + if paramstr.empty? + paramstr = '[]' + else + paramstr = "[\n" << paramstr.gsub(/^/, ' ') << "\n ]" + end + return <<__EOD__ +[#{ dq(name_as) }, #{ dq(name) }, + #{ paramstr }, + #{ soapaction ? dq(soapaction) : "nil" }, #{ dq(namespace) } +] +__EOD__ + end + + def collect_parameter(operation) + result = operation.inputparts.collect { |part| + collect_type(part.type) + param_set('in', definedtype(part), part.name) + } + outparts = operation.outputparts + if outparts.size > 0 + retval = outparts[0] + collect_type(retval.type) + result << param_set('retval', definedtype(retval), retval.name) + cdr(outparts).each { |part| + collect_type(part.type) + result << param_set('out', definedtype(part), part.name) + } + end + result + end + + def definedtype(part) + if mapped = basetype_mapped_class(part.type) + ['::' + mapped.name] + elsif definedelement = @elements[part.element] + raise RuntimeError.new("Part: #{part.name} should be typed for RPC service for now.") + elsif definedtype = @simpletypes[part.type] + ['::' + basetype_mapped_class(definedtype.base).name] + elsif definedtype = @complextypes[part.type] + case definedtype.compoundtype + when :TYPE_STRUCT + ['::SOAP::SOAPStruct', part.type.namespace, part.type.name] + when :TYPE_ARRAY + arytype = definedtype.find_arytype || XSD::AnyTypeName + ns = arytype.namespace + name = arytype.name.sub(/\[(?:,)*\]$/, '') + ['::SOAP::SOAPArray', ns, name] + else + raise NotImplementedError.new("Must not reach here.") + end + else + raise RuntimeError.new("Part: #{part.name} cannot be resolved.") + end + end + + def param_set(io_type, type, name) + [io_type, type, name] + end + + def collect_type(type) + # ignore inline type definition. + return if type.nil? + @types << type + return unless @complextypes[type] + @complextypes[type].each_element do |element| + collect_type(element.type) + end + end + + def param2str(params) + params.collect { |param| + "[#{ dq(param[0]) }, #{ dq(param[2]) }, #{ type2str(param[1]) }]" + }.join(",\n") + end + + def type2str(type) + if type.size == 1 + "[#{ type[0] }]" + else + "[#{ type[0] }, #{ dq(type[1]) }, #{ dq(type[2]) }]" + end + end + + def dq(ele) + "\"" << ele << "\"" + end + + def cdr(ary) + result = ary.dup + result.shift + result + end +end + + +end +end diff --git a/lib/wsdl/soap/servantSkeltonCreator.rb b/lib/wsdl/soap/servantSkeltonCreator.rb new file mode 100644 index 000000000..bf293949b --- /dev/null +++ b/lib/wsdl/soap/servantSkeltonCreator.rb @@ -0,0 +1,65 @@ +# WSDL4R - Creating servant skelton code from WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/classDefCreatorSupport' +require 'xsd/codegen' + + +module WSDL +module SOAP + + +class ServantSkeltonCreator + include ClassDefCreatorSupport + include ::XSD::CodeGen::GenSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + end + + def dump(porttype = nil) + if porttype.nil? + result = "" + @definitions.porttypes.each do |type| + result << dump_porttype(type.name) + result << "\n" + end + else + result = dump_porttype(porttype) + end + result + end + +private + + def dump_porttype(name) + class_name = create_class_name(name) + c = ::XSD::CodeGen::ClassDef.new(class_name) + operations = @definitions.porttype(name).operations + operations.each do |operation| + name = operation.name.name + input = operation.input + m = ::XSD::CodeGen::MethodDef.new(name, + input.find_message.parts.collect { |part| safevarname(part.name) }) do + <<-EOD + raise NotImplementedError.new + EOD + end + m.comment = dump_method_signature(operation) + c.add_method(m) + end + c.dump + end +end + + +end +end diff --git a/lib/wsdl/soap/standaloneServerStubCreator.rb b/lib/wsdl/soap/standaloneServerStubCreator.rb new file mode 100644 index 000000000..34bcfdbba --- /dev/null +++ b/lib/wsdl/soap/standaloneServerStubCreator.rb @@ -0,0 +1,79 @@ +# WSDL4R - Creating standalone server stub code from WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/mappingRegistryCreator' +require 'wsdl/soap/methodDefCreator' +require 'wsdl/soap/classDefCreatorSupport' + + +module WSDL +module SOAP + + +class StandaloneServerStubCreator + include ClassDefCreatorSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + end + + def dump(service_name) + STDERR.puts "!!! IMPORTANT !!!" + STDERR.puts "- Standalone stub can have only 1 port for now. So creating stub for the first port and rests are ignored." + STDERR.puts "- Standalone server stub ignores port location defined in WSDL. Location is http://localhost:10080/ by default. Generated client from WSDL must be configured to point this endpoint by hand." + STDERR.puts "!!! IMPORTANT !!!" + port = @definitions.service(service_name).ports[0] + dump_porttype(port.porttype.name) + end + +private + + def dump_porttype(name) + class_name = create_class_name(name) + methoddef, types = MethodDefCreator.new(@definitions).dump(name) + mr_creator = MappingRegistryCreator.new(@definitions) + + c1 = ::XSD::CodeGen::ClassDef.new(class_name) + c1.def_require("soap/rpc/standaloneServer") + c1.def_require("soap/mapping/registry") + c1.def_const("MappingRegistry", "::SOAP::Mapping::Registry.new") + c1.def_code(mr_creator.dump(types)) + c1.def_code <<-EOD +Methods = [ +#{ methoddef.gsub(/^/, " ") } +] + EOD + c2 = ::XSD::CodeGen::ClassDef.new(class_name + "App", + "::SOAP::RPC::StandaloneServer") + c2.def_method("initialize", "*arg") do + <<-EOD + super(*arg) + servant = #{class_name}.new + #{class_name}::Methods.each do |name_as, name, params, soapaction, ns| + qname = XSD::QName.new(ns, name_as) + @soaplet.app_scope_router.add_method(servant, qname, soapaction, name, params) + end + self.mapping_registry = #{class_name}::MappingRegistry + EOD + end + c1.dump + "\n" + c2.dump + format(<<-EOD) + + if $0 == __FILE__ + # Change listen port. + #{class_name}App.new('app', nil, '0.0.0.0', 10080).start + end + EOD + end +end + + +end +end diff --git a/lib/wsdl/xmlSchema/enumeration.rb b/lib/wsdl/xmlSchema/enumeration.rb new file mode 100644 index 000000000..cd61572d0 --- /dev/null +++ b/lib/wsdl/xmlSchema/enumeration.rb @@ -0,0 +1,36 @@ +# WSDL4R - XMLSchema enumeration definition for WSDL. +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class Enumeration < Info + def initialize + super + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when ValueAttrName + parent.enumeration << value + value + end + end +end + + +end +end diff --git a/lib/wsdl/xmlSchema/simpleRestriction.rb b/lib/wsdl/xmlSchema/simpleRestriction.rb new file mode 100644 index 000000000..6986e7442 --- /dev/null +++ b/lib/wsdl/xmlSchema/simpleRestriction.rb @@ -0,0 +1,48 @@ +# WSDL4R - XMLSchema simpleType definition for WSDL. +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' + + +module WSDL +module XMLSchema + + +class SimpleRestriction < Info + attr_reader :base + attr_reader :enumeration + + def initialize + super + @base = nil + @enumeration = [] # NamedElements? + end + + def valid?(value) + @enumeration.include?(value) + end + + def parse_element(element) + case element + when EnumerationName + Enumeration.new # just a parsing handler + end + end + + def parse_attr(attr, value) + case attr + when BaseAttrName + @base = value + end + end +end + + +end +end diff --git a/lib/wsdl/xmlSchema/simpleType.rb b/lib/wsdl/xmlSchema/simpleType.rb new file mode 100644 index 000000000..830086f99 --- /dev/null +++ b/lib/wsdl/xmlSchema/simpleType.rb @@ -0,0 +1,81 @@ +# WSDL4R - XMLSchema simpleType definition for WSDL. +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' + + +module WSDL +module XMLSchema + + +class SimpleType < Info + attr_accessor :name + attr_reader :derivetype + attr_reader :restriction + + def check_lexical_format(value) + if @restriction + check_restriction(value) + elsif @extension + raise NotImplementedError + # ToDo + else + raise ArgumentError.new("incomplete simpleType") + end + end + + def base + if @restriction + @restriction.base + elsif @extension + @extension.base + else + raise ArgumentError.new("incomplete simpleType") + end + end + + def initialize(name = nil) + super() + @name = name + @derivetype = nil + @restriction = nil + end + + def targetnamespace + parent.targetnamespace + end + + def parse_element(element) + case element + when RestrictionName + @restriction = SimpleRestriction.new + @derivetype = element.name + @restriction + end + end + + def parse_attr(attr, value) + case attr + when NameAttrName + @name = XSD::QName.new(targetnamespace, value) + end + end + +private + + def check_restriction(value) + unless @restriction.valid?(value) + raise ::XSD::ValueSpaceError.new("#{@name}: cannot accept '#{value}'.") + end + end +end + + +end +end diff --git a/lib/xsd/codegen.rb b/lib/xsd/codegen.rb new file mode 100644 index 000000000..d820ebf1f --- /dev/null +++ b/lib/xsd/codegen.rb @@ -0,0 +1,12 @@ +# XSD4R - Generating code library +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'xsd/codegen/moduledef' +require 'xsd/codegen/classdef' +require 'xsd/codegen/methoddef' diff --git a/lib/xsd/codegen/classdef.rb b/lib/xsd/codegen/classdef.rb new file mode 100644 index 000000000..8f72e95ef --- /dev/null +++ b/lib/xsd/codegen/classdef.rb @@ -0,0 +1,203 @@ +# XSD4R - Generating class definition code +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'xsd/codegen/moduledef' +require 'xsd/codegen/methoddef' + + +module XSD +module CodeGen + + +class ClassDef < ModuleDef + include GenSupport + + def initialize(name, baseclass = nil) + super(name) + @baseclass = baseclass + @classvar = [] + @attrdef = [] + end + + def def_classvar(var, value) + var = var.sub(/\A@@/, "") + unless safevarname?(var) + raise ArgumentError.new("#{var} seems to be unsafe") + end + @classvar << [var, value] + end + + def def_attr(attrname, writable = true, varname = nil) + unless safevarname?(varname || attrname) + raise ArgumentError.new("#{varname || attrname} seems to be unsafe") + end + @attrdef << [attrname, writable, varname] + end + + def dump + buf = "" + unless @requirepath.empty? + buf << dump_requirepath + end + buf << dump_emptyline unless buf.empty? + package = @name.split(/::/)[0..-2] + buf << dump_package_def(package) unless package.empty? + buf << dump_comment if @comment + buf << dump_class_def + spacer = false + unless @classvar.empty? + spacer = true + buf << dump_classvar + end + unless @const.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_const + end + unless @code.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_code + end + unless @attrdef.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_attributes + end + unless @methoddef.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_methods + end + buf << dump_class_def_end + buf << dump_package_def_end(package) unless package.empty? + buf + end + +private + + def dump_class_def + name = @name.to_s.split(/::/) + if @baseclass + format("class #{name.last} < #{@baseclass}") + else + format("class #{name.last}") + end + end + + def dump_class_def_end + str = format("end") + end + + def dump_classvar + dump_static( + @classvar.collect { |var, value| + %Q(@@#{var.sub(/^@@/, "")} = #{dump_value(value)}) + }.join("\n") + ) + end + + def dump_attributes + str = "" + @attrdef.each do |attrname, writable, varname| + varname ||= attrname + if attrname == varname + str << format(dump_accessor(attrname, writable), 2) + end + end + @attrdef.each do |attrname, writable, varname| + varname ||= attrname + if attrname != varname + str << "\n" unless str.empty? + str << format(dump_attribute(attrname, writable, varname), 2) + end + end + str + end + + def dump_accessor(attrname, writable) + if writable + "attr_accessor :#{attrname}" + else + "attr_reader :#{attrname}" + end + end + + def dump_attribute(attrname, writable, varname) + str = nil + mr = MethodDef.new(attrname) + mr.definition = "@#{varname}" + str = mr.dump + if writable + mw = MethodDef.new(attrname + "=", 'value') + mw.definition = "@#{varname} = value" + str << "\n" + mw.dump + end + str + end +end + + +end +end + + +if __FILE__ == $0 + require 'xsd/codegen/classdef' + include XSD::CodeGen + c = ClassDef.new("Foo::Bar::HobbitName", String) + c.def_require("foo/bar") + c.comment = <<-EOD + foo + bar + baz + EOD + c.def_const("FOO", 1) + c.def_classvar("@@foo", "var".dump) + c.def_classvar("baz", "1".dump) + c.def_attr("Foo", true, "foo") + c.def_attr("bar") + c.def_attr("baz", true) + c.def_attr("Foo2", true, "foo2") + c.def_attr("foo3", false, "foo3") + c.def_method("foo") do + <<-EOD + foo.bar = 1 +\tbaz.each do |ele| +\t ele + end + EOD + end + c.def_method("baz", "qux") do + <<-EOD + [1, 2, 3].each do |i| + p i + end + EOD + end + + m = MethodDef.new("qux", "quxx", "quxxx") do + <<-EOD + p quxx + quxxx + EOD + end + m.comment = "hello world\n123" + c.add_method(m) + c.def_code <<-EOD + Foo.new + Bar.z + EOD + c.def_code <<-EOD + Foo.new + Bar.z + EOD + c.def_privatemethod("foo", "baz", "*arg", "&block") + + puts c.dump +end diff --git a/lib/xsd/codegen/commentdef.rb b/lib/xsd/codegen/commentdef.rb new file mode 100644 index 000000000..f98fade57 --- /dev/null +++ b/lib/xsd/codegen/commentdef.rb @@ -0,0 +1,34 @@ +# XSD4R - Generating comment definition code +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' + + +module XSD +module CodeGen + + +module CommentDef + include GenSupport + + attr_accessor :comment + +private + + def dump_comment + if /^#/ =~ @comment + format(@comment) + else + format(@comment).gsub(/^/, "# ") + end + end +end + + +end +end diff --git a/lib/xsd/codegen/gensupport.rb b/lib/xsd/codegen/gensupport.rb new file mode 100644 index 000000000..df90550fa --- /dev/null +++ b/lib/xsd/codegen/gensupport.rb @@ -0,0 +1,112 @@ +# XSD4R - Code generation support +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +module XSD +module CodeGen + + +module GenSupport + def capitalize(target) + target.sub(/^([a-z])/) { $1.tr!('[a-z]', '[A-Z]') } + end + module_function :capitalize + + def uncapitalize(target) + target.sub(/^([A-Z])/) { $1.tr!('[A-Z]', '[a-z]') } + end + module_function :uncapitalize + + def safeconstname(name) + safename = name.scan(/[a-zA-Z0-9_]+/).collect { |ele| + GenSupport.capitalize(ele) + }.join + unless /^[A-Z]/ =~ safename + safename = "C_#{safename}" + end + safename + end + module_function :safeconstname + + def safeconstname?(name) + /\A[A-Z][a-zA-Z0-9_]*\z/ =~ name + end + module_function :safeconstname? + + def safemethodname(name) + safevarname(name) + end + module_function :safemethodname + + def safemethodname?(name) + /\A[a-zA-Z_][a-zA-Z0-9_]*[=!?]?\z/ =~ name + end + module_function :safemethodname? + + def safevarname(name) + safename = name.scan(/[a-zA-Z0-9_]+/).join('_') + safename = uncapitalize(safename) + unless /^[a-z]/ =~ safename + safename = "m_#{safename}" + end + safename + end + module_function :safevarname + + def safevarname?(name) + /\A[a-z_][a-zA-Z0-9_]*\z/ =~ name + end + module_function :safevarname? + + def format(str, indent = nil) + str = trim_eol(str) + str = trim_indent(str) + if indent + str.gsub(/^/, " " * indent) + else + str + end + end + +private + + def trim_eol(str) + str.collect { |line| + line.sub(/\r?\n$/, "") + "\n" + }.join + end + + def trim_indent(str) + indent = nil + str = str.collect { |line| untab(line) }.join + str.each do |line| + head = line.index(/\S/) + if !head.nil? and (indent.nil? or head < indent) + indent = head + end + end + return str unless indent + str.collect { |line| + line.sub(/^ {0,#{indent}}/, "") + }.join + end + + def untab(line, ts = 8) + while pos = line.index(/\t/) + line = line.sub(/\t/, " " * (ts - (pos % ts))) + end + line + end + + def dump_emptyline + "\n" + end +end + + +end +end diff --git a/lib/xsd/codegen/methoddef.rb b/lib/xsd/codegen/methoddef.rb new file mode 100644 index 000000000..797a4f024 --- /dev/null +++ b/lib/xsd/codegen/methoddef.rb @@ -0,0 +1,63 @@ +# XSD4R - Generating method definition code +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'xsd/codegen/commentdef' + + +module XSD +module CodeGen + + +class MethodDef + include GenSupport + include CommentDef + + attr_accessor :definition + + def initialize(name, *params) + unless safemethodname?(name) + raise ArgumentError.new("#{name} seems to be unsafe") + end + @name = name + @params = params + @comment = nil + @definition = yield if block_given? + end + + def dump + buf = "" + buf << dump_comment if @comment + buf << dump_method_def + buf << dump_definition if @definition + buf << dump_method_def_end + buf + end + +private + + def dump_method_def + if @params.empty? + format("def #{@name}") + else + format("def #{@name}(#{@params.join(", ")})") + end + end + + def dump_method_def_end + format("end") + end + + def dump_definition + format(@definition, 2) + end +end + + +end +end diff --git a/lib/xsd/codegen/moduledef.rb b/lib/xsd/codegen/moduledef.rb new file mode 100644 index 000000000..dc2746b2e --- /dev/null +++ b/lib/xsd/codegen/moduledef.rb @@ -0,0 +1,191 @@ +# XSD4R - Generating module definition code +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'xsd/codegen/methoddef' +require 'xsd/codegen/commentdef' + + +module XSD +module CodeGen + + +class ModuleDef + include GenSupport + include CommentDef + + def initialize(name) + @name = name + @comment = nil + @const = [] + @code = [] + @requirepath = [] + @methoddef = [] + end + + def def_require(path) + @requirepath << path + end + + def def_const(const, value) + unless safeconstname?(const) + raise ArgumentError.new("#{const} seems to be unsafe") + end + @const << [const, value] + end + + def def_code(code) + @code << code + end + + def def_method(name, *params) + add_method(MethodDef.new(name, *params) { yield if block_given? }, :public) + end + alias def_publicmethod def_method + + def def_protectedmethod(name, *params) + add_method(MethodDef.new(name, *params) { yield if block_given? }, + :protected) + end + + def def_privatemethod(name, *params) + add_method(MethodDef.new(name, *params) { yield if block_given? }, :private) + end + + def add_method(m, visibility = :public) + @methoddef << [visibility, m] + end + + def dump + buf = "" + unless @requirepath.empty? + buf << dump_requirepath + end + buf << dump_emptyline unless buf.empty? + package = @name.split(/::/)[0..-2] + buf << dump_package_def(package) unless package.empty? + buf << dump_comment if @comment + buf << dump_module_def + spacer = false + unless @const.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_const + end + unless @code.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_code + end + unless @methoddef.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_methods + end + buf << dump_module_def_end + buf << dump_package_def_end(package) unless package.empty? + buf + end + +private + + def dump_requirepath + format( + @requirepath.collect { |path| + %Q(require '#{path}') + }.join("\n") + ) + end + + def dump_const + dump_static( + @const.sort.collect { |var, value| + %Q(#{var} = #{dump_value(value)}) + }.join("\n") + ) + end + + def dump_code + dump_static(@code.join("\n")) + end + + def dump_static(str) + format(str, 2) + end + + def dump_methods + methods = {} + @methoddef.each do |visibility, method| + (methods[visibility] ||= []) << method + end + str = "" + [:public, :protected, :private].each do |visibility| + if methods[visibility] + str << "\n" unless str.empty? + str << visibility.to_s << "\n\n" unless visibility == :public + str << methods[visibility].collect { |m| format(m.dump, 2) }.join("\n") + end + end + str + end + + def dump_value(value) + if value.respond_to?(:to_src) + value.to_src + else + value + end + end + + def dump_package_def(package) + format(package.collect { |ele| "module #{ele}" }.join("; ")) + "\n\n" + end + + def dump_package_def_end(package) + "\n\n" + format(package.collect { |ele| "end" }.join("; ")) + end + + def dump_module_def + name = @name.to_s.split(/::/) + format("module #{name.last}") + end + + def dump_module_def_end + format("end") + end +end + + +end +end + + +if __FILE__ == $0 + require 'xsd/codegen/moduledef' + include XSD::CodeGen + m = ModuleDef.new("Foo::Bar::HobbitName") + m.def_require("foo/bar") + m.def_require("baz") + m.comment = <<-EOD + foo + bar + baz + EOD + m.def_method("foo") do + <<-EOD + foo.bar = 1 + baz.each do |ele| + ele + 1 + end + EOD + end + m.def_method("baz", "qux") + #m.def_protectedmethod("aaa") + m.def_privatemethod("bbb") + puts m.dump +end diff --git a/sample/soap/authheader/authmgr.rb b/sample/soap/authheader/authmgr.rb new file mode 100644 index 000000000..a4d3b66c0 --- /dev/null +++ b/sample/soap/authheader/authmgr.rb @@ -0,0 +1,41 @@ +class Authmgr + def initialize + @users = { + 'NaHi' => 'passwd', + 'HiNa' => 'wspass' + } + @sessions = {} + end + + def login(userid, passwd) + userid and passwd and @users[userid] == passwd + end + + # returns userid + def auth(sessionid) + @sessions[sessionid] + end + + def create_session(userid) + while true + key = create_sessionkey + break unless @sessions[key] + end + @sessions[key] = userid + key + end + + def get_session(userid) + @sessions.index(userid) + end + + def destroy_session(sessionkey) + @sessions.delete(sessionkey) + end + +private + + def create_sessionkey + Time.now.usec.to_s + end +end diff --git a/sample/soap/authheader/client.rb b/sample/soap/authheader/client.rb new file mode 100644 index 000000000..4055fe63f --- /dev/null +++ b/sample/soap/authheader/client.rb @@ -0,0 +1,40 @@ +require 'soap/rpc/driver' +require 'soap/header/simplehandler' + +server = ARGV.shift || 'http://localhost:7000/' + +class ClientAuthHeaderHandler < SOAP::Header::SimpleHandler + MyHeaderName = XSD::QName.new("http://tempuri.org/authHeader", "auth") + + def initialize(userid, passwd) + super(MyHeaderName) + @sessionid = nil + @userid = userid + @passwd = passwd + @mustunderstand = true + end + + def on_simple_outbound + if @sessionid + { "sessionid" => @sessionid } + else + { "userid" => @userid, "passwd" => @passwd } + end + end + + def on_simple_inbound(my_header, mustunderstand) + @sessionid = my_header["sessionid"] + end +end + +ns = 'http://tempuri.org/authHeaderPort' +serv = SOAP::RPC::Driver.new(server, ns) +serv.add_method('deposit', 'amt') +serv.add_method('withdrawal', 'amt') + +serv.headerhandler << ClientAuthHeaderHandler.new('NaHi', 'passwd') + +serv.wiredump_dev = STDOUT + +p serv.deposit(150) +p serv.withdrawal(120) diff --git a/sample/soap/authheader/client2.rb b/sample/soap/authheader/client2.rb new file mode 100644 index 000000000..58a7da45a --- /dev/null +++ b/sample/soap/authheader/client2.rb @@ -0,0 +1,39 @@ +require 'soap/rpc/driver' +require 'soap/header/simplehandler' + +server = ARGV.shift || 'http://localhost:7000/' + +class ClientAuthHeaderHandler < SOAP::Header::SimpleHandler + MyHeaderName = XSD::QName.new("http://tempuri.org/authHeader", "auth") + + def initialize(userid, passwd) + super(MyHeaderName) + @sessionid = nil + @userid = userid + @passwd = passwd + end + + def on_simple_outbound + if @sessionid + { "sessionid" => @sessionid } + else + { "userid" => @userid, "passwd" => @passwd } + end + end + + def on_simple_inbound(my_header, mustunderstand) + @sessionid = my_header["sessionid"] + end +end + +ns = 'http://tempuri.org/authHeaderPort' +serv = SOAP::RPC::Driver.new(server, ns) +serv.add_method('deposit', 'amt') +serv.add_method('withdrawal', 'amt') + +serv.headerhandler << ClientAuthHeaderHandler.new('NaHi', 'passwd') + +serv.wiredump_dev = STDOUT + +p serv.deposit(150) +p serv.withdrawal(120) diff --git a/sample/soap/authheader/server.rb b/sample/soap/authheader/server.rb new file mode 100644 index 000000000..6b562d02f --- /dev/null +++ b/sample/soap/authheader/server.rb @@ -0,0 +1,72 @@ +#!/usr/bin/env ruby + +require 'soap/rpc/standaloneServer' +require 'soap/header/simplehandler' +require 'authmgr' + +class AuthHeaderPortServer < SOAP::RPC::StandaloneServer + class AuthHeaderService + def self.create + new + end + + def deposit(amt) + "deposit #{amt} OK" + end + + def withdrawal(amt) + "withdrawal #{amt} OK" + end + end + + Name = 'http://tempuri.org/authHeaderPort' + def initialize(*arg) + super + add_rpc_servant(AuthHeaderService.new, Name) + add_rpc_request_headerhandler(ServerAuthHeaderHandler) + end + + class ServerAuthHeaderHandler < SOAP::Header::SimpleHandler + MyHeaderName = XSD::QName.new("http://tempuri.org/authHeader", "auth") + + @authmgr = Authmgr.new + def self.create + new(@authmgr) + end + + def initialize(authmgr) + super(MyHeaderName) + @authmgr = authmgr + @userid = @sessionid = nil + end + + def on_simple_outbound + { "sessionid" => @sessionid } + end + + def on_simple_inbound(my_header, mu) + auth = false + userid = my_header["userid"] + passwd = my_header["passwd"] + if @authmgr.login(userid, passwd) + auth = true + elsif sessionid = my_header["sessionid"] + if userid = @authmgr.auth(sessionid) + @authmgr.destroy_session(sessionid) + auth = true + end + end + raise RuntimeError.new("authentication failed") unless auth + @userid = userid + @sessionid = @authmgr.create_session(userid) + end + end +end + +if $0 == __FILE__ + svr = AuthHeaderPortServer.new('AuthHeaderPortServer', nil, '0.0.0.0', 7000) + trap(:INT) do + svr.shutdown + end + status = svr.start +end diff --git a/sample/soap/authheader/server2.rb b/sample/soap/authheader/server2.rb new file mode 100644 index 000000000..b0065e314 --- /dev/null +++ b/sample/soap/authheader/server2.rb @@ -0,0 +1,77 @@ +#!/usr/bin/env ruby + +require 'soap/rpc/standaloneServer' +require 'soap/header/simplehandler' +require 'authmgr' + +class AuthHeaderPortServer < SOAP::RPC::StandaloneServer + class AuthHeaderService + def self.create + new + end + + def initialize(authmgr) + @authmgr = authmgr + end + + def login(userid, passwd) + if @authmgr.login(userid, passwd) + @authmgr.create_session(userid) + else + raise RuntimeError.new("authentication failed") + end + end + + def deposit(amt) + "deposit #{amt} OK" + end + + def withdrawal(amt) + "withdrawal #{amt} OK" + end + end + + Name = 'http://tempuri.org/authHeaderPort' + def initialize(*arg) + super + add_rpc_servant(AuthHeaderService.new, Name) + ServerAuthHeaderHandler.init + add_rpc_request_headerhandler(ServerAuthHeaderHandler) + end + + class ServerAuthHeaderHandler < SOAP::Header::SimpleHandler + MyHeaderName = XSD::QName.new("http://tempuri.org/authHeader", "auth") + + def self.create + new(@authmgr) + end + + def initialize(authmgr) + super(MyHeaderName) + @authmgr = authmgr + @sessionid = nil + end + + def on_simple_outbound + if @sessionid + { "sessionid" => @sessionid } + end + end + + def on_simple_inbound(my_header, mu) + auth = false + if sessionid = my_header["sessionid"] + if userid = @authmgr.auth(sessionid) + @authmgr.destroy_session(sessionid) + @session_id = @authmgr.create_session(userid) + auth = true + end + end + raise RuntimeError.new("authentication failed") unless auth + end + end +end + +if $0 == __FILE__ + status = AuthHeaderPortServer.new('AuthHeaderPortServer', nil, '0.0.0.0', 7000).start +end diff --git a/sample/soap/raa2.4/raa.rb b/sample/soap/raa2.4/raa.rb new file mode 100644 index 000000000..9b4c4e41a --- /dev/null +++ b/sample/soap/raa2.4/raa.rb @@ -0,0 +1,332 @@ +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class Gem + @@schema_type = "Gem" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" + + def id + @id + end + + def id=(value) + @id = value + end + + def category + @category + end + + def category=(value) + @category = value + end + + def owner + @owner + end + + def owner=(value) + @owner = value + end + + def project + @project + end + + def project=(value) + @project = value + end + + def updated + @updated + end + + def updated=(value) + @updated = value + end + + def created + @created + end + + def created=(value) + @created = value + end + + def initialize(id = nil, + category = nil, + owner = nil, + project = nil, + updated = nil, + created = nil) + @id = id + @category = category + @owner = owner + @project = project + @updated = updated + @created = created + end +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class Category + @@schema_type = "Category" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" + + def major + @major + end + + def major=(value) + @major = value + end + + def minor + @minor + end + + def minor=(value) + @minor = value + end + + def initialize(major = nil, + minor = nil) + @major = major + @minor = minor + end +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class Owner + @@schema_type = "Owner" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" + + def id + @id + end + + def id=(value) + @id = value + end + + def email + @email + end + + def email=(value) + @email = value + end + + def name + @name + end + + def name=(value) + @name = value + end + + def initialize(id = nil, + email = nil, + name = nil) + @id = id + @email = email + @name = name + end +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class Project + @@schema_type = "Project" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" + + def name + @name + end + + def name=(value) + @name = value + end + + def short_description + @short_description + end + + def short_description=(value) + @short_description = value + end + + def version + @version + end + + def version=(value) + @version = value + end + + def status + @status + end + + def status=(value) + @status = value + end + + def url + @url + end + + def url=(value) + @url = value + end + + def download + @download + end + + def download=(value) + @download = value + end + + def license + @license + end + + def license=(value) + @license = value + end + + def description + @description + end + + def description=(value) + @description = value + end + + def updated + @updated + end + + def updated=(value) + @updated = value + end + + def history + @history + end + + def history=(value) + @history = value + end + + def dependency + @dependency + end + + def dependency=(value) + @dependency = value + end + + def initialize(name = nil, + short_description = nil, + version = nil, + status = nil, + url = nil, + download = nil, + license = nil, + description = nil, + updated = nil, + history = nil, + dependency = nil) + @name = name + @short_description = short_description + @version = version + @status = status + @url = url + @download = download + @license = license + @description = description + @updated = updated + @history = history + @dependency = dependency + end +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class ProjectDependency + @@schema_type = "ProjectDependency" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" + + def project + @project + end + + def project=(value) + @project = value + end + + def version + @version + end + + def version=(value) + @version = value + end + + def description + @description + end + + def description=(value) + @description = value + end + + def initialize(project = nil, + version = nil, + description = nil) + @project = project + @version = version + @description = description + end +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class GemArray < Array + # Contents type should be dumped here... + @@schema_type = "GemArray" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class OwnerArray < Array + # Contents type should be dumped here... + @@schema_type = "OwnerArray" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class ProjectArray < Array + # Contents type should be dumped here... + @@schema_type = "ProjectArray" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class ProjectDependencyArray < Array + # Contents type should be dumped here... + @@schema_type = "ProjectDependencyArray" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class StringArray < Array + # Contents type should be dumped here... + @@schema_type = "StringArray" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" +end + +# http://xml.apache.org/xml-soap +class Map < Array + # Contents type should be dumped here... + @@schema_type = "Map" + @@schema_ns = "http://xml.apache.org/xml-soap" +end + diff --git a/sample/soap/raa2.4/raaDriver.rb b/sample/soap/raa2.4/raaDriver.rb new file mode 100644 index 000000000..10d0ba257 --- /dev/null +++ b/sample/soap/raa2.4/raaDriver.rb @@ -0,0 +1,255 @@ +require 'raa.rb' + +require 'soap/rpc/driver' + +class RaaServicePortType < SOAP::RPC::Driver + TargetNamespace = "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + MappingRegistry = ::SOAP::Mapping::Registry.new + + MappingRegistry.set( + Gem, + ::SOAP::SOAPStruct, + ::SOAP::Mapping::Registry::TypedStructFactory, + { :type => XSD::QName.new("http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "Gem") } + ) + MappingRegistry.set( + Category, + ::SOAP::SOAPStruct, + ::SOAP::Mapping::Registry::TypedStructFactory, + { :type => XSD::QName.new("http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "Category") } + ) + MappingRegistry.set( + Owner, + ::SOAP::SOAPStruct, + ::SOAP::Mapping::Registry::TypedStructFactory, + { :type => XSD::QName.new("http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "Owner") } + ) + MappingRegistry.set( + Project, + ::SOAP::SOAPStruct, + ::SOAP::Mapping::Registry::TypedStructFactory, + { :type => XSD::QName.new("http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "Project") } + ) + MappingRegistry.set( + ProjectArray, + ::SOAP::SOAPArray, + ::SOAP::Mapping::Registry::TypedArrayFactory, + { :type => XSD::QName.new("http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "Project") } + ) + MappingRegistry.set( + ProjectDependencyArray, + ::SOAP::SOAPArray, + ::SOAP::Mapping::Registry::TypedArrayFactory, + { :type => XSD::QName.new("http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "ProjectDependency") } + ) + MappingRegistry.set( + StringArray, + ::SOAP::SOAPArray, + ::SOAP::Mapping::Registry::TypedArrayFactory, + { :type => XSD::QName.new("http://www.w3.org/2001/XMLSchema", "string") } + ) + MappingRegistry.set( + Map, + ::SOAP::SOAPArray, + ::SOAP::Mapping::Registry::TypedArrayFactory, + { :type => XSD::QName.new("http://www.w3.org/2001/XMLSchema", "anyType") } + ) + MappingRegistry.set( + OwnerArray, + ::SOAP::SOAPArray, + ::SOAP::Mapping::Registry::TypedArrayFactory, + { :type => XSD::QName.new("http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "Owner") } + ) + MappingRegistry.set( + ProjectDependency, + ::SOAP::SOAPStruct, + ::SOAP::Mapping::Registry::TypedStructFactory, + { :type => XSD::QName.new("http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "ProjectDependency") } + ) + Methods = [ + ["gem", "gem", + [ + ["in", "name", [SOAP::SOAPString]], + ["retval", "return", [::SOAP::SOAPStruct, "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "Gem"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["dependents", "dependents", + [ + ["in", "name", [SOAP::SOAPString]], + ["in", "version", [SOAP::SOAPString]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "ProjectDependency"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["names", "names", + [ + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["size", "size", + [ + ["retval", "return", [SOAP::SOAPInt]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["list_by_category", "list_by_category", + [ + ["in", "major", [SOAP::SOAPString]], + ["in", "minor", [SOAP::SOAPString]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["tree_by_category", "tree_by_category", + [ + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "anyType"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["list_recent_updated", "list_recent_updated", + [ + ["in", "idx", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["list_recent_created", "list_recent_created", + [ + ["in", "idx", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["list_updated_since", "list_updated_since", + [ + ["in", "date", [SOAP::SOAPDateTime]], + ["in", "idx", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["list_created_since", "list_created_since", + [ + ["in", "date", [SOAP::SOAPDateTime]], + ["in", "idx", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["list_by_owner", "list_by_owner", + [ + ["in", "owner_id", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["search_name", "search_name", + [ + ["in", "substring", [SOAP::SOAPString]], + ["in", "idx", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["search_short_description", "search_short_description", + [ + ["in", "substring", [SOAP::SOAPString]], + ["in", "idx", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["search_owner", "search_owner", + [ + ["in", "substring", [SOAP::SOAPString]], + ["in", "idx", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["search_version", "search_version", + [ + ["in", "substring", [SOAP::SOAPString]], + ["in", "idx", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["search_status", "search_status", + [ + ["in", "substring", [SOAP::SOAPString]], + ["in", "idx", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["search_description", "search_description", + [ + ["in", "substring", [SOAP::SOAPString]], + ["in", "idx", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "string"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["search", "search", + [ + ["in", "substring", [SOAP::SOAPString]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.w3.org/2001/XMLSchema", "anyType"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["owner", "owner", + [ + ["in", "owner_id", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPStruct, "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "Owner"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["list_owner", "list_owner", + [ + ["in", "idx", [SOAP::SOAPInt]], + ["retval", "return", [::SOAP::SOAPArray, "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "Owner"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["update", "update", + [ + ["in", "name", [SOAP::SOAPString]], + ["in", "pass", [SOAP::SOAPString]], + ["in", "gem", [::SOAP::SOAPStruct, "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "Gem"]], + ["retval", "return", [::SOAP::SOAPStruct, "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/", "Gem"]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ], + ["update_pass", "update_pass", + [ + ["in", "name", [SOAP::SOAPString]], + ["in", "oldpass", [SOAP::SOAPString]], + ["in", "newpass", [SOAP::SOAPString]] + ], + "", "http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/" + ] + ] + + DefaultEndpointUrl = "http://raa.ruby-lang.org/soapsrv" + + def initialize(endpoint_url = nil) + endpoint_url ||= DefaultEndpointUrl + super(endpoint_url, nil) + self.mapping_registry = MappingRegistry + init_methods + end + +private + + def init_methods + Methods.each do |name_as, name, params, soapaction, namespace| + qname = XSD::QName.new(namespace, name_as) + @proxy.add_method(qname, soapaction, name, params) + add_rpc_method_interface(name, params) + end + end +end + diff --git a/sample/soap/raa2.4/raaServiceClient.rb b/sample/soap/raa2.4/raaServiceClient.rb new file mode 100644 index 000000000..a59815ba7 --- /dev/null +++ b/sample/soap/raa2.4/raaServiceClient.rb @@ -0,0 +1,354 @@ +#!/usr/bin/env ruby +require 'raaDriver.rb' + +endpoint_url = ARGV.shift +obj = RaaServicePortType.new(endpoint_url) + +# Uncomment the below line to see SOAP wiredumps. +# obj.wiredump_dev = STDERR + +# SYNOPSIS +# gem(name) +# +# ARGS +# name - {http://www.w3.org/2001/XMLSchema}string +# +# RETURNS +# return Gem - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}Gem +# +# RAISES +# (undefined) +# +name = nil +puts obj.gem(name) + +# SYNOPSIS +# dependents(name, version) +# +# ARGS +# name - {http://www.w3.org/2001/XMLSchema}string +# version - {http://www.w3.org/2001/XMLSchema}string +# +# RETURNS +# return ProjectDependencyArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}ProjectDependencyArray +# +# RAISES +# (undefined) +# +name = version = nil +puts obj.dependents(name, version) + +# SYNOPSIS +# names +# +# ARGS +# N/A +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# + +puts obj.names + +# SYNOPSIS +# size +# +# ARGS +# N/A +# +# RETURNS +# return - {http://www.w3.org/2001/XMLSchema}int +# +# RAISES +# (undefined) +# + +puts obj.size + +# SYNOPSIS +# list_by_category(major, minor) +# +# ARGS +# major - {http://www.w3.org/2001/XMLSchema}string +# minor - {http://www.w3.org/2001/XMLSchema}string +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# +major = minor = nil +puts obj.list_by_category(major, minor) + +# SYNOPSIS +# tree_by_category +# +# ARGS +# N/A +# +# RETURNS +# return Map - {http://xml.apache.org/xml-soap}Map +# +# RAISES +# (undefined) +# + +puts obj.tree_by_category + +# SYNOPSIS +# list_recent_updated(idx) +# +# ARGS +# idx - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# +idx = nil +puts obj.list_recent_updated(idx) + +# SYNOPSIS +# list_recent_created(idx) +# +# ARGS +# idx - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# +idx = nil +puts obj.list_recent_created(idx) + +# SYNOPSIS +# list_updated_since(date, idx) +# +# ARGS +# date - {http://www.w3.org/2001/XMLSchema}dateTime +# idx - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# +date = idx = nil +puts obj.list_updated_since(date, idx) + +# SYNOPSIS +# list_created_since(date, idx) +# +# ARGS +# date - {http://www.w3.org/2001/XMLSchema}dateTime +# idx - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# +date = idx = nil +puts obj.list_created_since(date, idx) + +# SYNOPSIS +# list_by_owner(owner_id) +# +# ARGS +# owner_id - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# +owner_id = nil +puts obj.list_by_owner(owner_id) + +# SYNOPSIS +# search_name(substring, idx) +# +# ARGS +# substring - {http://www.w3.org/2001/XMLSchema}string +# idx - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# +substring = idx = nil +puts obj.search_name(substring, idx) + +# SYNOPSIS +# search_short_description(substring, idx) +# +# ARGS +# substring - {http://www.w3.org/2001/XMLSchema}string +# idx - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# +substring = idx = nil +puts obj.search_short_description(substring, idx) + +# SYNOPSIS +# search_owner(substring, idx) +# +# ARGS +# substring - {http://www.w3.org/2001/XMLSchema}string +# idx - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# +substring = idx = nil +puts obj.search_owner(substring, idx) + +# SYNOPSIS +# search_version(substring, idx) +# +# ARGS +# substring - {http://www.w3.org/2001/XMLSchema}string +# idx - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# +substring = idx = nil +puts obj.search_version(substring, idx) + +# SYNOPSIS +# search_status(substring, idx) +# +# ARGS +# substring - {http://www.w3.org/2001/XMLSchema}string +# idx - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# +substring = idx = nil +puts obj.search_status(substring, idx) + +# SYNOPSIS +# search_description(substring, idx) +# +# ARGS +# substring - {http://www.w3.org/2001/XMLSchema}string +# idx - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return StringArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}StringArray +# +# RAISES +# (undefined) +# +substring = idx = nil +puts obj.search_description(substring, idx) + +# SYNOPSIS +# search(substring) +# +# ARGS +# substring - {http://www.w3.org/2001/XMLSchema}string +# +# RETURNS +# return Map - {http://xml.apache.org/xml-soap}Map +# +# RAISES +# (undefined) +# +substring = nil +puts obj.search(substring) + +# SYNOPSIS +# owner(owner_id) +# +# ARGS +# owner_id - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return Owner - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}Owner +# +# RAISES +# (undefined) +# +owner_id = nil +puts obj.owner(owner_id) + +# SYNOPSIS +# list_owner(idx) +# +# ARGS +# idx - {http://www.w3.org/2001/XMLSchema}int +# +# RETURNS +# return OwnerArray - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}OwnerArray +# +# RAISES +# (undefined) +# +idx = nil +puts obj.list_owner(idx) + +# SYNOPSIS +# update(name, pass, gem) +# +# ARGS +# name - {http://www.w3.org/2001/XMLSchema}string +# pass - {http://www.w3.org/2001/XMLSchema}string +# gem Gem - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}Gem +# +# RETURNS +# return Gem - {http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/}Gem +# +# RAISES +# (undefined) +# +name = pass = gem = nil +puts obj.update(name, pass, gem) + +# SYNOPSIS +# update_pass(name, oldpass, newpass) +# +# ARGS +# name - {http://www.w3.org/2001/XMLSchema}string +# oldpass - {http://www.w3.org/2001/XMLSchema}string +# newpass - {http://www.w3.org/2001/XMLSchema}string +# +# RETURNS +# N/A +# +# RAISES +# (undefined) +# +name = oldpass = newpass = nil +puts obj.update_pass(name, oldpass, newpass) + + diff --git a/sample/soap/raa2.4/sample.rb b/sample/soap/raa2.4/sample.rb new file mode 100644 index 000000000..e157f8361 --- /dev/null +++ b/sample/soap/raa2.4/sample.rb @@ -0,0 +1,115 @@ +#!/usr/bin/env ruby + +# This is a sample client based on raaServiceClient.rb. +# You can generate raaServiceClient.rb and related files with +# wsdl2ruby.rb --wsdl http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/ --type client + +require 'pp' +require 'raaDriver.rb' + +raa = RaaServicePortType.new +# raa.wiredump_dev = STDERR + +def sec(msg) + puts + puts "--------" + puts "-- " + msg + puts +end + +def subsec(msg) + puts "-- " + msg +end + +sec("retrieve a gem (RAA Information) which has specified name") +name = 'soap4r' +pp raa.gem(name) + +sec("retrieve dependents of the project") +name = 'http-access2'; version = nil +pp raa.dependents(name, version) + +sec("number of registered gems") +puts raa.size + +sec("retrieve all registered gem names") +p raa.names + +sec("retrieve gems of specified category") +major = 'Library'; minor = 'XML' +p raa.list_by_category(major, minor) + +sec("retrieve category tree") +pp raa.tree_by_category + +sec("retrieve gems which is updated recently") +idx = 0 +p raa.list_recent_updated(idx) +subsec("next 10 gems") +idx += 1 +p raa.list_recent_updated(idx) +subsec("next 10 gems") +idx += 1 +p raa.list_recent_updated(idx) + +sec("retrieve gems which is created recently") +p raa.list_recent_created(idx) + +sec("retrieve gems which is updated in 7 days") +date = Time.now - 7 * 24 * 60 * 60; idx = 0 +p raa.list_updated_since(date, idx) + +sec("retrieve gems which is created in 7 days") +p raa.list_created_since(date, idx) + +sec("retrieve gems of specified owner") +owner_id = 8 # NaHi +p raa.list_by_owner(owner_id) + +sec("search gems with keyword") +substring = 'soap' +pp raa.search(substring) + +# There are several search interface to search a field explicitly. +# puts raa.search_name(substring, idx) +# puts raa.search_short_description(substring, idx) +# puts raa.search_owner(substring, idx) +# puts raa.search_version(substring, idx) +# puts raa.search_status(substring, idx) +# puts raa.search_description(substring, idx) + +sec("retrieve owner info") +owner_id = 8 +pp raa.owner(owner_id) + +sec("retrieve owners") +idx = 0 +p raa.list_owner(idx) + +sec("update 'sampleproject'") +name = 'sampleproject' +pass = 'sampleproject' +gem = raa.gem(name) +p gem.project.version +gem.project.version.succ! +gem.updated = Time.now +raa.update(name, pass, gem) +p raa.gem(name).project.version + +sec("update pass phrase") +raa.update_pass(name, 'sampleproject', 'foo') +subsec("update check") +gem = raa.gem(name) +gem.project.description = 'Current pass phrase is "foo"' +gem.updated = Time.now +raa.update(name, 'foo', gem) +# +subsec("recover pass phrase") +raa.update_pass(name, 'foo', 'sampleproject') +subsec("update check") +gem = raa.gem(name) +gem.project.description = 'Current pass phrase is "sampleproject"' +gem.updated = Time.now +raa.update(name, 'sampleproject', gem) + +sec("done") diff --git a/sample/soap/ssl/files/README b/sample/soap/ssl/files/README new file mode 100644 index 000000000..98ebcf7c2 --- /dev/null +++ b/sample/soap/ssl/files/README @@ -0,0 +1 @@ +* certificates and keys in this directory is copied from http-access2 test. diff --git a/sample/soap/ssl/files/ca.cert b/sample/soap/ssl/files/ca.cert new file mode 100644 index 000000000..bcabbee4a --- /dev/null +++ b/sample/soap/ssl/files/ca.cert @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID0DCCArigAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES +MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X +DTA0MDEzMDAwNDIzMloXDTM2MDEyMjAwNDIzMlowPDELMAkGA1UEBgwCSlAxEjAQ +BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQswCQYDVQQDDAJDQTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANbv0x42BTKFEQOE+KJ2XmiSdZpR +wjzQLAkPLRnLB98tlzs4xo+y4RyY/rd5TT9UzBJTIhP8CJi5GbS1oXEerQXB3P0d +L5oSSMwGGyuIzgZe5+vZ1kgzQxMEKMMKlzA73rbMd4Jx3u5+jdbP0EDrPYfXSvLY +bS04n2aX7zrN3x5KdDrNBfwBio2/qeaaj4+9OxnwRvYP3WOvqdW0h329eMfHw0pi +JI0drIVdsEqClUV4pebT/F+CPUPkEh/weySgo9wANockkYu5ujw2GbLFcO5LXxxm +dEfcVr3r6t6zOA4bJwL0W/e6LBcrwiG/qPDFErhwtgTLYf6Er67SzLyA66UCAwEA +AaOB3DCB2TAPBgNVHRMBAf8EBTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09w +ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRJ7Xd380KzBV7f +USKIQ+O/vKbhDzAOBgNVHQ8BAf8EBAMCAQYwZAYDVR0jBF0wW4AUSe13d/NCswVe +31EiiEPjv7ym4Q+hQKQ+MDwxCzAJBgNVBAYMAkpQMRIwEAYDVQQKDAlKSU4uR1Iu +SlAxDDAKBgNVBAsMA1JSUjELMAkGA1UEAwwCQ0GCAQAwDQYJKoZIhvcNAQEFBQAD +ggEBAIu/mfiez5XN5tn2jScgShPgHEFJBR0BTJBZF6xCk0jyqNx/g9HMj2ELCuK+ +r/Y7KFW5c5M3AQ+xWW0ZSc4kvzyTcV7yTVIwj2jZ9ddYMN3nupZFgBK1GB4Y05GY +MJJFRkSu6d/Ph5ypzBVw2YMT/nsOo5VwMUGLgS7YVjU+u/HNWz80J3oO17mNZllj +PvORJcnjwlroDnS58KoJ7GDgejv3ESWADvX1OHLE4cRkiQGeLoEU4pxdCxXRqX0U +PbwIkZN9mXVcrmPHq8MWi4eC/V7hnbZETMHuWhUoiNdOEfsAXr3iP4KjyyRdwc7a +d/xgcK06UVQRL/HbEYGiQL056mc= +-----END CERTIFICATE----- diff --git a/sample/soap/ssl/files/client.cert b/sample/soap/ssl/files/client.cert new file mode 100644 index 000000000..ad13c4b73 --- /dev/null +++ b/sample/soap/ssl/files/client.cert @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDKDCCAhCgAwIBAgIBAjANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES +MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X +DTA0MDEzMTAzMTQ1OFoXDTM1MDEyMzAzMTQ1OFowZTELMAkGA1UEBgwCSlAxEjAQ +BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMRAwDgYDVQQDDAdleGFtcGxl +MSIwIAYJKoZIhvcNAQkBDBNleGFtcGxlQGV4YW1wbGUub3JnMIGfMA0GCSqGSIb3 +DQEBAQUAA4GNADCBiQKBgQDRWssrK8Gyr+500hpLjCGR3+AHL8/hEJM5zKi/MgLW +jTkvsgOwbYwXOiNtAbR9y4/ucDq7EY+cMUMHES4uFaPTcOaAV0aZRmk8AgslN1tQ +gNS6ew7/Luq3DcVeWkX8PYgR9VG0mD1MPfJ6+IFA5d3vKpdBkBgN4l46jjO0/2Xf +ewIDAQABo4GPMIGMMAwGA1UdEwEB/wQCMAAwMQYJYIZIAYb4QgENBCQWIlJ1Ynkv +T3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFOFvay0H7lr2 +xUx6waYEV2bVDYQhMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAgYI +KwYBBQUHAwQwDQYJKoZIhvcNAQEFBQADggEBABd2dYWqbDIWf5sWFvslezxJv8gI +w64KCJBuyJAiDuf+oazr3016kMzAlt97KecLZDusGNagPrq02UX7YMoQFsWJBans +cDtHrkM0al5r6/WGexNMgtYbNTYzt/IwodISGBgZ6dsOuhznwms+IBsTNDAvWeLP +lt2tOqD8kEmjwMgn0GDRuKjs4EoboA3kMULb1p9akDV9ZESU3eOtpS5/G5J5msLI +9WXbYBjcjvkLuJH9VsJhb+R58Vl0ViemvAHhPilSl1SPWVunGhv6FcIkdBEi1k9F +e8BNMmsEjFiANiIRvpdLRbiGBt0KrKTndVfsmoKCvY48oCOvnzxtahFxfs8= +-----END CERTIFICATE----- diff --git a/sample/soap/ssl/files/client.key b/sample/soap/ssl/files/client.key new file mode 100644 index 000000000..37bc62f25 --- /dev/null +++ b/sample/soap/ssl/files/client.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQDRWssrK8Gyr+500hpLjCGR3+AHL8/hEJM5zKi/MgLWjTkvsgOw +bYwXOiNtAbR9y4/ucDq7EY+cMUMHES4uFaPTcOaAV0aZRmk8AgslN1tQgNS6ew7/ +Luq3DcVeWkX8PYgR9VG0mD1MPfJ6+IFA5d3vKpdBkBgN4l46jjO0/2XfewIDAQAB +AoGAZcz8llWErtsV3QB9gNb3S/PNADGjqBFjReva8n3jG2k4sZSibpwWTwUaTNtT +ZQgjSRKRvH1hk9XwffNAvXAQZNNkuj/16gO2oO45nyLj4dO365ujLptWnVIWDHOE +uN0GeiZO+VzcCisT0WCq4tvtLeH8svrxzA8cbXIEyOK7NiECQQDwo2zPFyKAZ/Cu +lDJ6zKT+RjfWwW7DgWzirAlTrt4ViMaW+IaDH29TmQpb4V4NuR3Xi+2Xl4oicu6S +36TW9+/FAkEA3rgfOQJuLlWSnw1RTGwvnC816a/W7iYYY7B+0U4cDbfWl7IoXT4y +M8nV/HESooviZLqBwzAYSoj3fFKYBKpGPwJAUO8GN5iWWA2dW3ooiDiv/X1sZmRk +dojfMFWgRW747tEzya8Ivq0h6kH8w+5GjeMG8Gn1nRiwsulo6Ckj7dEx6QJACyui +7UIQ8qP6GZ4aYMHgVW4Mvy7Bkeo5OO7GPYs0Xv/EdJFL8vlGnVBXOjUVoS9w6Gpu +TbLg1QQvnX2rADjmEwJANxZO2GUkaWGsEif8aGW0x5g/IdaMGG27pTWk5zqix7P3 +1UDrdo/JOXhptovhRi06EppIxAxYmbh9vd9VN8Itlw== +-----END RSA PRIVATE KEY----- diff --git a/sample/soap/ssl/files/server.cert b/sample/soap/ssl/files/server.cert new file mode 100644 index 000000000..998ccc589 --- /dev/null +++ b/sample/soap/ssl/files/server.cert @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQGDAJKUDES +MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxDjAMBgNVBAMMBVN1YkNB +MB4XDTA0MDEzMTAzMTMxNloXDTMzMDEyMzAzMTMxNlowQzELMAkGA1UEBgwCSlAx +EjAQBgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMRIwEAYDVQQDDAlsb2Nh +bGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANFJTxWqup3nV9dsJAku +p+WaXnPNIzcpAA3qMGZDJTJsfa8Du7ZxTP0XJK5mETttBrn711cJxAuP3KjqnW9S +vtZ9lY2sXJ6Zj62sN5LwG3VVe25dI28yR1EsbHjJ5Zjf9tmggMC6am52dxuHbt5/ +vHo4ngJuKE/U+eeGRivMn6gFAgMBAAGjgYUwgYIwDAYDVR0TAQH/BAIwADAxBglg +hkgBhvhCAQ0EJBYiUnVieS9PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd +BgNVHQ4EFgQUpZIyygD9JxFYHHOTEuWOLbCKfckwCwYDVR0PBAQDAgWgMBMGA1Ud +JQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQBwAIj5SaBHaA5X31IP +CFCJiep96awfp7RANO0cuUj+ZpGoFn9d6FXY0g+Eg5wAkCNIzZU5NHN9xsdOpnUo +zIBbyTfQEPrge1CMWMvL6uGaoEXytq84VTitF/xBTky4KtTn6+es4/e7jrrzeUXQ +RC46gkHObmDT91RkOEGjHLyld2328jo3DIN/VTHIryDeVHDWjY5dENwpwdkhhm60 +DR9IrNBbXWEe9emtguNXeN0iu1ux0lG1Hc6pWGQxMlRKNvGh0yZB9u5EVe38tOV0 +jQaoNyL7qzcQoXD3Dmbi1p0iRmg/+HngISsz8K7k7MBNVsSclztwgCzTZOBiVtkM +rRlQ +-----END CERTIFICATE----- diff --git a/sample/soap/ssl/files/server.key b/sample/soap/ssl/files/server.key new file mode 100644 index 000000000..9ba2218a0 --- /dev/null +++ b/sample/soap/ssl/files/server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDRSU8Vqrqd51fXbCQJLqflml5zzSM3KQAN6jBmQyUybH2vA7u2 +cUz9FySuZhE7bQa5+9dXCcQLj9yo6p1vUr7WfZWNrFyemY+trDeS8Bt1VXtuXSNv +MkdRLGx4yeWY3/bZoIDAumpudncbh27ef7x6OJ4CbihP1PnnhkYrzJ+oBQIDAQAB +AoGBAIf4CstW2ltQO7+XYGoex7Hh8s9lTSW/G2vu5Hbr1LTHy3fzAvdq8MvVR12O +rk9fa+lU9vhzPc0NMB0GIDZ9GcHuhW5hD1Wg9OSCbTOkZDoH3CAFqonjh4Qfwv5W +IPAFn9KHukdqGXkwEMdErsUaPTy9A1V/aROVEaAY+HJgq/eZAkEA/BP1QMV04WEZ +Oynzz7/lLizJGGxp2AOvEVtqMoycA/Qk+zdKP8ufE0wbmCE3Qd6GoynavsHb6aGK +gQobb8zDZwJBANSK6MrXlrZTtEaeZuyOB4mAmRzGzOUVkUyULUjEx2GDT93ujAma +qm/2d3E+wXAkNSeRpjUmlQXy/2oSqnGvYbMCQQDRM+cYyEcGPUVpWpnj0shrF/QU +9vSot/X1G775EMTyaw6+BtbyNxVgOIu2J+rqGbn3c+b85XqTXOPL0A2RLYkFAkAm +syhSDtE9X55aoWsCNZY/vi+i4rvaFoQ/WleogVQAeGVpdo7/DK9t9YWoFBIqth0L +mGSYFu9ZhvZkvQNV8eYrAkBJ+rOIaLDsmbrgkeDruH+B/9yrm4McDtQ/rgnOGYnH +LjLpLLOrgUxqpzLWe++EwSLwK2//dHO+SPsQJ4xsyQJy +-----END RSA PRIVATE KEY----- diff --git a/sample/soap/ssl/files/sslclient.properties b/sample/soap/ssl/files/sslclient.properties new file mode 100644 index 000000000..547ac7b3f --- /dev/null +++ b/sample/soap/ssl/files/sslclient.properties @@ -0,0 +1,5 @@ +# verify server's certificate +protocol.http.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER +# certificates for verification +protocol.http.ssl_config.ca_file = files/ca.cert +protocol.http.ssl_config.ca_file = files/subca.cert diff --git a/sample/soap/ssl/files/sslclient_require_noserverauth.properties b/sample/soap/ssl/files/sslclient_require_noserverauth.properties new file mode 100644 index 000000000..5ce5337fb --- /dev/null +++ b/sample/soap/ssl/files/sslclient_require_noserverauth.properties @@ -0,0 +1,2 @@ +# no verify server's certificate +protocol.http.ssl_config.verify_mode = diff --git a/sample/soap/ssl/files/sslclient_with_clientauth.properties b/sample/soap/ssl/files/sslclient_with_clientauth.properties new file mode 100644 index 000000000..f1c81ebf4 --- /dev/null +++ b/sample/soap/ssl/files/sslclient_with_clientauth.properties @@ -0,0 +1,9 @@ +# verify server's certificate +protocol.http.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER +# certificates for verification +protocol.http.ssl_config.ca_file = files/ca.cert +protocol.http.ssl_config.ca_file = files/subca.cert + +# key and certificate for client identity +protocol.http.ssl_config.client_cert = files/client.cert +protocol.http.ssl_config.client_key = files/client.key diff --git a/sample/soap/ssl/files/subca.cert b/sample/soap/ssl/files/subca.cert new file mode 100644 index 000000000..1e471851b --- /dev/null +++ b/sample/soap/ssl/files/subca.cert @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES +MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X +DTA0MDEzMDAwNDMyN1oXDTM1MDEyMjAwNDMyN1owPzELMAkGA1UEBgwCSlAxEjAQ +BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQ4wDAYDVQQDDAVTdWJDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0Ou7AyRcRXnB/kVHv/6kwe +ANzgg/DyJfsAUqW90m7Lu1nqyug8gK0RBd77yU0w5HOAMHTVSdpjZK0g2sgx4Mb1 +d/213eL9TTl5MRVEChTvQr8q5DVG/8fxPPE7fMI8eOAzd98/NOAChk+80r4Sx7fC +kGVEE1bKwY1MrUsUNjOY2d6t3M4HHV3HX1V8ShuKfsHxgCmLzdI8U+5CnQedFgkm +3e+8tr8IX5RR1wA1Ifw9VadF7OdI/bGMzog/Q8XCLf+WPFjnK7Gcx6JFtzF6Gi4x +4dp1Xl45JYiVvi9zQ132wu8A1pDHhiNgQviyzbP+UjcB/tsOpzBQF8abYzgEkWEC +AwEAAaNyMHAwDwYDVR0TAQH/BAUwAwEB/zAxBglghkgBhvhCAQ0EJBYiUnVieS9P +cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUlCjXWLsReYzH +LzsxwVnCXmKoB/owCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCJ/OyN +rT8Cq2Y+G2yA/L1EMRvvxwFBqxavqaqHl/6rwsIBFlB3zbqGA/0oec6MAVnYynq4 +c4AcHTjx3bQ/S4r2sNTZq0DH4SYbQzIobx/YW8PjQUJt8KQdKMcwwi7arHP7A/Ha +LKu8eIC2nsUBnP4NhkYSGhbmpJK+PFD0FVtD0ZIRlY/wsnaZNjWWcnWF1/FNuQ4H +ySjIblqVQkPuzebv3Ror6ZnVDukn96Mg7kP4u6zgxOeqlJGRe1M949SS9Vudjl8X +SF4aZUUB9pQGhsqQJVqaz2OlhGOp9D0q54xko/rekjAIcuDjl1mdX4F2WRrzpUmZ +uY/bPeOBYiVsOYVe +-----END CERTIFICATE----- diff --git a/sample/soap/ssl/sslclient.rb b/sample/soap/ssl/sslclient.rb new file mode 100644 index 000000000..a055247a4 --- /dev/null +++ b/sample/soap/ssl/sslclient.rb @@ -0,0 +1,12 @@ +require 'http-access2' +require 'soap/rpc/driver' + +# setup driver +url = "https://localhost:17443/" +client = SOAP::RPC::Driver.new(url, 'urn:sslhelloworld') +client.add_method("hello_world", "from") +# load SSL properties +client.loadproperty('files/sslclient.properties') + +# SOAP over SSL +p client.hello_world(__FILE__) diff --git a/sample/soap/ssl/sslclient_require_noserverauth.rb b/sample/soap/ssl/sslclient_require_noserverauth.rb new file mode 100644 index 000000000..af121e9a4 --- /dev/null +++ b/sample/soap/ssl/sslclient_require_noserverauth.rb @@ -0,0 +1,12 @@ +require 'http-access2' +require 'soap/rpc/driver' + +# setup driver +url = "https://localhost:17443/" +client = SOAP::RPC::Driver.new(url, 'urn:sslhelloworld') +client.add_method("hello_world", "from") +# load SSL properties +client.loadproperty('files/sslclient_require_noserverauth.properties') + +# SOAP over SSL +p client.hello_world(__FILE__) diff --git a/sample/soap/ssl/sslclient_with_clientauth.rb b/sample/soap/ssl/sslclient_with_clientauth.rb new file mode 100644 index 000000000..7753d7b80 --- /dev/null +++ b/sample/soap/ssl/sslclient_with_clientauth.rb @@ -0,0 +1,12 @@ +require 'http-access2' +require 'soap/rpc/driver' + +# setup driver +url = "https://localhost:17443/" +client = SOAP::RPC::Driver.new(url, 'urn:sslhelloworld') +client.add_method("hello_world", "from") +# load SSL properties +client.loadproperty('files/sslclient_with_clientauth.properties') + +# SOAP over SSL +p client.hello_world(__FILE__) diff --git a/sample/soap/ssl/sslserver.rb b/sample/soap/ssl/sslserver.rb new file mode 100644 index 000000000..e65cbacc7 --- /dev/null +++ b/sample/soap/ssl/sslserver.rb @@ -0,0 +1,49 @@ +require 'soap/rpc/httpserver' +require 'webrick/https' +require 'logger' + +class HelloWorldServer < SOAP::RPC::HTTPServer +private + + def on_init + @default_namespace = 'urn:sslhelloworld' + add_method(self, 'hello_world', 'from') + end + + def hello_world(from) + "Hello World, from #{ from }" + end +end + + +if $0 == __FILE__ + DIR = File.dirname(File.expand_path(__FILE__)) + + def cert(filename) + OpenSSL::X509::Certificate.new(File.open(File.join(DIR, filename)) { |f| + f.read + }) + end + + def key(filename) + OpenSSL::PKey::RSA.new(File.open(File.join(DIR, filename)) { |f| + f.read + }) + end + + $server = HelloWorldServer.new( + :BindAddress => "0.0.0.0", + :Port => 17443, + :AccessLog => [], + :SSLEnable => true, + :SSLCACertificateFile => File.join(DIR, 'files/ca.cert'), + :SSLCertificate => cert('files/server.cert'), + :SSLPrivateKey => key('files/server.key'), + :SSLVerifyClient => nil, + :SSLCertName => nil + ) + trap(:INT) do + $server.shutdown + end + $server.start +end diff --git a/sample/soap/ssl/sslserver_noauth.rb b/sample/soap/ssl/sslserver_noauth.rb new file mode 100644 index 000000000..48f5a68ad --- /dev/null +++ b/sample/soap/ssl/sslserver_noauth.rb @@ -0,0 +1,45 @@ +require 'soap/rpc/httpserver' +require 'webrick/https' +require 'logger' + +class HelloWorldServer < SOAP::RPC::HTTPServer +private + + def on_init + @default_namespace = 'urn:sslhelloworld' + add_method(self, 'hello_world', 'from') + end + + def hello_world(from) + "Hello World, from #{ from }" + end +end + + +if $0 == __FILE__ + DIR = File.dirname(File.expand_path(__FILE__)) + + def cert(filename) + OpenSSL::X509::Certificate.new(File.open(File.join(DIR, filename)) { |f| + f.read + }) + end + + def key(filename) + OpenSSL::PKey::RSA.new(File.open(File.join(DIR, filename)) { |f| + f.read + }) + end + + $server = HelloWorldServer.new( + :BindAddress => "0.0.0.0", + :Port => 17443, + :AccessLog => [], + :SSLEnable => true, + :SSLCertName => [['OU', 'example'], ['CN', 'localhost']] # creates dummy certificate + ) + trap(:INT) do + $server.shutdown + end + $server.start +end diff --git a/sample/soap/ssl/sslserver_require_clientauth.rb b/sample/soap/ssl/sslserver_require_clientauth.rb new file mode 100644 index 000000000..63caf69ca --- /dev/null +++ b/sample/soap/ssl/sslserver_require_clientauth.rb @@ -0,0 +1,50 @@ +require 'soap/rpc/httpserver' +require 'webrick/https' +require 'logger' + +class HelloWorldServer < SOAP::RPC::HTTPServer +private + + def on_init + @default_namespace = 'urn:sslhelloworld' + add_method(self, 'hello_world', 'from') + end + + def hello_world(from) + "Hello World, from #{ from }" + end +end + + +if $0 == __FILE__ + DIR = File.dirname(File.expand_path(__FILE__)) + + def cert(filename) + OpenSSL::X509::Certificate.new(File.open(File.join(DIR, filename)) { |f| + f.read + }) + end + + def key(filename) + OpenSSL::PKey::RSA.new(File.open(File.join(DIR, filename)) { |f| + f.read + }) + end + + $server = HelloWorldServer.new( + :BindAddress => "0.0.0.0", + :Port => 17443, + :AccessLog => [], + :SSLEnable => true, + :SSLCACertificateFile => File.join(DIR, 'files/ca.cert'), + :SSLCertificate => cert('files/server.cert'), + :SSLPrivateKey => key('files/server.key'), + :SSLVerifyClient => + OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT|OpenSSL::SSL::VERIFY_PEER, + :SSLClientCA => cert('files/ca.cert') + ) + trap(:INT) do + $server.shutdown + end + $server.start +end diff --git a/sample/soap/swa/client.rb b/sample/soap/swa/client.rb new file mode 100644 index 000000000..01c59a384 --- /dev/null +++ b/sample/soap/swa/client.rb @@ -0,0 +1,13 @@ +require 'soap/rpc/driver' +require 'soap/attachment' + +server = 'http://localhost:7000/' +driver = SOAP::RPC::Driver.new(server, 'http://www.acmetron.com/soap') +driver.wiredump_dev = STDERR +driver.add_method('get_file') +driver.add_method('put_file', 'name', 'file') + +p driver.get_file +file = File.open($0) +attach = SOAP::Attachment.new(file) +p driver.put_file($0, attach) diff --git a/sample/soap/swa/server.rb b/sample/soap/swa/server.rb new file mode 100644 index 000000000..0a82fe58b --- /dev/null +++ b/sample/soap/swa/server.rb @@ -0,0 +1,23 @@ +require 'soap/rpc/standaloneServer' +require 'soap/attachment' + +class SwAService + def get_file + return { + 'name' => $0, + 'file' => SOAP::Attachment.new(File.open($0)) + } + end + + def put_file(name, file) + "File '#{name}' was received ok." + end +end + +server = SOAP::RPC::StandaloneServer.new('SwAServer', + 'http://www.acmetron.com/soap', '0.0.0.0', 7000) +server.add_servant(SwAService.new) +trap(:INT) do + server.shutdown +end +server.start diff --git a/sample/soap/whois.rb b/sample/soap/whois.rb new file mode 100644 index 000000000..2737e8085 --- /dev/null +++ b/sample/soap/whois.rb @@ -0,0 +1,14 @@ +#!/usr/bin/env ruby + +key = ARGV.shift + +require 'soap/rpc/driver' + +server = 'http://www.SoapClient.com/xml/SQLDataSoap.WSDL' +interface = 'http://www.SoapClient.com/xml/SQLDataSoap.xsd' + +whois = SOAP::RPC::Driver.new(server, interface) +whois.wiredump_dev = STDERR +whois.add_method('ProcessSRL', 'SRLFile', 'RequestName', 'key') + +p whois.ProcessSRL('WHOIS.SRI', 'whois', key) diff --git a/sample/wsdl/raa2.4/raa.rb b/sample/wsdl/raa2.4/raa.rb new file mode 100644 index 000000000..9b4c4e41a --- /dev/null +++ b/sample/wsdl/raa2.4/raa.rb @@ -0,0 +1,332 @@ +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class Gem + @@schema_type = "Gem" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" + + def id + @id + end + + def id=(value) + @id = value + end + + def category + @category + end + + def category=(value) + @category = value + end + + def owner + @owner + end + + def owner=(value) + @owner = value + end + + def project + @project + end + + def project=(value) + @project = value + end + + def updated + @updated + end + + def updated=(value) + @updated = value + end + + def created + @created + end + + def created=(value) + @created = value + end + + def initialize(id = nil, + category = nil, + owner = nil, + project = nil, + updated = nil, + created = nil) + @id = id + @category = category + @owner = owner + @project = project + @updated = updated + @created = created + end +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class Category + @@schema_type = "Category" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" + + def major + @major + end + + def major=(value) + @major = value + end + + def minor + @minor + end + + def minor=(value) + @minor = value + end + + def initialize(major = nil, + minor = nil) + @major = major + @minor = minor + end +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class Owner + @@schema_type = "Owner" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" + + def id + @id + end + + def id=(value) + @id = value + end + + def email + @email + end + + def email=(value) + @email = value + end + + def name + @name + end + + def name=(value) + @name = value + end + + def initialize(id = nil, + email = nil, + name = nil) + @id = id + @email = email + @name = name + end +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class Project + @@schema_type = "Project" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" + + def name + @name + end + + def name=(value) + @name = value + end + + def short_description + @short_description + end + + def short_description=(value) + @short_description = value + end + + def version + @version + end + + def version=(value) + @version = value + end + + def status + @status + end + + def status=(value) + @status = value + end + + def url + @url + end + + def url=(value) + @url = value + end + + def download + @download + end + + def download=(value) + @download = value + end + + def license + @license + end + + def license=(value) + @license = value + end + + def description + @description + end + + def description=(value) + @description = value + end + + def updated + @updated + end + + def updated=(value) + @updated = value + end + + def history + @history + end + + def history=(value) + @history = value + end + + def dependency + @dependency + end + + def dependency=(value) + @dependency = value + end + + def initialize(name = nil, + short_description = nil, + version = nil, + status = nil, + url = nil, + download = nil, + license = nil, + description = nil, + updated = nil, + history = nil, + dependency = nil) + @name = name + @short_description = short_description + @version = version + @status = status + @url = url + @download = download + @license = license + @description = description + @updated = updated + @history = history + @dependency = dependency + end +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class ProjectDependency + @@schema_type = "ProjectDependency" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" + + def project + @project + end + + def project=(value) + @project = value + end + + def version + @version + end + + def version=(value) + @version = value + end + + def description + @description + end + + def description=(value) + @description = value + end + + def initialize(project = nil, + version = nil, + description = nil) + @project = project + @version = version + @description = description + end +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class GemArray < Array + # Contents type should be dumped here... + @@schema_type = "GemArray" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class OwnerArray < Array + # Contents type should be dumped here... + @@schema_type = "OwnerArray" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class ProjectArray < Array + # Contents type should be dumped here... + @@schema_type = "ProjectArray" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class ProjectDependencyArray < Array + # Contents type should be dumped here... + @@schema_type = "ProjectDependencyArray" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" +end + +# http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/ +class StringArray < Array + # Contents type should be dumped here... + @@schema_type = "StringArray" + @@schema_ns = "http://www.ruby-lang.org/xmlns/soap/type/RAA/0.0.3/" +end + +# http://xml.apache.org/xml-soap +class Map < Array + # Contents type should be dumped here... + @@schema_type = "Map" + @@schema_ns = "http://xml.apache.org/xml-soap" +end + diff --git a/sample/wsdl/raa2.4/wsdlDriver.rb b/sample/wsdl/raa2.4/wsdlDriver.rb new file mode 100644 index 000000000..bc5fb1998 --- /dev/null +++ b/sample/wsdl/raa2.4/wsdlDriver.rb @@ -0,0 +1,117 @@ +#!/usr/bin/env ruby + +# You can generate raa.rb required here with the command; +# wsdl2ruby.rb --wsdl http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/ --classdef +require 'raa' +require 'soap/wsdlDriver' +require 'pp' + +RAA_WSDL = 'http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/' + +raa = SOAP::WSDLDriverFactory.new(RAA_WSDL).create_driver +raa.generate_explicit_type = true +# raa.wiredump_dev = STDERR + +def sec(msg) + puts + puts "--------" + puts "-- " + msg + puts +end + +def subsec(msg) + puts "-- " + msg +end + +sec("retrieve a gem (RAA Information) which has specified name") +name = 'soap4r' +pp raa.gem(name) + +sec("retrieve dependents of the project") +name = 'http-access2'; version = nil +pp raa.dependents(name, version) + +sec("number of registered gems") +puts raa.size + +sec("retrieve all registered gem names") +p raa.names + +sec("retrieve gems of specified category") +major = 'Library'; minor = 'XML' +p raa.list_by_category(major, minor) + +sec("retrieve category tree") +pp raa.tree_by_category + +sec("retrieve gems which is updated recently") +idx = 0 +p raa.list_recent_updated(idx) +subsec("next 10 gems") +idx += 1 +p raa.list_recent_updated(idx) +subsec("next 10 gems") +idx += 1 +p raa.list_recent_updated(idx) + +sec("retrieve gems which is created recently") +p raa.list_recent_created(idx) + +sec("retrieve gems which is updated in 7 days") +date = Time.now - 7 * 24 * 60 * 60; idx = 0 +p raa.list_updated_since(date, idx) + +sec("retrieve gems which is created in 7 days") +p raa.list_created_since(date, idx) + +sec("retrieve gems of specified owner") +owner_id = 8 # NaHi +p raa.list_by_owner(owner_id) + +sec("search gems with keyword") +substring = 'soap' +pp raa.search(substring) + +# There are several search interface to search a field explicitly. +# puts raa.search_name(substring, idx) +# puts raa.search_short_description(substring, idx) +# puts raa.search_owner(substring, idx) +# puts raa.search_version(substring, idx) +# puts raa.search_status(substring, idx) +# puts raa.search_description(substring, idx) + +sec("retrieve owner info") +owner_id = 8 +pp raa.owner(owner_id) + +sec("retrieve owners") +idx = 0 +p raa.list_owner(idx) + +sec("update 'sampleproject'") +name = 'sampleproject' +pass = 'sampleproject' +gem = raa.gem(name) +p gem.project.version +gem.project.version.succ! +gem.updated = Time.now +raa.update(name, pass, gem) +p raa.gem(name).project.version + +sec("update pass phrase") +raa.update_pass(name, 'sampleproject', 'foo') +subsec("update check") +gem = raa.gem(name) +gem.project.description = 'Current pass phrase is "foo"' +gem.updated = Time.now +raa.update(name, 'foo', gem) +# +subsec("recover pass phrase") +raa.update_pass(name, 'foo', 'sampleproject') +subsec("update check") +gem = raa.gem(name) +gem.project.description = 'Current pass phrase is "sampleproject"' +gem.updated = Time.now +raa.update(name, 'sampleproject', gem) + +sec("done") diff --git a/test/soap/header/server.cgi b/test/soap/header/server.cgi new file mode 100644 index 000000000..f9739d0d1 --- /dev/null +++ b/test/soap/header/server.cgi @@ -0,0 +1,119 @@ +require 'pstore' +require 'soap/rpc/cgistub' +require 'soap/header/simplehandler' + + +class AuthHeaderPortServer < SOAP::RPC::CGIStub + PortName = 'http://tempuri.org/authHeaderPort' + SupportPortName = 'http://tempuri.org/authHeaderSupportPort' + MyHeaderName = XSD::QName.new("http://tempuri.org/authHeader", "auth") + SessionDB = File.join(File.expand_path(File.dirname(__FILE__)), 'session.pstoredb') + + class AuthHeaderService + def self.create + new + end + + def deposit(amt) + "deposit #{amt} OK" + end + + def withdrawal(amt) + "withdrawal #{amt} OK" + end + end + + class AuthHeaderSupportService + def delete_sessiondb + File.unlink(SessionDB) if File.file?(SessionDB) + backup = SessionDB + "~" + File.unlink(backup) if File.file?(backup) + end + end + + def initialize(*arg) + super + add_rpc_servant(AuthHeaderService.new, PortName) + add_rpc_servant(AuthHeaderSupportService.new, SupportPortName) + add_rpc_headerhandler(ServerAuthHeaderHandler.new) + end + + class ServerAuthHeaderHandler < SOAP::Header::SimpleHandler + Users = { + 'NaHi' => 'passwd', + 'HiNa' => 'wspass' + } + + def initialize + super(MyHeaderName) + @db = PStore.new(SessionDB) + @db.transaction do + @db["root"] = {} unless @db.root?("root") + end + @userid = @sessionid = nil + end + + def login(userid, passwd) + userid and passwd and Users[userid] == passwd + end + + def auth(sessionid) + in_sessiondb do |root| + root[sessionid][0] + end + end + + def create_session(userid) + in_sessiondb do |root| + while true + key = create_sessionkey + break unless root[key] + end + root[key] = [userid] + key + end + end + + def destroy_session(sessionkey) + in_sessiondb do |root| + root.delete(sessionkey) + end + end + + def on_simple_outbound + { "sessionid" => @sessionid } + end + + def on_simple_inbound(my_header, mu) + auth = false + userid = my_header["userid"] + passwd = my_header["passwd"] + if login(userid, passwd) + auth = true + elsif sessionid = my_header["sessionid"] + if userid = auth(sessionid) + destroy_session(sessionid) + auth = true + end + end + raise RuntimeError.new("authentication failed") unless auth + @userid = userid + @sessionid = create_session(userid) + end + + private + + def create_sessionkey + Time.now.usec.to_s + end + + def in_sessiondb + @db.transaction do + yield(@db["root"]) + end + end + end +end + + +status = AuthHeaderPortServer.new('AuthHeaderPortServer', nil).start diff --git a/test/soap/header/test_authheader.rb b/test/soap/header/test_authheader.rb new file mode 100644 index 000000000..2c04769dd --- /dev/null +++ b/test/soap/header/test_authheader.rb @@ -0,0 +1,247 @@ +require 'test/unit' +require 'soap/rpc/driver' +require 'soap/rpc/standaloneServer' +require 'soap/header/simplehandler' + + +module SOAP +module Header + + +class TestAuthHeader < Test::Unit::TestCase + Port = 17171 + PortName = 'http://tempuri.org/authHeaderPort' + MyHeaderName = XSD::QName.new("http://tempuri.org/authHeader", "auth") + DummyHeaderName = XSD::QName.new("http://tempuri.org/authHeader", "dummy") + + class AuthHeaderPortServer < SOAP::RPC::StandaloneServer + class AuthHeaderService + def self.create + new + end + + def deposit(amt) + "deposit #{amt} OK" + end + + def withdrawal(amt) + "withdrawal #{amt} OK" + end + end + + def initialize(*arg) + super + add_rpc_servant(AuthHeaderService.new, PortName) + ServerAuthHeaderHandler.init + add_rpc_request_headerhandler(ServerAuthHeaderHandler) + end + + class ServerAuthHeaderHandler < SOAP::Header::SimpleHandler + class << self + def create + new + end + + def init + @users = { + 'NaHi' => 'passwd', + 'HiNa' => 'wspass' + } + @sessions = {} + end + + def login(userid, passwd) + userid and passwd and @users[userid] == passwd + end + + def auth(sessionid) + @sessions[sessionid][0] + end + + def create_session(userid) + while true + key = create_sessionkey + break unless @sessions[key] + end + @sessions[key] = [userid] + key + end + + def destroy_session(sessionkey) + @sessions.delete(sessionkey) + end + + def sessions + @sessions + end + + private + + def create_sessionkey + Time.now.usec.to_s + end + end + + def initialize + super(MyHeaderName) + @userid = @sessionid = nil + end + + def on_simple_outbound + { "sessionid" => @sessionid } + end + + def on_simple_inbound(my_header, mu) + auth = false + userid = my_header["userid"] + passwd = my_header["passwd"] + if self.class.login(userid, passwd) + auth = true + elsif sessionid = my_header["sessionid"] + if userid = self.class.auth(sessionid) + self.class.destroy_session(sessionid) + auth = true + end + end + raise RuntimeError.new("authentication failed") unless auth + @userid = userid + @sessionid = self.class.create_session(userid) + end + end + end + + class ClientAuthHeaderHandler < SOAP::Header::SimpleHandler + def initialize(userid, passwd, mustunderstand) + super(MyHeaderName) + @sessionid = nil + @userid = userid + @passwd = passwd + @mustunderstand = mustunderstand + end + + def on_simple_outbound + if @sessionid + { "sessionid" => @sessionid } + else + { "userid" => @userid, "passwd" => @passwd } + end + end + + def on_simple_inbound(my_header, mustunderstand) + @sessionid = my_header["sessionid"] + end + + def sessionid + @sessionid + end + end + + class DummyHeaderHandler < SOAP::Header::SimpleHandler + def initialize(mustunderstand) + super(DummyHeaderName) + @mustunderstand = mustunderstand + end + + def on_simple_outbound + { XSD::QName.new("foo", "bar") => nil } + end + + def on_simple_inbound(my_header, mustunderstand) + end + end + + def setup + @endpoint = "http://localhost:#{Port}/" + setup_server + setup_client + end + + def setup_server + @server = AuthHeaderPortServer.new(self.class.name, nil, '0.0.0.0', Port) + @server.level = Logger::Severity::ERROR + @t = Thread.new { + @server.start + } + while @server.status != :Running + sleep 0.1 + unless @t.alive? + @t.join + raise + end + end + end + + def setup_client + @client = SOAP::RPC::Driver.new(@endpoint, PortName) + @client.wiredump_dev = STDERR if $DEBUG + @client.add_method('deposit', 'amt') + @client.add_method('withdrawal', 'amt') + end + + def teardown + teardown_server + teardown_client + end + + def teardown_server + @server.shutdown + @t.kill + @t.join + end + + def teardown_client + @client.reset_stream + end + + def test_success_no_mu + h = ClientAuthHeaderHandler.new('NaHi', 'passwd', false) + @client.headerhandler << h + do_transaction_check(h) + end + + def test_success_mu + h = ClientAuthHeaderHandler.new('NaHi', 'passwd', true) + @client.headerhandler << h + do_transaction_check(h) + end + + def test_no_mu + h = ClientAuthHeaderHandler.new('NaHi', 'passwd', true) + @client.headerhandler << h + @client.headerhandler << DummyHeaderHandler.new(false) + do_transaction_check(h) + end + + def test_mu + h = ClientAuthHeaderHandler.new('NaHi', 'passwd', true) + @client.headerhandler << h + @client.headerhandler << (h2 = DummyHeaderHandler.new(true)) + assert_raise(SOAP::UnhandledMustUnderstandHeaderError) do + assert_equal("deposit 150 OK", @client.deposit(150)) + end + @client.headerhandler.delete(h2) + @client.headerhandler << (h2 = DummyHeaderHandler.new(false)) + do_transaction_check(h) + end + + def do_transaction_check(h) + assert_equal("deposit 150 OK", @client.deposit(150)) + serversess = AuthHeaderPortServer::ServerAuthHeaderHandler.sessions[h.sessionid] + assert_equal("NaHi", serversess[0]) + assert_equal("withdrawal 120 OK", @client.withdrawal(120)) + serversess = AuthHeaderPortServer::ServerAuthHeaderHandler.sessions[h.sessionid] + assert_equal("NaHi", serversess[0]) + end + + def test_authfailure + h = ClientAuthHeaderHandler.new('NaHi', 'pa', false) + @client.headerhandler << h + assert_raises(RuntimeError) do + @client.deposit(150) + end + end +end + + +end +end diff --git a/test/soap/header/test_authheader_cgi.rb b/test/soap/header/test_authheader_cgi.rb new file mode 100644 index 000000000..03bd1bb96 --- /dev/null +++ b/test/soap/header/test_authheader_cgi.rb @@ -0,0 +1,128 @@ +require 'test/unit' +require 'soap/rpc/driver' +require 'soap/rpc/standaloneServer' +require 'soap/header/simplehandler' +require 'logger' +require 'webrick' +require 'rbconfig' + + +module SOAP +module Header + + +class TestAuthHeaderCGI < Test::Unit::TestCase + # This test shuld be run after installing ruby. + RUBYBIN = File.join( + Config::CONFIG["bindir"], + Config::CONFIG["ruby_install_name"] + Config::CONFIG["EXEEXT"] + ) + RUBYBIN << " -d" if $DEBUG + + Port = 17171 + PortName = 'http://tempuri.org/authHeaderPort' + SupportPortName = 'http://tempuri.org/authHeaderSupportPort' + MyHeaderName = XSD::QName.new("http://tempuri.org/authHeader", "auth") + + class ClientAuthHeaderHandler < SOAP::Header::SimpleHandler + def initialize(userid, passwd) + super(MyHeaderName) + @sessionid = nil + @userid = userid + @passwd = passwd + end + + def on_simple_outbound + if @sessionid + { "sessionid" => @sessionid } + else + { "userid" => @userid, "passwd" => @passwd } + end + end + + def on_simple_inbound(my_header, mustunderstand) + @sessionid = my_header["sessionid"] + end + + def sessionid + @sessionid + end + end + + def setup + @endpoint = "http://localhost:#{Port}/" + setup_server + setup_client + end + + def setup_server + @endpoint = "http://localhost:#{Port}/server.cgi" + logger = Logger.new(STDERR) + logger.level = Logger::Severity::ERROR + @server = WEBrick::HTTPServer.new( + :BindAddress => "0.0.0.0", + :Logger => logger, + :Port => Port, + :AccessLog => [], + :DocumentRoot => File.dirname(File.expand_path(__FILE__)), + :CGIPathEnv => ENV['PATH'], + :CGIInterpreter => RUBYBIN + ) + @t = Thread.new { + Thread.current.abort_on_exception = true + @server.start + } + while @server.status != :Running + sleep 0.1 + unless @t.alive? + @t.join + raise + end + end + end + + def setup_client + @client = SOAP::RPC::Driver.new(@endpoint, PortName) + @client.wiredump_dev = STDERR if $DEBUG + @client.add_method('deposit', 'amt') + @client.add_method('withdrawal', 'amt') + @supportclient = SOAP::RPC::Driver.new(@endpoint, SupportPortName) + @supportclient.add_method('delete_sessiondb') + end + + def teardown + @supportclient.delete_sessiondb + teardown_server + teardown_client + end + + def teardown_server + @server.shutdown + @t.kill + @t.join + end + + def teardown_client + @client.reset_stream + @supportclient.reset_stream + end + + def test_success + h = ClientAuthHeaderHandler.new('NaHi', 'passwd') + @client.headerhandler << h + assert_equal("deposit 150 OK", @client.deposit(150)) + assert_equal("withdrawal 120 OK", @client.withdrawal(120)) + end + + def test_authfailure + h = ClientAuthHeaderHandler.new('NaHi', 'pa') + @client.headerhandler << h + assert_raises(RuntimeError) do + @client.deposit(150) + end + end +end + + +end +end diff --git a/test/soap/ssl/README b/test/soap/ssl/README new file mode 100644 index 000000000..98ebcf7c2 --- /dev/null +++ b/test/soap/ssl/README @@ -0,0 +1 @@ +* certificates and keys in this directory is copied from http-access2 test. diff --git a/test/soap/ssl/ca.cert b/test/soap/ssl/ca.cert new file mode 100644 index 000000000..bcabbee4a --- /dev/null +++ b/test/soap/ssl/ca.cert @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID0DCCArigAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES +MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X +DTA0MDEzMDAwNDIzMloXDTM2MDEyMjAwNDIzMlowPDELMAkGA1UEBgwCSlAxEjAQ +BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQswCQYDVQQDDAJDQTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANbv0x42BTKFEQOE+KJ2XmiSdZpR +wjzQLAkPLRnLB98tlzs4xo+y4RyY/rd5TT9UzBJTIhP8CJi5GbS1oXEerQXB3P0d +L5oSSMwGGyuIzgZe5+vZ1kgzQxMEKMMKlzA73rbMd4Jx3u5+jdbP0EDrPYfXSvLY +bS04n2aX7zrN3x5KdDrNBfwBio2/qeaaj4+9OxnwRvYP3WOvqdW0h329eMfHw0pi +JI0drIVdsEqClUV4pebT/F+CPUPkEh/weySgo9wANockkYu5ujw2GbLFcO5LXxxm +dEfcVr3r6t6zOA4bJwL0W/e6LBcrwiG/qPDFErhwtgTLYf6Er67SzLyA66UCAwEA +AaOB3DCB2TAPBgNVHRMBAf8EBTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09w +ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRJ7Xd380KzBV7f +USKIQ+O/vKbhDzAOBgNVHQ8BAf8EBAMCAQYwZAYDVR0jBF0wW4AUSe13d/NCswVe +31EiiEPjv7ym4Q+hQKQ+MDwxCzAJBgNVBAYMAkpQMRIwEAYDVQQKDAlKSU4uR1Iu +SlAxDDAKBgNVBAsMA1JSUjELMAkGA1UEAwwCQ0GCAQAwDQYJKoZIhvcNAQEFBQAD +ggEBAIu/mfiez5XN5tn2jScgShPgHEFJBR0BTJBZF6xCk0jyqNx/g9HMj2ELCuK+ +r/Y7KFW5c5M3AQ+xWW0ZSc4kvzyTcV7yTVIwj2jZ9ddYMN3nupZFgBK1GB4Y05GY +MJJFRkSu6d/Ph5ypzBVw2YMT/nsOo5VwMUGLgS7YVjU+u/HNWz80J3oO17mNZllj +PvORJcnjwlroDnS58KoJ7GDgejv3ESWADvX1OHLE4cRkiQGeLoEU4pxdCxXRqX0U +PbwIkZN9mXVcrmPHq8MWi4eC/V7hnbZETMHuWhUoiNdOEfsAXr3iP4KjyyRdwc7a +d/xgcK06UVQRL/HbEYGiQL056mc= +-----END CERTIFICATE----- diff --git a/test/soap/ssl/client.cert b/test/soap/ssl/client.cert new file mode 100644 index 000000000..ad13c4b73 --- /dev/null +++ b/test/soap/ssl/client.cert @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDKDCCAhCgAwIBAgIBAjANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES +MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X +DTA0MDEzMTAzMTQ1OFoXDTM1MDEyMzAzMTQ1OFowZTELMAkGA1UEBgwCSlAxEjAQ +BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMRAwDgYDVQQDDAdleGFtcGxl +MSIwIAYJKoZIhvcNAQkBDBNleGFtcGxlQGV4YW1wbGUub3JnMIGfMA0GCSqGSIb3 +DQEBAQUAA4GNADCBiQKBgQDRWssrK8Gyr+500hpLjCGR3+AHL8/hEJM5zKi/MgLW +jTkvsgOwbYwXOiNtAbR9y4/ucDq7EY+cMUMHES4uFaPTcOaAV0aZRmk8AgslN1tQ +gNS6ew7/Luq3DcVeWkX8PYgR9VG0mD1MPfJ6+IFA5d3vKpdBkBgN4l46jjO0/2Xf +ewIDAQABo4GPMIGMMAwGA1UdEwEB/wQCMAAwMQYJYIZIAYb4QgENBCQWIlJ1Ynkv +T3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFOFvay0H7lr2 +xUx6waYEV2bVDYQhMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAgYI +KwYBBQUHAwQwDQYJKoZIhvcNAQEFBQADggEBABd2dYWqbDIWf5sWFvslezxJv8gI +w64KCJBuyJAiDuf+oazr3016kMzAlt97KecLZDusGNagPrq02UX7YMoQFsWJBans +cDtHrkM0al5r6/WGexNMgtYbNTYzt/IwodISGBgZ6dsOuhznwms+IBsTNDAvWeLP +lt2tOqD8kEmjwMgn0GDRuKjs4EoboA3kMULb1p9akDV9ZESU3eOtpS5/G5J5msLI +9WXbYBjcjvkLuJH9VsJhb+R58Vl0ViemvAHhPilSl1SPWVunGhv6FcIkdBEi1k9F +e8BNMmsEjFiANiIRvpdLRbiGBt0KrKTndVfsmoKCvY48oCOvnzxtahFxfs8= +-----END CERTIFICATE----- diff --git a/test/soap/ssl/client.key b/test/soap/ssl/client.key new file mode 100644 index 000000000..37bc62f25 --- /dev/null +++ b/test/soap/ssl/client.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQDRWssrK8Gyr+500hpLjCGR3+AHL8/hEJM5zKi/MgLWjTkvsgOw +bYwXOiNtAbR9y4/ucDq7EY+cMUMHES4uFaPTcOaAV0aZRmk8AgslN1tQgNS6ew7/ +Luq3DcVeWkX8PYgR9VG0mD1MPfJ6+IFA5d3vKpdBkBgN4l46jjO0/2XfewIDAQAB +AoGAZcz8llWErtsV3QB9gNb3S/PNADGjqBFjReva8n3jG2k4sZSibpwWTwUaTNtT +ZQgjSRKRvH1hk9XwffNAvXAQZNNkuj/16gO2oO45nyLj4dO365ujLptWnVIWDHOE +uN0GeiZO+VzcCisT0WCq4tvtLeH8svrxzA8cbXIEyOK7NiECQQDwo2zPFyKAZ/Cu +lDJ6zKT+RjfWwW7DgWzirAlTrt4ViMaW+IaDH29TmQpb4V4NuR3Xi+2Xl4oicu6S +36TW9+/FAkEA3rgfOQJuLlWSnw1RTGwvnC816a/W7iYYY7B+0U4cDbfWl7IoXT4y +M8nV/HESooviZLqBwzAYSoj3fFKYBKpGPwJAUO8GN5iWWA2dW3ooiDiv/X1sZmRk +dojfMFWgRW747tEzya8Ivq0h6kH8w+5GjeMG8Gn1nRiwsulo6Ckj7dEx6QJACyui +7UIQ8qP6GZ4aYMHgVW4Mvy7Bkeo5OO7GPYs0Xv/EdJFL8vlGnVBXOjUVoS9w6Gpu +TbLg1QQvnX2rADjmEwJANxZO2GUkaWGsEif8aGW0x5g/IdaMGG27pTWk5zqix7P3 +1UDrdo/JOXhptovhRi06EppIxAxYmbh9vd9VN8Itlw== +-----END RSA PRIVATE KEY----- diff --git a/test/soap/ssl/server.cert b/test/soap/ssl/server.cert new file mode 100644 index 000000000..998ccc589 --- /dev/null +++ b/test/soap/ssl/server.cert @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQGDAJKUDES +MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxDjAMBgNVBAMMBVN1YkNB +MB4XDTA0MDEzMTAzMTMxNloXDTMzMDEyMzAzMTMxNlowQzELMAkGA1UEBgwCSlAx +EjAQBgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMRIwEAYDVQQDDAlsb2Nh +bGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANFJTxWqup3nV9dsJAku +p+WaXnPNIzcpAA3qMGZDJTJsfa8Du7ZxTP0XJK5mETttBrn711cJxAuP3KjqnW9S +vtZ9lY2sXJ6Zj62sN5LwG3VVe25dI28yR1EsbHjJ5Zjf9tmggMC6am52dxuHbt5/ +vHo4ngJuKE/U+eeGRivMn6gFAgMBAAGjgYUwgYIwDAYDVR0TAQH/BAIwADAxBglg +hkgBhvhCAQ0EJBYiUnVieS9PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd +BgNVHQ4EFgQUpZIyygD9JxFYHHOTEuWOLbCKfckwCwYDVR0PBAQDAgWgMBMGA1Ud +JQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQBwAIj5SaBHaA5X31IP +CFCJiep96awfp7RANO0cuUj+ZpGoFn9d6FXY0g+Eg5wAkCNIzZU5NHN9xsdOpnUo +zIBbyTfQEPrge1CMWMvL6uGaoEXytq84VTitF/xBTky4KtTn6+es4/e7jrrzeUXQ +RC46gkHObmDT91RkOEGjHLyld2328jo3DIN/VTHIryDeVHDWjY5dENwpwdkhhm60 +DR9IrNBbXWEe9emtguNXeN0iu1ux0lG1Hc6pWGQxMlRKNvGh0yZB9u5EVe38tOV0 +jQaoNyL7qzcQoXD3Dmbi1p0iRmg/+HngISsz8K7k7MBNVsSclztwgCzTZOBiVtkM +rRlQ +-----END CERTIFICATE----- diff --git a/test/soap/ssl/server.key b/test/soap/ssl/server.key new file mode 100644 index 000000000..9ba2218a0 --- /dev/null +++ b/test/soap/ssl/server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDRSU8Vqrqd51fXbCQJLqflml5zzSM3KQAN6jBmQyUybH2vA7u2 +cUz9FySuZhE7bQa5+9dXCcQLj9yo6p1vUr7WfZWNrFyemY+trDeS8Bt1VXtuXSNv +MkdRLGx4yeWY3/bZoIDAumpudncbh27ef7x6OJ4CbihP1PnnhkYrzJ+oBQIDAQAB +AoGBAIf4CstW2ltQO7+XYGoex7Hh8s9lTSW/G2vu5Hbr1LTHy3fzAvdq8MvVR12O +rk9fa+lU9vhzPc0NMB0GIDZ9GcHuhW5hD1Wg9OSCbTOkZDoH3CAFqonjh4Qfwv5W +IPAFn9KHukdqGXkwEMdErsUaPTy9A1V/aROVEaAY+HJgq/eZAkEA/BP1QMV04WEZ +Oynzz7/lLizJGGxp2AOvEVtqMoycA/Qk+zdKP8ufE0wbmCE3Qd6GoynavsHb6aGK +gQobb8zDZwJBANSK6MrXlrZTtEaeZuyOB4mAmRzGzOUVkUyULUjEx2GDT93ujAma +qm/2d3E+wXAkNSeRpjUmlQXy/2oSqnGvYbMCQQDRM+cYyEcGPUVpWpnj0shrF/QU +9vSot/X1G775EMTyaw6+BtbyNxVgOIu2J+rqGbn3c+b85XqTXOPL0A2RLYkFAkAm +syhSDtE9X55aoWsCNZY/vi+i4rvaFoQ/WleogVQAeGVpdo7/DK9t9YWoFBIqth0L +mGSYFu9ZhvZkvQNV8eYrAkBJ+rOIaLDsmbrgkeDruH+B/9yrm4McDtQ/rgnOGYnH +LjLpLLOrgUxqpzLWe++EwSLwK2//dHO+SPsQJ4xsyQJy +-----END RSA PRIVATE KEY----- diff --git a/test/soap/ssl/sslsvr.rb b/test/soap/ssl/sslsvr.rb new file mode 100644 index 000000000..281c1a1a5 --- /dev/null +++ b/test/soap/ssl/sslsvr.rb @@ -0,0 +1,56 @@ +require 'webrick/https' +require 'logger' +require 'rbconfig' + +require 'soap/rpc/httpserver' + +class HelloWorldServer < SOAP::RPC::HTTPServer +private + + def on_init + self.level = Logger::Severity::FATAL + @default_namespace = 'urn:ssltst' + add_method(self, 'hello_world', 'from') + end + + def hello_world(from) + "Hello World, from #{ from }" + end +end + + +if $0 == __FILE__ + PORT = 17171 + DIR = File.dirname(File.expand_path(__FILE__)) + + def cert(filename) + OpenSSL::X509::Certificate.new(File.open(File.join(DIR, filename)) { |f| + f.read + }) + end + + def key(filename) + OpenSSL::PKey::RSA.new(File.open(File.join(DIR, filename)) { |f| + f.read + }) + end + + $server = HelloWorldServer.new( + :BindAddress => "0.0.0.0", + :Port => PORT, + :AccessLog => [], + :SSLEnable => true, + :SSLCACertificateFile => File.join(DIR, 'ca.cert'), + :SSLCertificate => cert('server.cert'), + :SSLPrivateKey => key('server.key'), + :SSLVerifyClient => nil, #OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT|OpenSSL::SSL::VERIFY_PEER, + :SSLClientCA => cert('ca.cert'), + :SSLCertName => nil + ) + trap(:INT) do + $server.shutdown if $server + end + STDOUT.sync = true + STDOUT.puts $$ + $server.start +end diff --git a/test/soap/ssl/subca.cert b/test/soap/ssl/subca.cert new file mode 100644 index 000000000..1e471851b --- /dev/null +++ b/test/soap/ssl/subca.cert @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES +MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X +DTA0MDEzMDAwNDMyN1oXDTM1MDEyMjAwNDMyN1owPzELMAkGA1UEBgwCSlAxEjAQ +BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQ4wDAYDVQQDDAVTdWJDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0Ou7AyRcRXnB/kVHv/6kwe +ANzgg/DyJfsAUqW90m7Lu1nqyug8gK0RBd77yU0w5HOAMHTVSdpjZK0g2sgx4Mb1 +d/213eL9TTl5MRVEChTvQr8q5DVG/8fxPPE7fMI8eOAzd98/NOAChk+80r4Sx7fC +kGVEE1bKwY1MrUsUNjOY2d6t3M4HHV3HX1V8ShuKfsHxgCmLzdI8U+5CnQedFgkm +3e+8tr8IX5RR1wA1Ifw9VadF7OdI/bGMzog/Q8XCLf+WPFjnK7Gcx6JFtzF6Gi4x +4dp1Xl45JYiVvi9zQ132wu8A1pDHhiNgQviyzbP+UjcB/tsOpzBQF8abYzgEkWEC +AwEAAaNyMHAwDwYDVR0TAQH/BAUwAwEB/zAxBglghkgBhvhCAQ0EJBYiUnVieS9P +cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUlCjXWLsReYzH +LzsxwVnCXmKoB/owCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCJ/OyN +rT8Cq2Y+G2yA/L1EMRvvxwFBqxavqaqHl/6rwsIBFlB3zbqGA/0oec6MAVnYynq4 +c4AcHTjx3bQ/S4r2sNTZq0DH4SYbQzIobx/YW8PjQUJt8KQdKMcwwi7arHP7A/Ha +LKu8eIC2nsUBnP4NhkYSGhbmpJK+PFD0FVtD0ZIRlY/wsnaZNjWWcnWF1/FNuQ4H +ySjIblqVQkPuzebv3Ror6ZnVDukn96Mg7kP4u6zgxOeqlJGRe1M949SS9Vudjl8X +SF4aZUUB9pQGhsqQJVqaz2OlhGOp9D0q54xko/rekjAIcuDjl1mdX4F2WRrzpUmZ +uY/bPeOBYiVsOYVe +-----END CERTIFICATE----- diff --git a/test/soap/ssl/test_ssl.rb b/test/soap/ssl/test_ssl.rb new file mode 100644 index 000000000..6678c775a --- /dev/null +++ b/test/soap/ssl/test_ssl.rb @@ -0,0 +1,212 @@ +require 'test/unit' +begin + require 'http-access2' +rescue LoadError +end +require 'soap/rpc/driver' + +if defined?(HTTPAccess2) + +module SOAP; module SSL + + +class TestSSL < Test::Unit::TestCase + PORT = 17171 + + DIR = File.dirname(File.expand_path(__FILE__)) + require 'rbconfig' + RUBY = File.join( + Config::CONFIG["bindir"], + Config::CONFIG["ruby_install_name"] + Config::CONFIG["EXEEXT"] + ) + + def setup + @url = "https://localhost:#{PORT}/hello" + @serverpid = @client = nil + @verify_callback_called = false + setup_server + setup_client + end + + def teardown + teardown_client + teardown_server + end + + def streamhandler + @client.instance_eval("@servant").instance_eval("@streamhandler").client + end + + def test_options + cfg = streamhandler.ssl_config + assert_nil(cfg.client_cert) + assert_nil(cfg.client_key) + assert_nil(cfg.client_ca) + assert_equal(OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT, cfg.verify_mode) + assert_nil(cfg.verify_callback) + assert_nil(cfg.timeout) + assert_equal(OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_SSLv2, cfg.options) + assert_equal("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH", cfg.ciphers) + assert_instance_of(OpenSSL::X509::Store, cfg.cert_store) + # dummy call to ensure sslsvr initialization finished. + assert_raise(OpenSSL::SSL::SSLError) do + @client.hello_world("ssl client") + end + end + + def test_verification + cfg = @client.options + cfg["protocol.http.ssl_config.verify_callback"] = method(:verify_callback).to_proc + begin + @verify_callback_called = false + @client.hello_world("ssl client") + assert(false) + rescue OpenSSL::SSL::SSLError => ssle + assert_equal("certificate verify failed", ssle.message) + assert(@verify_callback_called) + end + # + cfg["protocol.http.ssl_config.client_cert"] = File.join(DIR, "client.cert") + cfg["protocol.http.ssl_config.client_key"] = File.join(DIR, "client.key") + @verify_callback_called = false + begin + @client.hello_world("ssl client") + assert(false) + rescue OpenSSL::SSL::SSLError => ssle + assert_equal("certificate verify failed", ssle.message) + assert(@verify_callback_called) + end + # + cfg["protocol.http.ssl_config.ca_file"] = File.join(DIR, "ca.cert") + @verify_callback_called = false + begin + @client.hello_world("ssl client") + assert(false) + rescue OpenSSL::SSL::SSLError => ssle + assert_equal("certificate verify failed", ssle.message) + assert(@verify_callback_called) + end + # + cfg["protocol.http.ssl_config.ca_file"] = File.join(DIR, "subca.cert") + @verify_callback_called = false + assert_equal("Hello World, from ssl client", @client.hello_world("ssl client")) + assert(@verify_callback_called) + # + cfg["protocol.http.ssl_config.verify_depth"] = "1" + @verify_callback_called = false + begin + @client.hello_world("ssl client") + assert(false) + rescue OpenSSL::SSL::SSLError => ssle + assert_equal("certificate verify failed", ssle.message) + assert(@verify_callback_called) + end + # + cfg["protocol.http.ssl_config.verify_depth"] = "" + cfg["protocol.http.ssl_config.cert_store"] = OpenSSL::X509::Store.new + cfg["protocol.http.ssl_config.verify_mode"] = OpenSSL::SSL::VERIFY_PEER.to_s + begin + @client.hello_world("ssl client") + assert(false) + rescue OpenSSL::SSL::SSLError => ssle + assert_equal("certificate verify failed", ssle.message) + end + # + cfg["protocol.http.ssl_config.verify_mode"] = "" + assert_equal("Hello World, from ssl client", @client.hello_world("ssl client")) + end + + def test_property + testpropertyname = File.join(DIR, 'soapclient.properties') + File.open(testpropertyname, "w") do |f| + f <<<<__EOP__ +protocol.http.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER +# depth: 1 causes an error (intentional) +protocol.http.ssl_config.verify_depth = 1 +protocol.http.ssl_config.client_cert = #{File.join(DIR, 'client.cert')} +protocol.http.ssl_config.client_key = #{File.join(DIR, 'client.key')} +protocol.http.ssl_config.ca_file = #{File.join(DIR, 'ca.cert')} +protocol.http.ssl_config.ca_file = #{File.join(DIR, 'subca.cert')} +protocol.http.ssl_config.ciphers = ALL +__EOP__ + end + begin + @client.loadproperty(testpropertyname) + @client.options["protocol.http.ssl_config.verify_callback"] = method(:verify_callback).to_proc + @verify_callback_called = false + begin + @client.hello_world("ssl client") + assert(false) + rescue OpenSSL::SSL::SSLError => ssle + assert_equal("certificate verify failed", ssle.message) + assert(@verify_callback_called) + end + # + @client.options["protocol.http.ssl_config.verify_depth"] = "" + @verify_callback_called = false + assert_equal("Hello World, from ssl client", @client.hello_world("ssl client")) + assert(@verify_callback_called) + ensure + File.unlink(testpropertyname) + end + end + + def test_ciphers + cfg = @client.options + cfg["protocol.http.ssl_config.client_cert"] = File.join(DIR, 'client.cert') + cfg["protocol.http.ssl_config.client_key"] = File.join(DIR, 'client.key') + cfg["protocol.http.ssl_config.ca_file"] = File.join(DIR, "ca.cert") + cfg["protocol.http.ssl_config.ca_file"] = File.join(DIR, "subca.cert") + #cfg.timeout = 123 + assert_equal("Hello World, from ssl client", @client.hello_world("ssl client")) + # + cfg["protocol.http.ssl_config.ciphers"] = "!ALL" + begin + @client.hello_world("ssl client") + assert(false) + rescue OpenSSL::SSL::SSLError => ssle + assert_equal("no ciphers available", ssle.message) + end + # + cfg["protocol.http.ssl_config.ciphers"] = "ALL" + assert_equal("Hello World, from ssl client", @client.hello_world("ssl client")) + end + +private + + def q(str) + %Q["#{str}"] + end + + def setup_server + svrcmd = "#{q(RUBY)} " + svrcmd << "-d " if $DEBUG + svrcmd << File.join(DIR, "sslsvr.rb") + svrout = IO.popen(svrcmd) + @serverpid = Integer(svrout.gets.chomp) + end + + def setup_client + @client = SOAP::RPC::Driver.new(@url, 'urn:ssltst') + @client.add_method("hello_world", "from") + end + + def teardown_server + Process.kill('INT', @serverpid) + end + + def teardown_client + @client.reset_stream + end + + def verify_callback(ok, cert) + @verify_callback_called = true + p ["client", ok, cert] if $DEBUG + ok + end +end + + +end; end + +end diff --git a/test/soap/struct/test_struct.rb b/test/soap/struct/test_struct.rb new file mode 100644 index 000000000..71ada3167 --- /dev/null +++ b/test/soap/struct/test_struct.rb @@ -0,0 +1,83 @@ +require 'test/unit' +require 'soap/rpc/httpserver' +require 'soap/rpc/driver' + + +module SOAP; module Struct + + +class TestStruct < Test::Unit::TestCase + Namespace = "urn:example.com:simpletype-rpc" + class Server < ::SOAP::RPC::HTTPServer + @@test_struct = ::Struct.new(:one, :two) + + def on_init + add_method(self, 'a_method') + end + + def a_method + @@test_struct.new("string", 1) + end + end + + Port = 17171 + + def setup + setup_server + setup_client + end + + def setup_server + @server = Server.new( + :Port => Port, + :AccessLog => [], + :SOAPDefaultNamespace => Namespace + ) + @server.level = Logger::Severity::ERROR + @server_thread = start_server_thread(@server) + end + + def setup_client + @client = ::SOAP::RPC::Driver.new("http://localhost:#{Port}/", Namespace) + @client.wiredump_dev = STDERR if $DEBUG + @client.add_method('a_method') + end + + def teardown + teardown_server + teardown_client + end + + def teardown_server + @server.shutdown + @server_thread.kill + @server_thread.join + end + + def teardown_client + @client.reset_stream + end + + def start_server_thread(server) + t = Thread.new { + Thread.current.abort_on_exception = true + server.start + } + while server.status != :Running + sleep 0.1 + unless t.alive? + t.join + raise + end + end + t + end + + def test_struct + assert_equal("string", @client.a_method.one) + assert_equal(1, @client.a_method.two) + end +end + + +end; end diff --git a/test/soap/swa/test_file.rb b/test/soap/swa/test_file.rb new file mode 100644 index 000000000..29bdf88a3 --- /dev/null +++ b/test/soap/swa/test_file.rb @@ -0,0 +1,77 @@ +require 'test/unit' +require 'soap/rpc/driver' +require 'soap/rpc/standaloneServer' +require 'soap/attachment' + + +module SOAP +module SWA + + +class TestFile < Test::Unit::TestCase + Port = 17171 + THIS_FILE = File.expand_path(__FILE__) + + class SwAService + def get_file + return { + 'name' => $0, + 'file' => SOAP::Attachment.new(File.open(THIS_FILE)) # closed when GCed. + } + end + + def put_file(name, file) + "File '#{name}' was received ok." + end + end + + def setup + @server = SOAP::RPC::StandaloneServer.new('SwAServer', + 'http://www.acmetron.com/soap', '0.0.0.0', Port) + @server.add_servant(SwAService.new) + @server.level = Logger::Severity::ERROR + @t = Thread.new { + @server.start + } + while @server.status != :Running + sleep 0.1 + unless @t.alive? + @t.join + raise + end + end + @endpoint = "http://localhost:#{Port}/" + @client = SOAP::RPC::Driver.new(@endpoint, 'http://www.acmetron.com/soap') + @client.add_method('get_file') + @client.add_method('put_file', 'name', 'file') + @client.wiredump_dev = STDERR if $DEBUG + end + + def teardown + @server.shutdown + @t.kill + @t.join + @client.reset_stream + end + + def test_file + assert_equal( + File.open(THIS_FILE) { |f| f.read }, + @client.get_file['file'].content + ) + assert_equal( + "File 'foo' was received ok.", + @client.put_file('foo', + SOAP::Attachment.new(File.open(THIS_FILE))) + ) + assert_equal( + "File 'bar' was received ok.", + @client.put_file('bar', + SOAP::Attachment.new(File.open(THIS_FILE) { |f| f.read })) + ) + end +end + + +end +end diff --git a/test/soap/wsdlDriver/README.txt b/test/soap/wsdlDriver/README.txt new file mode 100644 index 000000000..b4d45a048 --- /dev/null +++ b/test/soap/wsdlDriver/README.txt @@ -0,0 +1,2 @@ +echo_version.rb is generated by wsdl2ruby.rb; +% wsdl2ruby.rb --wsdl simpletype.wsdl --classdef --force diff --git a/test/soap/wsdlDriver/echo_version.rb b/test/soap/wsdlDriver/echo_version.rb new file mode 100644 index 000000000..7d76fb758 --- /dev/null +++ b/test/soap/wsdlDriver/echo_version.rb @@ -0,0 +1,20 @@ +# urn:example.com:simpletype-rpc-type +class Version_struct + @@schema_type = "version_struct" + @@schema_ns = "urn:example.com:simpletype-rpc-type" + + attr_accessor :version + attr_accessor :msg + + def initialize(version = nil, msg = nil) + @version = version + @msg = msg + end +end + +# urn:example.com:simpletype-rpc-type +module Versions + C_16 = "1.6" + C_18 = "1.8" + C_19 = "1.9" +end diff --git a/test/soap/wsdlDriver/simpletype.wsdl b/test/soap/wsdlDriver/simpletype.wsdl new file mode 100644 index 000000000..7c211a6b2 --- /dev/null +++ b/test/soap/wsdlDriver/simpletype.wsdl @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<definitions name="echo_version" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:tns="urn:example.com:simpletype-rpc" + xmlns:txd="urn:example.com:simpletype-rpc-type" + targetNamespace="urn:example.com:simpletype-rpc" + xmlns="http://schemas.xmlsoap.org/wsdl/"> + <types> + <xsd:schema targetNamespace="urn:example.com:simpletype-rpc-type"> + <xsd:complexType name="version_struct"> + <xsd:all> + <xsd:element name="version" type="txd:versions" /> + <xsd:element name="msg" type="xsd:string" /> + </xsd:all> + </xsd:complexType> + + <xsd:simpleType name="versions"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="1.6"/> + <xsd:enumeration value="1.8"/> + <xsd:enumeration value="1.9"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:schema> + </types> + + <message name="msg_version"> + <part name="version" type="txd:versions"/> + </message> + + <message name="msg_version_struct"> + <part name="return" type="txd:version_struct"/> + </message> + + <portType name="echo_version_port_type"> + <operation name="echo_version"> + <input message="tns:msg_version"/> + <output message="tns:msg_version_struct"/> + </operation> + </portType> + + <binding name="echo_version_binding" type="tns:echo_version_port_type"> + <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/> + <operation name="echo_version"> + <soap:operation soapAction="urn:example.com:simpletype-rpc"/> + <input> + <soap:body use="encoded" namespace="urn:example.com:simpletype-rpc" + encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> + </input> + <output> + <soap:body use="encoded" namespace="urn:example.com:simpletype-rpc" + encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> + </output> + </operation> + </binding> + + <service name="echo_version_service"> + <port name="echo_version_port" binding="tns:echo_version_binding"> + <soap:address location="http://localhost:10080"/> + </port> + </service> +</definitions> diff --git a/test/soap/wsdlDriver/test_simpletype.rb b/test/soap/wsdlDriver/test_simpletype.rb new file mode 100644 index 000000000..ed628927c --- /dev/null +++ b/test/soap/wsdlDriver/test_simpletype.rb @@ -0,0 +1,92 @@ +require 'test/unit' +require 'soap/rpc/httpserver' +require 'soap/wsdlDriver' + + +module SOAP + + +class TestSimpleType < Test::Unit::TestCase + class Server < ::SOAP::RPC::HTTPServer + def on_init + add_method(self, 'echo_version', 'version') + end + + def echo_version(version) + # "2.0" is out of range. + Version_struct.new(version || "2.0", 'checked') + end + end + + DIR = File.dirname(File.expand_path(__FILE__)) + require File.join(DIR, 'echo_version') + + Port = 17171 + + def setup + setup_server + setup_client + end + + def setup_server + @server = Server.new( + :Port => Port, + :AccessLog => [], + :SOAPDefaultNamespace => "urn:example.com:simpletype-rpc" + ) + @server.level = Logger::Severity::ERROR + @server_thread = start_server_thread(@server) + end + + def setup_client + wsdl = File.join(DIR, 'simpletype.wsdl') + @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_driver + @client.endpoint_url = "http://localhost:#{Port}/" + @client.generate_explicit_type = false + end + + def teardown + teardown_server + teardown_client + end + + def teardown_server + @server.shutdown + @server_thread.kill + @server_thread.join + end + + def teardown_client + @client.reset_stream + end + + def start_server_thread(server) + t = Thread.new { + Thread.current.abort_on_exception = true + server.start + } + while server.status != :Running + sleep 0.1 + unless t.alive? + t.join + raise + end + end + t + end + + def test_ping + result = @client.echo_version("1.9") + assert_equal("1.9", result.version) + assert_equal("checked", result.msg) + assert_raise(::XSD::ValueSpaceError) do + @client.echo_version("2.0") + end + assert_raise(::XSD::ValueSpaceError) do + @client.echo_version(nil) # nil => "2.0" => out of range + end + end +end + + +end diff --git a/test/wsdl/multiplefault.wsdl b/test/wsdl/multiplefault.wsdl new file mode 100644 index 000000000..2d928b60b --- /dev/null +++ b/test/wsdl/multiplefault.wsdl @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<definitions name="MultipleFaultTest" + targetNamespace="urn:jp.gr.jin.rrr.example.ele" + xmlns:tns="urn:jp.gr.jin.rrr.example.ele" + xmlns:typens="urn:jp.gr.jin.rrr.example.datatypes" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" + xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" + xmlns="http://schemas.xmlsoap.org/wsdl/"> + + <types> + <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" + targetNamespace="urn:jp.gr.jin.rrr.example.datatypes"> + <xsd:complexType name="AuthenticationError"> + <all> + <element name="message" type="xsd:string" /> + <element name="backtrace" type="xoapenc:Array" /> + </all> + </xsd:complexType> + <xsd:complexType name="AuthorizationError"> + <all> + <element name="message" type="xsd:string" /> + <element name="backtrace" type="xoapenc:Array" /> + </all> + </xsd:complexType> + </xsd:schema> + </types> + + <message name="inputmsg"/> + <message name="outputmsg"/> + <message name="faultmsg1" > + <part name="exception" type="typens:AuthenticationError" /> + </message> + <message name="faultmsg2" > + <part name="exception" type="typens:AuthorizationError" /> + </message> + + <portType name="MultipleFaultPortType"> + <operation name="myoperation"> + <input message="tns:inputmsg"/> + <output message="tns:outputmsg"/> + <fault message="tns:faultmsg1"/> + <fault message="tns:faultmsg2"/> + </operation> + </portType> + + <binding name="MultipleFaultBinding" type="tns:MultipleFaultPortType"> + <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> + <operation name="myoperation"> + <soap:operation soapAction="urn:jp.gr.jin.rrr.example.ele"/> + <input> + <soap:body use="encoded" namespace="urn:jp.gr.jin.rrr.example.ele" + encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> + </input> + <output> + <soap:body use="encoded" namespace="urn:jp.gr.jin.rrr.example.ele" + encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> + </output> + </operation> + </binding> + + <service name="MultipleFaultService"> + <port name="MultipleFaultPortType" binding="tns:MultipleFaultBinding"> + <soap:address location="http://localhost:17171/"/> + </port> + </service> +</definitions> diff --git a/test/wsdl/simpletype/simpletype.wsdl b/test/wsdl/simpletype/simpletype.wsdl new file mode 100644 index 000000000..ec3266fc1 --- /dev/null +++ b/test/wsdl/simpletype/simpletype.wsdl @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<definitions name="ping_service" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:tns="urn:example.com:simpletype" + targetNamespace="urn:example.com:simpletype" + xmlns="http://schemas.xmlsoap.org/wsdl/"> + <types> + <xsd:schema targetNamespace="urn:example.com:simpletype"> + <xsd:element name="ruby"> + <xsd:complexType> + <xsd:sequence> + <xsd:element minOccurs="1" maxOccurs="1" name="version" type="tns:version"/> + <xsd:element minOccurs="0" maxOccurs="1" name="date" type="xsd:dateTime"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:simpleType name="version"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="1.6"/> + <xsd:enumeration value="1.8"/> + <xsd:enumeration value="1.9"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:schema> + </types> + + <message name="ping_in"> + <part name="parameters" element="tns:ruby"/> + </message> + + <message name="ping_out"> + <part name="parameters" element="xsd:string"/> + </message> + + <message name="versionmsg"> + <part name="version" element="tns:version"/> + </message> + + <portType name="ping_port_type"> + <operation name="ping"> + <input message="tns:ping_in"/> + <output message="tns:ping_out"/> + </operation> + + <operation name="echo_version"> + <input message="tns:versionmsg"/> + <output message="tns:versionmsg"/> + </operation> + </portType> + + <binding name="ping_binding" type="tns:ping_port_type"> + <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> + <operation name="ping"> + <soap:operation soapAction="urn:example.com:simpletype" style="document"/> + <input><soap:body use="literal"/></input> + <output><soap:body use="literal"/></output> + </operation> + </binding> + + <service name="ping_service"> + <port name="ping_port" binding="tns:ping_binding"> + <soap:address location="http://localhost:10080"/> + </port> + </service> +</definitions> diff --git a/test/wsdl/simpletype/test_simpletype.rb b/test/wsdl/simpletype/test_simpletype.rb new file mode 100644 index 000000000..a46bf5dd7 --- /dev/null +++ b/test/wsdl/simpletype/test_simpletype.rb @@ -0,0 +1,81 @@ +require 'test/unit' +require 'soap/rpc/standaloneServer' +require 'soap/wsdlDriver' + + +module WSDL +module SimpleType + + +class TestSimpleType < Test::Unit::TestCase + class Server < ::SOAP::RPC::StandaloneServer + def on_init + add_method(self, 'ruby', 'version', 'date') + end + + def ruby(version, date) + "#{version} (#{date})" + end + end + + DIR = File.dirname(File.expand_path(__FILE__)) + + Port = 17171 + + def setup + setup_server + setup_client + end + + def setup_server + @server = Server.new('Test', "urn:example.com:simpletype", '0.0.0.0', Port) + @server.level = Logger::Severity::ERROR + @server_thread = start_server_thread(@server) + end + + def setup_client + wsdl = File.join(DIR, 'simpletype.wsdl') + @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_driver + @client.endpoint_url = "http://localhost:#{Port}/" + @client.generate_explicit_type = false + end + + def teardown + teardown_server + teardown_client + end + + def teardown_server + @server.shutdown + @server_thread.kill + @server_thread.join + end + + def teardown_client + @client.reset_stream + end + + def start_server_thread(server) + t = Thread.new { + Thread.current.abort_on_exception = true + server.start + } + while server.status != :Running + sleep 0.1 + unless t.alive? + t.join + raise + end + end + t + end + + def test_ping + header, body = @client.ping(nil, {:version => "1.9", :date => "2004-01-01T00:00:00Z"}) + assert_equal("1.9 (2004-01-01T00:00:00Z)", body) + end +end + + +end +end diff --git a/test/wsdl/test_multiplefault.rb b/test/wsdl/test_multiplefault.rb new file mode 100644 index 000000000..7004297dc --- /dev/null +++ b/test/wsdl/test_multiplefault.rb @@ -0,0 +1,39 @@ +require 'test/unit' +require 'wsdl/parser' +require 'wsdl/soap/classDefCreator' + + +module WSDL + + +class TestMultipleFault < Test::Unit::TestCase + def self.setup(filename) + @@filename = filename + end + + def test_multiplefault + @wsdl = WSDL::Parser.new.parse(File.open(@@filename) { |f| f.read }) + classdefstr = WSDL::SOAP::ClassDefCreator.new(@wsdl).dump + yield_eval_binding(classdefstr) do |b| + assert_equal( + WSDL::TestMultipleFault::AuthenticationError, + eval("AuthenticationError", b) + ) + assert_equal( + WSDL::TestMultipleFault::AuthorizationError, + eval("AuthorizationError", b) + ) + end + end + + def yield_eval_binding(evaled) + b = binding + eval(evaled, b) + yield(b) + end +end + +TestMultipleFault.setup(File.join(File.dirname(__FILE__), 'multiplefault.wsdl')) + + +end |