diff options
author | nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-12-20 13:50:15 +0000 |
---|---|---|
committer | nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-12-20 13:50:15 +0000 |
commit | e5a3aba50e2bd7e0327aacd8fe1ab7963fc4a007 (patch) | |
tree | b56a6e784df74331c28e4a94901b96837f214e35 /lib/soap/rpc/soaplet.rb | |
parent | 643dc132113489749c333a6bda14730d9b175ed1 (diff) |
* added files:
* lib/soap/mapping/wsdl*.rb
* lib/wsdl/soap/element.rb
* lib/wsdl/xmlSchema/simpleContent.rb
* modified files:
* lib/soap/*
* lib/wsdl/*
* lib/xsd/*
* test/soap/*
* test/wsdl/*
* test/xsd/*
* summary
* imported from the soap4r repository. Version: 1.5.3-ruby1.8.2
* added several XSD basetype support: nonPositiveInteger,
negativeInteger, nonNegativeInteger, unsignedLong, unsignedInt,
unsignedShort, unsignedByte, positiveInteger
* HTTP client connection/send/receive timeout support.
* HTTP client/server gzipped content encoding support.
* improved WSDL schema definition support; still is far from
complete, but is making step by step improovement.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7612 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/soap/rpc/soaplet.rb')
-rw-r--r-- | lib/soap/rpc/soaplet.rb | 92 |
1 files changed, 72 insertions, 20 deletions
diff --git a/lib/soap/rpc/soaplet.rb b/lib/soap/rpc/soaplet.rb index 0c1427acf5..8f18c53d3a 100644 --- a/lib/soap/rpc/soaplet.rb +++ b/lib/soap/rpc/soaplet.rb @@ -10,6 +10,13 @@ require 'webrick/httpservlet/abstract' require 'webrick/httpstatus' require 'soap/rpc/router' require 'soap/streamHandler' +begin + require 'stringio' + require 'zlib' +rescue LoadError + STDERR.puts "Loading stringio or zlib failed. No gzipped response support." if $DEBUG +end + module SOAP module RPC @@ -18,12 +25,18 @@ module RPC class SOAPlet < WEBrick::HTTPServlet::AbstractServlet public attr_reader :app_scope_router + attr_reader :options def initialize - @router_map = {} + @rpc_router_map = {} @app_scope_router = ::SOAP::RPC::Router.new(self.class.name) @headerhandlerfactory = [] @app_scope_headerhandler = nil + @options = {} + end + + def allow_content_encoding_gzip=(allow) + @options[:allow_content_encoding_gzip] = allow end # Add servant factory whose object has request scope. A servant object is @@ -41,7 +54,7 @@ public unless factory.respond_to?(:create) raise TypeError.new("factory must respond to 'create'") end - router = setup_request_router(namespace) + router = setup_rpc_request_router(namespace) router.factory = factory router.mapping_registry = mapping_registry end @@ -49,8 +62,8 @@ public # Add servant object which has application scope. def add_rpc_servant(obj, namespace) router = @app_scope_router - SOAPlet.add_servant_to_router(router, obj, namespace) - add_router(namespace, router) + SOAPlet.add_rpc_servant_to_router(router, obj, namespace) + add_rpc_router(namespace, router) end alias add_servant add_rpc_servant @@ -84,19 +97,26 @@ public end def do_POST(req, res) - namespace = parse_soapaction(req.meta_vars['HTTP_SOAPACTION']) - router = lookup_router(namespace) + @config[:Logger].debug { "SOAP request: " + req.body } + soapaction = parse_soapaction(req.meta_vars['HTTP_SOAPACTION']) + router = lookup_router(soapaction) with_headerhandler(router) do |router| begin conn_data = ::SOAP::StreamHandler::ConnectionData.new conn_data.receive_string = req.body conn_data.receive_contenttype = req['content-type'] conn_data = router.route(conn_data) + res['content-type'] = conn_data.send_contenttype if conn_data.is_fault res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR end - res.body = conn_data.send_string - res['content-type'] = conn_data.send_contenttype + if outstring = encode_gzip(req, conn_data.send_string) + res['content-encoding'] = 'gzip' + res['content-length'] = outstring.size + res.body = outstring + else + res.body = conn_data.send_string + end rescue Exception => e conn_data = router.create_fault_response(e) res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR @@ -107,6 +127,9 @@ public if res.body.is_a?(IO) res.chunked = true + @config[:Logger].debug { "SOAP response: (chunked response not logged)" } + else + @config[:Logger].debug { "SOAP response: " + res.body } end end @@ -115,8 +138,9 @@ private class RequestRouter < ::SOAP::RPC::Router attr_accessor :factory - def initialize(namespace = nil) + def initialize(style = :rpc, namespace = nil) super(namespace) + @style = style @namespace = namespace @factory = nil end @@ -125,19 +149,23 @@ private obj = @factory.create namespace = self.actor router = ::SOAP::RPC::Router.new(@namespace) - SOAPlet.add_servant_to_router(router, obj, namespace) + if @style == :rpc + SOAPlet.add_rpc_servant_to_router(router, obj, namespace) + else + raise RuntimeError.new("'document' style not supported.") + end router.route(soap_string) end end - def setup_request_router(namespace) - router = @router_map[namespace] || RequestRouter.new(namespace) - add_router(namespace, router) + def setup_rpc_request_router(namespace) + router = @rpc_router_map[namespace] || RequestRouter.new(:rpc, namespace) + add_rpc_router(namespace, router) router end - def add_router(namespace, router) - @router_map[namespace] = router + def add_rpc_router(namespace, router) + @rpc_router_map[namespace] = router end def parse_soapaction(soapaction) @@ -152,7 +180,7 @@ private def lookup_router(namespace) if namespace - @router_map[namespace] || @app_scope_router + @rpc_router_map[namespace] || @app_scope_router else @app_scope_router end @@ -172,25 +200,49 @@ private end end + def encode_gzip(req, outstring) + unless encode_gzip?(req) + return nil + end + begin + ostream = StringIO.new + gz = Zlib::GzipWriter.new(ostream) + gz.write(outstring) + ostream.string + ensure + gz.close + end + end + + def encode_gzip?(req) + @options[:allow_content_encoding_gzip] and defined?(::Zlib) and + req['accept-encoding'] and + req['accept-encoding'].split(/,\s*/).include?('gzip') + end + class << self public - def add_servant_to_router(router, obj, namespace) + def add_rpc_servant_to_router(router, obj, namespace) ::SOAP::RPC.defined_methods(obj).each do |name| begin - add_servant_method_to_router(router, obj, namespace, name) + add_rpc_servant_method_to_router(router, obj, namespace, name) rescue SOAP::RPC::MethodDefinitionError => e p e if $DEBUG end end end - def add_servant_method_to_router(router, obj, namespace, name) + def add_rpc_servant_method_to_router(router, obj, namespace, name, + style = :rpc, use = :encoded) qname = XSD::QName.new(namespace, name) soapaction = nil method = obj.method(name) param_def = ::SOAP::RPC::SOAPMethod.create_param_def( (1..method.arity.abs).collect { |i| "p#{ i }" }) - router.add_method(obj, qname, soapaction, name, param_def) + opt = {} + opt[:request_style] = opt[:response_style] = style + opt[:request_use] = opt[:response_use] = use + router.add_operation(qname, soapaction, obj, name, param_def, opt) end end end |