From 330a8e51c56f5386753f55ba8e656a62471a36ba Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> Date: Mon, 20 Dec 2004 14:41:10 +0000 Subject: This commit was manufactured by cvs2svn to create branch 'ruby_1_8'. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@7616 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/net/https.rb | 171 +++++++++++++++++++ lib/soap/mapping/wsdlencodedregistry.rb | 173 +++++++++++++++++++ lib/soap/mapping/wsdlliteralregistry.rb | 281 +++++++++++++++++++++++++++++++ lib/wsdl/soap/element.rb | 34 ++++ lib/wsdl/xmlSchema/simpleContent.rb | 65 +++++++ sample/optparse/subcommand.rb | 19 +++ sample/soap/helloworld/hw_c_gzip.rb | 8 + sample/soap/helloworld/hw_s_gzip.rb | 21 +++ sample/soap/scopesample/client.rb | 34 ++++ sample/soap/scopesample/httpd.rb | 22 +++ sample/soap/scopesample/samplehttpd.conf | 2 + sample/soap/scopesample/servant.rb | 18 ++ sample/soap/scopesample/server.cgi | 29 ++++ sample/soap/scopesample/server.rb | 20 +++ test/ruby/test_super.rb | 88 ++++++++++ 15 files changed, 985 insertions(+) create mode 100644 lib/net/https.rb create mode 100644 lib/soap/mapping/wsdlencodedregistry.rb create mode 100644 lib/soap/mapping/wsdlliteralregistry.rb create mode 100644 lib/wsdl/soap/element.rb create mode 100644 lib/wsdl/xmlSchema/simpleContent.rb create mode 100755 sample/optparse/subcommand.rb create mode 100644 sample/soap/helloworld/hw_c_gzip.rb create mode 100644 sample/soap/helloworld/hw_s_gzip.rb create mode 100644 sample/soap/scopesample/client.rb create mode 100644 sample/soap/scopesample/httpd.rb create mode 100644 sample/soap/scopesample/samplehttpd.conf create mode 100644 sample/soap/scopesample/servant.rb create mode 100755 sample/soap/scopesample/server.cgi create mode 100644 sample/soap/scopesample/server.rb create mode 100644 test/ruby/test_super.rb diff --git a/lib/net/https.rb b/lib/net/https.rb new file mode 100644 index 0000000000..fb329df43d --- /dev/null +++ b/lib/net/https.rb @@ -0,0 +1,171 @@ +=begin + += $RCSfile$ -- SSL/TLS enhancement for Net::HTTP. + +== Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2001 GOTOU Yuuzou + All rights reserved. + +== Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + +== Requirements + This program requires Net 1.2.0 or higher version. + You can get it from RAA or Ruby's CVS repository. + +== Version + $Id$ + + 2001-11-06: Contiributed to Ruby/OpenSSL project. + 2004-03-06: Some code is merged in to net/http. + +== Example + +Here is a simple HTTP client: + + require 'net/http' + require 'uri' + + uri = URI.parse(ARGV[0] || 'http://localhost/') + http = Net::HTTP.new(uri.host, uri.port) + http.start { + http.request_get(uri.path) {|res| + print res.body + } + } + +It can be replaced by the following code: + + require 'net/https' + require 'uri' + + uri = URI.parse(ARGV[0] || 'https://localhost/') + http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = true if uri.scheme == "https" # enable SSL/TLS + http.start { + http.request_get(uri.path) {|res| + print res.body + } + } + +== class Net::HTTP + +=== Instance Methods + +: use_ssl? + returns true if use SSL/TLS with HTTP. + +: use_ssl=((|true_or_false|)) + sets use_ssl. + +: peer_cert + return the X.509 certificates the server presented. + +: key, key=((|key|)) + Sets an OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object. + (This method is appeared in Michal Rokos's OpenSSL extention.) + +: cert, cert=((|cert|)) + Sets an OpenSSL::X509::Certificate object as client certificate + (This method is appeared in Michal Rokos's OpenSSL extention). + +: ca_file, ca_file=((|path|)) + Sets path of a CA certification file in PEM format. + The file can contrain several CA certificats. + +: ca_path, ca_path=((|path|)) + Sets path of a CA certification directory containing certifications + in PEM format. + +: verify_mode, verify_mode=((|mode|)) + Sets the flags for server the certification verification at + begining of SSL/TLS session. + OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER is acceptable. + +: verify_callback, verify_callback=((|proc|)) + Sets the verify callback for the server certification verification. + +: verify_depth, verify_depth=((|num|)) + Sets the maximum depth for the certificate chain verification. + +: cert_store, cert_store=((|store|)) + Sets the X509::Store to verify peer certificate. + +: ssl_timeout, ssl_timeout=((|sec|)) + Sets the SSL timeout seconds. + +=end + +require 'net/http' +require 'openssl' + +module Net + + class HTTP + remove_method :use_ssl? + def use_ssl? + @use_ssl + end + + alias use_ssl use_ssl? # for backward compatibility + + # Turn on/off SSL. + # This flag must be set before starting session. + # If you change use_ssl value after session started, + # a Net::HTTP object raises IOError. + def use_ssl=(flag) + flag = (flag ? true : false) + raise IOError, "use_ssl value changed, but session already started" \ + if started? and @use_ssl != flag + if flag and not @ssl_context + @ssl_context = OpenSSL::SSL::SSLContext.new + end + @use_ssl = flag + end + + def self.ssl_context_accessor(name) + module_eval(<<-End, __FILE__, __LINE__ + 1) + def #{name} + return nil unless @ssl_context + @ssl_context.#{name} + end + + def #{name}=(val) + @ssl_context ||= OpenSSL::SSL::SSLContext.new + @ssl_context.#{name} = val + end + End + end + + ssl_context_accessor :key + ssl_context_accessor :cert + ssl_context_accessor :ca_file + ssl_context_accessor :ca_path + ssl_context_accessor :verify_mode + ssl_context_accessor :verify_callback + ssl_context_accessor :verify_depth + ssl_context_accessor :cert_store + + def ssl_timeout + return nil unless @ssl_context + @ssl_context.timeout + end + + def ssl_timeout=(sec) + raise ArgumentError, 'Net::HTTP#ssl_timeout= called but use_ssl=false' \ + unless use_ssl? + @ssl_context ||= OpenSSL::SSL::SSLContext.new + @ssl_context.timeout = sec + end + + alias timeout= ssl_timeout= # for backward compatibility + + def peer_cert + return nil if not use_ssl? or not @socket + @socket.io.peer_cert + end + end + +end diff --git a/lib/soap/mapping/wsdlencodedregistry.rb b/lib/soap/mapping/wsdlencodedregistry.rb new file mode 100644 index 0000000000..4433c73cf0 --- /dev/null +++ b/lib/soap/mapping/wsdlencodedregistry.rb @@ -0,0 +1,173 @@ +# SOAP4R - WSDL encoded mapping registry. +# Copyright (C) 2000, 2001, 2002, 2003 NAKAMURA, Hiroshi . + +# 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/baseData' +require 'soap/mapping/mapping' +require 'soap/mapping/typeMap' + + +module SOAP +module Mapping + + +class WSDLEncodedRegistry + include TraverseSupport + + attr_reader :definedtypes + attr_accessor :excn_handler_obj2soap + + def initialize(definedtypes, config = {}) + @definedtypes = definedtypes + @config = config + @excn_handler_obj2soap = nil + # For mapping AnyType element. + @rubytype_factory = RubytypeFactory.new( + :allow_untyped_struct => true, + :allow_original_mapping => true + ) + end + + def obj2soap(obj, type_qname = nil) + soap_obj = nil + if obj.nil? + soap_obj = SOAPNil.new + elsif type_qname.nil? or type_qname == XSD::AnyTypeName + soap_obj = @rubytype_factory.obj2soap(nil, obj, nil, self) + elsif obj.is_a?(XSD::NSDBase) + soap_obj = soap2soap(obj, type_qname) + elsif type = @definedtypes[type_qname] + soap_obj = obj2type(obj, type) + elsif (type = TypeMap[type_qname]) + soap_obj = base2soap(obj, type) + end + return soap_obj if soap_obj + if @excn_handler_obj2soap + soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj| + Mapping._obj2soap(yield_obj, self) + } + return soap_obj if soap_obj + end + raise MappingError.new("Cannot map #{ obj.class.name } to SOAP/OM.") + end + + def soap2obj(node) + raise RuntimeError.new("#{ self } is for obj2soap only.") + end + +private + + def soap2soap(obj, type_qname) + if obj.is_a?(SOAPBasetype) + obj + elsif obj.is_a?(SOAPStruct) && (type = @definedtypes[type_qname]) + soap_obj = obj + mark_marshalled_obj(obj, soap_obj) + elements2soap(obj, soap_obj, type.content.elements) + soap_obj + elsif obj.is_a?(SOAPArray) && (type = @definedtypes[type_qname]) + soap_obj = obj + contenttype = type.child_type + mark_marshalled_obj(obj, soap_obj) + obj.replace do |ele| + Mapping._obj2soap(ele, self, contenttype) + end + soap_obj + else + nil + end + end + + def obj2type(obj, type) + if type.is_a?(::WSDL::XMLSchema::SimpleType) + simple2soap(obj, type) + else + complex2soap(obj, type) + end + end + + def simple2soap(obj, type) + o = base2soap(obj, TypeMap[type.base]) + if type.restriction.enumeration.empty? + STDERR.puts("#{type.name}: simpleType which is not enum type not supported.") + return o + end + type.check_lexical_format(obj) + o + end + + def complex2soap(obj, type) + case type.compoundtype + when :TYPE_STRUCT + struct2soap(obj, type.name, type) + when :TYPE_ARRAY + array2soap(obj, type.name, type) + when :TYPE_MAP + map2soap(obj, type.name, type) + else + raise MappingError.new("Unknown compound type: #{ type.compoundtype }") + end + end + + def base2soap(obj, type) + soap_obj = nil + if type <= XSD::XSDString + soap_obj = type.new(XSD::Charset.is_ces(obj, $KCODE) ? + XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) : obj) + mark_marshalled_obj(obj, soap_obj) + else + soap_obj = type.new(obj) + end + soap_obj + end + + def struct2soap(obj, type_qname, type) + soap_obj = SOAPStruct.new(type_qname) + mark_marshalled_obj(obj, soap_obj) + elements2soap(obj, soap_obj, type.content.elements) + soap_obj + end + + def array2soap(obj, type_qname, type) + arytype = type.child_type + soap_obj = SOAPArray.new(ValueArrayName, 1, arytype) + mark_marshalled_obj(obj, soap_obj) + obj.each do |item| + soap_obj.add(Mapping._obj2soap(item, self, arytype)) + end + soap_obj + end + + MapKeyName = XSD::QName.new(nil, "key") + MapValueName = XSD::QName.new(nil, "value") + def map2soap(obj, type_qname, type) + keytype = type.child_type(MapKeyName) || XSD::AnyTypeName + valuetype = type.child_type(MapValueName) || XSD::AnyTypeName + soap_obj = SOAPStruct.new(MapQName) + mark_marshalled_obj(obj, soap_obj) + obj.each do |key, value| + elem = SOAPStruct.new + elem.add("key", Mapping._obj2soap(key, self, keytype)) + elem.add("value", Mapping._obj2soap(value, self, valuetype)) + # ApacheAxis allows only 'item' here. + soap_obj.add("item", elem) + end + soap_obj + end + + def elements2soap(obj, soap_obj, elements) + elements.each do |element| + name = element.name.name + child_obj = obj.instance_eval("@#{ name }") + soap_obj.add(name, Mapping._obj2soap(child_obj, self, element.type)) + end + end +end + + +end +end diff --git a/lib/soap/mapping/wsdlliteralregistry.rb b/lib/soap/mapping/wsdlliteralregistry.rb new file mode 100644 index 0000000000..c190c9d904 --- /dev/null +++ b/lib/soap/mapping/wsdlliteralregistry.rb @@ -0,0 +1,281 @@ +# SOAP4R - WSDL literal mapping registry. +# Copyright (C) 2004 NAKAMURA, Hiroshi . + +# 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/baseData' +require 'soap/mapping/mapping' +require 'soap/mapping/typeMap' +require 'xsd/codegen/gensupport' + + +module SOAP +module Mapping + + +class WSDLLiteralRegistry + attr_reader :definedelements + attr_reader :definedtypes + attr_accessor :excn_handler_obj2soap + attr_accessor :excn_handler_soap2obj + + def initialize(definedelements = nil, definedtypes = nil) + @definedelements = definedelements + @definedtypes = definedtypes + @rubytype_factory = RubytypeFactory.new(:allow_original_mapping => false) + @schema_element_cache = {} + end + + def obj2soap(obj, qname) + ret = nil + if !@definedelements.nil? && ele = @definedelements[qname] + ret = _obj2soap(obj, ele) + elsif !@definedtypes.nil? && type = @definedtypes[qname] + ret = obj2type(obj, type) + else + ret = unknownobj2soap(obj, qname) + end + return ret if ret + if @excn_handler_obj2soap + ret = @excn_handler_obj2soap.call(obj) { |yield_obj| + Mapping._obj2soap(yield_obj, self) + } + return ret if ret + end + raise MappingError.new("Cannot map #{ obj.class.name } to SOAP/OM.") + end + + # node should be a SOAPElement + def soap2obj(node) + begin + return soapele2obj(node) + rescue MappingError + end + if @excn_handler_soap2obj + begin + return @excn_handler_soap2obj.call(node) { |yield_node| + Mapping._soap2obj(yield_node, self) + } + rescue Exception + end + end + raise MappingError.new("Cannot map #{ node.type.name } to Ruby object.") + end + +private + + def _obj2soap(obj, ele) + o = nil + if ele.type + if type = @definedtypes[ele.type] + o = obj2type(obj, type) + elsif type = TypeMap[ele.type] + o = base2soap(obj, type) + else + raise MappingError.new("Cannot find type #{ele.type}.") + end + o.elename = ele.name + elsif ele.local_complextype + o = SOAPElement.new(ele.name) + ele.local_complextype.each_element do |child_ele| + o.add(_obj2soap(Mapping.find_attribute(obj, child_ele.name.name), + child_ele)) + end + else + raise MappingError.new('Illegal schema?') + end + o + end + + def obj2type(obj, type) + if type.is_a?(::WSDL::XMLSchema::SimpleType) + simple2soap(obj, type) + else + complex2soap(obj, type) + end + end + + def simple2soap(obj, type) + o = base2soap(obj, TypeMap[type.base]) + if type.restriction.enumeration.empty? + STDERR.puts( + "#{type.name}: simpleType which is not enum type not supported.") + return o + end + type.check_lexical_format(obj) + o + end + + def complex2soap(obj, type) + o = SOAPElement.new(type.name) + type.each_element do |child_ele| + o.add(_obj2soap(Mapping.find_attribute(obj, child_ele.name.name), + child_ele)) + end + o + end + + def unknownobj2soap(obj, name) + if obj.class.class_variables.include?('@@schema_element') + ele = SOAPElement.new(name) + add_elements2soap(obj, ele) + add_attributes2soap(obj, ele) + ele + elsif obj.is_a?(Hash) + ele = SOAPElement.from_obj(obj) + ele.elename = name + ele + else # expected to be a basetype or an anyType. + o = Mapping.obj2soap(obj) + o.elename = name + o + end + end + + def add_elements2soap(obj, ele) + elements, as_array = schema_element_definition(obj.class) + elements.each do |elename, type| + child = Mapping.find_attribute(obj, elename) + name = ::XSD::QName.new(nil, elename) + if as_array.include?(type) + child.each do |item| + ele.add(obj2soap(item, name)) + end + else + ele.add(obj2soap(child, name)) + end + end + end + + def add_attributes2soap(obj, ele) + attributes = schema_attribute_definition(obj.class) + attributes.each do |attrname, param| + attr = Mapping.find_attribute(obj, 'attr_' + attrname) + ele.extraattr[attrname] = attr + end + end + + def base2soap(obj, type) + soap_obj = nil + if type <= ::XSD::XSDString + soap_obj = type.new(::XSD::Charset.is_ces(obj, $KCODE) ? + ::XSD::Charset.encoding_conv(obj, $KCODE, ::XSD::Charset.encoding) : + obj) + else + soap_obj = type.new(obj) + end + soap_obj + end + + def anytype2obj(node) + if node.is_a?(::SOAP::SOAPBasetype) + return node.data + end + klass = ::SOAP::Mapping::Object + obj = klass.new + node.each do |name, value| + obj.__soap_set_property(name, Mapping.soap2obj(value)) + end + obj + end + + def soapele2obj(node, obj_class = nil) + unless obj_class + typestr = ::XSD::CodeGen::GenSupport.safeconstname(node.elename.name) + obj_class = Mapping.class_from_name(typestr) + end + if obj_class and obj_class.class_variables.include?('@@schema_element') + soapele2definedobj(node, obj_class) + elsif node.is_a?(SOAPElement) + node.to_obj + else + result, obj = @rubytype_factory.soap2obj(nil, node, nil, self) + obj + end + end + + def soapele2definedobj(node, obj_class) + obj = Mapping.create_empty_object(obj_class) + add_elements2obj(node, obj) + add_attributes2obj(node, obj) + obj + end + + def add_elements2obj(node, obj) + elements, as_array = schema_element_definition(obj.class) + vars = {} + node.each do |name, value| + if class_name = elements[name] + if klass = Mapping.class_from_name(class_name) + if klass.ancestors.include?(::SOAP::SOAPBasetype) + if value.respond_to?(:data) + child = klass.new(value.data).data + else + child = klass.new(nil).data + end + else + child = soapele2obj(value, klass) + end + else + raise MappingError.new("Unknown class: #{class_name}") + end + else # untyped element is treated as anyType. + child = anytype2obj(value) + end + if as_array.include?(class_name) + (vars[name] ||= []) << child + else + vars[name] = child + end + end + Mapping.set_instance_vars(obj, vars) + end + + def add_attributes2obj(node, obj) + Mapping.set_instance_vars(obj, {'__soap_attribute' => {}}) + vars = {} + attributes = schema_attribute_definition(obj.class) + attributes.each do |attrname, class_name| + attr = node.extraattr[::XSD::QName.new(nil, attrname)] + next if attr.nil? or attr.empty? + klass = Mapping.class_from_name(class_name) + if klass.ancestors.include?(::SOAP::SOAPBasetype) + child = klass.new(attr).data + else + child = attr + end + vars['attr_' + attrname] = child + end + Mapping.set_instance_vars(obj, vars) + end + + # it caches @@schema_element. this means that @@schema_element must not be + # changed while a lifetime of a WSDLLiteralRegistry. + def schema_element_definition(klass) + if @schema_element_cache.key?(klass) + return @schema_element_cache[klass] + end + elements = {} + as_array = [] + klass.class_eval('@@schema_element').each do |name, class_name| + if /\[\]$/ =~ class_name + class_name = class_name.sub(/\[\]$/, '') + as_array << class_name + end + elements[name] = class_name + end + @schema_element_cache[klass] = [elements, as_array] + return @schema_element_cache[klass] + end + + def schema_attribute_definition(klass) + attributes = klass.class_eval('@@schema_attribute') + end +end + + +end +end diff --git a/lib/wsdl/soap/element.rb b/lib/wsdl/soap/element.rb new file mode 100644 index 0000000000..c39a00d25a --- /dev/null +++ b/lib/wsdl/soap/element.rb @@ -0,0 +1,34 @@ +# WSDL4R - XMLSchema element definition for WSDL. +# Copyright (C) 2004 NAKAMURA, Hiroshi . + +# 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/xmlSchema/element' + + +module WSDL +module XMLSchema + + +class Element < Info + def map_as_array? + maxoccurs != '1' + end + + def attributes + @local_complextype.attributes + end + + def each_element + @local_complextype.each_element do |element| + yield(element) + end + end +end + + +end +end diff --git a/lib/wsdl/xmlSchema/simpleContent.rb b/lib/wsdl/xmlSchema/simpleContent.rb new file mode 100644 index 0000000000..0d83678a01 --- /dev/null +++ b/lib/wsdl/xmlSchema/simpleContent.rb @@ -0,0 +1,65 @@ +# WSDL4R - XMLSchema simpleContent definition for WSDL. +# Copyright (C) 2004 NAKAMURA, Hiroshi . + +# 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 SimpleContent < Info + attr_accessor :base + attr_reader :derivetype + attr_reader :content + attr_reader :attributes + + def initialize + super + @base = nil + @derivetype = nil + @content = nil + @attributes = XSD::NamedElements.new + end + + def targetnamespace + parent.targetnamespace + end + + def parse_element(element) + case element + when RestrictionName, ExtensionName + @derivetype = element.name + self + when AttributeName + if @derivetype.nil? + raise Parser::ElementConstraintError.new("base attr not found.") + end + o = Attribute.new + @attributes << o + o + end + end + + def parse_attr(attr, value) + if @derivetype.nil? + return nil + end + case attr + when BaseAttrName + @base = value + else + nil + end + end +end + + +end +end diff --git a/sample/optparse/subcommand.rb b/sample/optparse/subcommand.rb new file mode 100755 index 0000000000..21c42dd60a --- /dev/null +++ b/sample/optparse/subcommand.rb @@ -0,0 +1,19 @@ +#! /usr/bin/ruby +# contributed by Minero Aoki. + +require 'optparse' + +parser = OptionParser.new +parser.on('-i') { puts "-i" } +parser.on('-o') { puts '-o' } + +subparsers = Hash.new {|h,k| + $stderr.puts "no such subcommand: #{k}" + exit 1 +} +subparsers['add'] = OptionParser.new.on('-i') { puts "add -i" } +subparsers['del'] = OptionParser.new.on('-i') { puts "del -i" } +subparsers['list'] = OptionParser.new.on('-i') { puts "list -i" } + +parser.order!(ARGV) +subparsers[ARGV.shift].parse!(ARGV) unless ARGV.empty? diff --git a/sample/soap/helloworld/hw_c_gzip.rb b/sample/soap/helloworld/hw_c_gzip.rb new file mode 100644 index 0000000000..3335b5f571 --- /dev/null +++ b/sample/soap/helloworld/hw_c_gzip.rb @@ -0,0 +1,8 @@ +require 'soap/rpc/driver' + +s = SOAP::RPC::Driver.new('http://localhost:2000/', 'urn:hws') +s.add_method("hello_world", "from") +#s.wiredump_dev = STDOUT # care about binary output. +s.streamhandler.accept_encoding_gzip = true + +p s.hello_world(self.to_s) diff --git a/sample/soap/helloworld/hw_s_gzip.rb b/sample/soap/helloworld/hw_s_gzip.rb new file mode 100644 index 0000000000..d124df0e04 --- /dev/null +++ b/sample/soap/helloworld/hw_s_gzip.rb @@ -0,0 +1,21 @@ +require 'soap/rpc/standaloneServer' + +class HelloWorldServer < SOAP::RPC::StandaloneServer + def on_init + @soaplet.allow_content_encoding_gzip = true + @log.level = Logger::Severity::DEBUG + add_method(self, 'hello_world', 'from') + end + + def hello_world(from) + "Hello World, from #{ from }" + end +end + +if $0 == __FILE__ + server = HelloWorldServer.new('hws', 'urn:hws', '0.0.0.0', 2000) + trap(:INT) do + server.shutdown + end + server.start +end diff --git a/sample/soap/scopesample/client.rb b/sample/soap/scopesample/client.rb new file mode 100644 index 0000000000..009fdf1919 --- /dev/null +++ b/sample/soap/scopesample/client.rb @@ -0,0 +1,34 @@ +require 'soap/rpc/driver' + +server = ARGV.shift || 'http://localhost:7000/' +# server = 'http://localhost:8808/server.cgi' + +# client which accesses application scope servant. +app = SOAP::RPC::Driver.new(server, + 'http://tempuri.org/applicationScopeService') +app.add_method('push', 'value') +app.add_method('pop') + +# client which accesses request scope servant must send SOAPAction to identify +# the service. +req = SOAP::RPC::Driver.new(server, + 'http://tempuri.org/requestScopeService') +req.add_method_with_soapaction('push', + 'http://tempuri.org/requestScopeService', 'value') +req.add_method_with_soapaction('pop', + 'http://tempuri.org/requestScopeService') + +# exec +app.push(1) +app.push(2) +app.push(3) +p app.pop +p app.pop +p app.pop + +req.push(1) +req.push(2) +req.push(3) +p req.pop +p req.pop +p req.pop diff --git a/sample/soap/scopesample/httpd.rb b/sample/soap/scopesample/httpd.rb new file mode 100644 index 0000000000..5f58c7e14a --- /dev/null +++ b/sample/soap/scopesample/httpd.rb @@ -0,0 +1,22 @@ +#!/usr/bin/env ruby + +require 'webrick' +require 'soap/property' + +docroot = "." +port = 8808 +if opt = SOAP::Property.loadproperty("samplehttpd.conf") + docroot = opt["docroot"] + port = Integer(opt["port"]) +end + +s = WEBrick::HTTPServer.new( + :BindAddress => "0.0.0.0", + :Port => port, + :DocumentRoot => docroot, + :CGIPathEnv => ENV['PATH'] +) +trap(:INT) do + s.shutdown +end +s.start diff --git a/sample/soap/scopesample/samplehttpd.conf b/sample/soap/scopesample/samplehttpd.conf new file mode 100644 index 0000000000..85e9995021 --- /dev/null +++ b/sample/soap/scopesample/samplehttpd.conf @@ -0,0 +1,2 @@ +docroot = . +port = 8808 diff --git a/sample/soap/scopesample/servant.rb b/sample/soap/scopesample/servant.rb new file mode 100644 index 0000000000..5076050076 --- /dev/null +++ b/sample/soap/scopesample/servant.rb @@ -0,0 +1,18 @@ +class Servant + def self.create + new + end + + def initialize + STDERR.puts "Servant created." + @task = [] + end + + def push(value) + @task.push(value) + end + + def pop + @task.pop + end +end diff --git a/sample/soap/scopesample/server.cgi b/sample/soap/scopesample/server.cgi new file mode 100755 index 0000000000..ebe13eb131 --- /dev/null +++ b/sample/soap/scopesample/server.cgi @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby + +require 'soap/rpc/cgistub' +require 'servant' + +class Server < SOAP::RPC::CGIStub + class DummyServant + def push(value) + "Not supported" + end + + def pop + "Not supported" + end + end + + def initialize(*arg) + super + add_rpc_servant(Servant.new, 'http://tempuri.org/requestScopeService') + + # Application scope servant is not supported in CGI environment. + # See server.rb to support application scope servant. + dummy = DummyServant.new + add_method_with_namespace('http://tempuri.org/applicationScopeService', dummy, 'push', 'value') + add_method_with_namespace('http://tempuri.org/applicationScopeService', dummy, 'pop') + end +end + +status = Server.new('Server', nil).start diff --git a/sample/soap/scopesample/server.rb b/sample/soap/scopesample/server.rb new file mode 100644 index 0000000000..6b87b74c2f --- /dev/null +++ b/sample/soap/scopesample/server.rb @@ -0,0 +1,20 @@ +#!/usr/bin/env ruby + +require 'soap/rpc/standaloneServer' +require 'servant' + +class Server < SOAP::RPC::StandaloneServer + def initialize(*arg) + super + add_rpc_servant(Servant.new, 'http://tempuri.org/applicationScopeService') + add_rpc_request_servant(Servant, 'http://tempuri.org/requestScopeService') + end +end + +if $0 == __FILE__ + server = Server.new('Server', nil, '0.0.0.0', 7000) + trap(:INT) do + server.shutdown + end + server.start +end diff --git a/test/ruby/test_super.rb b/test/ruby/test_super.rb new file mode 100644 index 0000000000..df229a8f1a --- /dev/null +++ b/test/ruby/test_super.rb @@ -0,0 +1,88 @@ +require 'test/unit' + +class TestSuper < Test::Unit::TestCase + class Base + def single(a) a end + def double(a, b) [a,b] end + def array(*a) a end + end + class Single1 < Base + def single(*) super end + end + class Single2 < Base + def single(a,*) super end + end + class Double1 < Base + def double(*) super end + end + class Double2 < Base + def double(a,*) super end + end + class Double3 < Base + def double(a,b,*) super end + end + class Array1 < Base + def array(*) super end + end + class Array2 < Base + def array(a,*) super end + end + class Array3 < Base + def array(a,b,*) super end + end + class Array4 < Base + def array(a,b,c,*) super end + end + + def test_single1 + assert_equal(1, Single1.new.single(1)) + end + def test_single2 + assert_equal(1, Single2.new.single(1)) + end + def test_double1 + assert_equal([1, 2], Double1.new.double(1, 2)) + end + def test_double2 + assert_equal([1, 2], Double2.new.double(1, 2)) + end + def test_double3 + assert_equal([1, 2], Double3.new.double(1, 2)) + end + def test_array1 + assert_equal([], Array1.new.array()) + assert_equal([1], Array1.new.array(1)) + end + def test_array2 + assert_equal([1], Array2.new.array(1)) + assert_equal([1,2], Array2.new.array(1, 2)) + end + def test_array3 + assert_equal([1,2], Array3.new.array(1, 2)) + assert_equal([1,2,3], Array3.new.array(1, 2, 3)) + end + def test_array4 + assert_equal([1,2,3], Array4.new.array(1, 2, 3)) + assert_equal([1,2,3,4], Array4.new.array(1, 2, 3, 4)) + end + + class A + def tt(aa) + "A#tt" + end + + def uu(a) + class << self + define_method(:tt) do |sym| + super + end + end + end + end + + def test_define_method # [ruby-core:03856] + a = A.new + a.uu(12) + assert_equal("A#tt", a.tt(12)) + end +end -- cgit v1.2.3