summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/net/https.rb171
-rw-r--r--lib/soap/mapping/wsdlencodedregistry.rb173
-rw-r--r--lib/soap/mapping/wsdlliteralregistry.rb281
-rw-r--r--lib/wsdl/soap/element.rb34
-rw-r--r--lib/wsdl/xmlSchema/simpleContent.rb65
-rwxr-xr-xsample/optparse/subcommand.rb19
-rw-r--r--sample/soap/helloworld/hw_c_gzip.rb8
-rw-r--r--sample/soap/helloworld/hw_s_gzip.rb21
-rw-r--r--sample/soap/scopesample/client.rb34
-rw-r--r--sample/soap/scopesample/httpd.rb22
-rw-r--r--sample/soap/scopesample/samplehttpd.conf2
-rw-r--r--sample/soap/scopesample/servant.rb18
-rwxr-xr-xsample/soap/scopesample/server.cgi29
-rw-r--r--sample/soap/scopesample/server.rb20
-rw-r--r--test/ruby/test_super.rb88
15 files changed, 985 insertions, 0 deletions
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 <gotoyuzo@notwork.org>
+ 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 <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/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 <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/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 <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/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 <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 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