actionwebservice 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +33 -0
- data/README +25 -6
- data/Rakefile +7 -7
- data/TODO +27 -6
- data/lib/action_web_service.rb +1 -0
- data/lib/action_web_service/api.rb +8 -11
- data/lib/action_web_service/casting.rb +8 -1
- data/lib/action_web_service/client/soap_client.rb +7 -8
- data/lib/action_web_service/container/action_controller_container.rb +8 -8
- data/lib/action_web_service/container/delegated_container.rb +1 -1
- data/lib/action_web_service/dispatcher/abstract.rb +13 -7
- data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +41 -41
- data/lib/action_web_service/protocol/abstract.rb +5 -2
- data/lib/action_web_service/protocol/discovery.rb +2 -2
- data/lib/action_web_service/protocol/soap_protocol.rb +35 -9
- data/lib/action_web_service/protocol/soap_protocol/marshaler.rb +54 -14
- data/lib/action_web_service/protocol/xmlrpc_protocol.rb +11 -3
- data/lib/action_web_service/scaffolding.rb +68 -40
- data/lib/action_web_service/support/signature_types.rb +39 -11
- data/lib/action_web_service/templates/scaffolds/layout.rhtml +1 -1
- data/lib/action_web_service/templates/scaffolds/parameters.rhtml +4 -2
- data/lib/action_web_service/test_invoke.rb +4 -7
- data/test/abstract_dispatcher.rb +52 -13
- data/test/api_test.rb +2 -2
- data/test/casting_test.rb +6 -2
- data/test/dispatcher_action_controller_soap_test.rb +24 -9
- data/test/dispatcher_action_controller_xmlrpc_test.rb +1 -1
- data/test/invocation_test.rb +1 -1
- data/test/scaffolded_controller_test.rb +1 -1
- data/test/test_invoke_test.rb +11 -9
- metadata +6 -6
    
        data/CHANGELOG
    CHANGED
    
    | @@ -1,3 +1,36 @@ | |
| 1 | 
            +
            *0.8.0* (6 July, 2005)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * Fix WSDL generation by aliasing #inherited instead of trying to overwrite it, or the WSDL action may end up not being defined in the controller
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Add ActionController::Base.wsdl_namespace option, to allow overriding of the namespace used in generated WSDL and SOAP messages. This is equivalent to the [WebService(Namespace = "Value")] attribute in .NET.
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * Add workaround for Ruby 1.8.3's SOAP4R changing the return value of SOAP::Mapping::Registry#find_mapped_soap_class #1414 [Shugo Maeda]
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            * Fix moduled controller URLs in WSDL, and add unit test to verify the generated URL #1428
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            * Fix scaffolding template paths, it was broken on Win32
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            * Fix that functional testing of :layered controllers failed when using the SOAP protocol
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            * Allow invocation filters in :direct controllers as well, as they have access to more information regarding the web service request than ActionPack filters
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            * Add support for a :base64 signature type #1272 [Shugo Maeda]
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            * Fix that boolean fields were not rendered correctly in scaffolding
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            * Fix that scaffolding was not working for :delegated dispatching
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            * Add support for structured types as input parameters to scaffolding, this should let one test the blogging APIs using scaffolding as well
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            * Fix that generated WSDL was not using relative_url_root for base URI #1210 [Shugo Maeda]
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            * Use UTF-8 encoding by default for SOAP responses, but if an encoding is supplied by caller, use that for the response  #1211 [Shugo Maeda, NAKAMURA Hiroshi]
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            * If the WSDL was retrieved over HTTPS, use HTTPS URLs in the WSDL too
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            * Fix that casting change in 0.7.0 would convert nil values to the default value for the type instead of leaving it as nil
         | 
| 32 | 
            +
             | 
| 33 | 
            +
             | 
| 1 34 | 
             
            *0.7.1* (20th April, 2005)
         | 
| 2 35 |  | 
| 3 36 | 
             
            * Depend on Active Record 1.10.1 and Action Pack 1.8.1
         | 
    
        data/README
    CHANGED
    
    | @@ -78,15 +78,15 @@ modes of dispatching protocol requests, _Direct_, and _Delegated_. | |
| 78 78 |  | 
| 79 79 | 
             
            === Direct dispatching
         | 
| 80 80 |  | 
| 81 | 
            -
            This is the default mode. In this mode, controller  | 
| 82 | 
            -
            methods, and parameters  | 
| 83 | 
            -
             | 
| 81 | 
            +
            This is the default mode. In this mode, public controller instance methods
         | 
| 82 | 
            +
            implement the API methods, and parameters are passed through to the methods in
         | 
| 83 | 
            +
            accordance with the API specification.
         | 
| 84 84 |  | 
| 85 | 
            -
            The return value of the  | 
| 85 | 
            +
            The return value of the method is sent back as the return value to the
         | 
| 86 86 | 
             
            caller.
         | 
| 87 87 |  | 
| 88 88 | 
             
            In this mode, a special <tt>api</tt> action is generated in the target
         | 
| 89 | 
            -
            controller to unwrap the protocol request, forward it on to the relevant  | 
| 89 | 
            +
            controller to unwrap the protocol request, forward it on to the relevant method
         | 
| 90 90 | 
             
            and send back the wrapped return value. <em>This action must not be
         | 
| 91 91 | 
             
            overridden.</em>
         | 
| 92 92 |  | 
| @@ -108,7 +108,7 @@ overridden.</em> | |
| 108 108 |  | 
| 109 109 |  | 
| 110 110 | 
             
            For this example, protocol requests for +Add+ and +Remove+ methods sent to
         | 
| 111 | 
            -
            <tt>/person/api</tt> will be routed to the  | 
| 111 | 
            +
            <tt>/person/api</tt> will be routed to the controller methods +add+ and +remove+.
         | 
| 112 112 |  | 
| 113 113 |  | 
| 114 114 | 
             
            === Delegated dispatching
         | 
| @@ -196,6 +196,25 @@ For this example, an XML-RPC call for a method with a name like | |
| 196 196 | 
             
            method on the <tt>:mt</tt> service.
         | 
| 197 197 |  | 
| 198 198 |  | 
| 199 | 
            +
            == Customizing WSDL generation
         | 
| 200 | 
            +
             | 
| 201 | 
            +
            You can customize the names used for the SOAP bindings in the generated
         | 
| 202 | 
            +
            WSDL by using the wsdl_service_name option in a controller:
         | 
| 203 | 
            +
             | 
| 204 | 
            +
              class WsController < ApplicationController
         | 
| 205 | 
            +
                wsdl_service_name 'MyApp'
         | 
| 206 | 
            +
              end
         | 
| 207 | 
            +
             | 
| 208 | 
            +
            You can also customize the namespace used in the generated WSDL for
         | 
| 209 | 
            +
            custom types and message definition types:
         | 
| 210 | 
            +
             | 
| 211 | 
            +
              class WsController < ApplicationController
         | 
| 212 | 
            +
                wsdl_namespace 'http://my.company.com/app/wsapi'
         | 
| 213 | 
            +
              end
         | 
| 214 | 
            +
             | 
| 215 | 
            +
            The default namespace used is 'urn:ActionWebService', if you don't supply
         | 
| 216 | 
            +
            one.
         | 
| 217 | 
            +
             | 
| 199 218 | 
             
            == Testing your APIs
         | 
| 200 219 |  | 
| 201 220 |  | 
    
        data/Rakefile
    CHANGED
    
    | @@ -9,7 +9,7 @@ require 'fileutils' | |
| 9 9 |  | 
| 10 10 | 
             
            PKG_BUILD     = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
         | 
| 11 11 | 
             
            PKG_NAME      = 'actionwebservice'
         | 
| 12 | 
            -
            PKG_VERSION   = '0. | 
| 12 | 
            +
            PKG_VERSION   = '0.8.0' + PKG_BUILD
         | 
| 13 13 | 
             
            PKG_FILE_NAME   = "#{PKG_NAME}-#{PKG_VERSION}"
         | 
| 14 14 | 
             
            PKG_DESTINATION = ENV["RAILS_PKG_DESTINATION"] || "../#{PKG_NAME}"
         | 
| 15 15 |  | 
| @@ -62,9 +62,9 @@ spec = Gem::Specification.new do |s| | |
| 62 62 | 
             
              s.rubyforge_project = "aws"
         | 
| 63 63 | 
             
              s.homepage = "http://www.rubyonrails.org"
         | 
| 64 64 |  | 
| 65 | 
            -
              s.add_dependency('actionpack', '= 1. | 
| 66 | 
            -
              s.add_dependency('activerecord', '= 1. | 
| 67 | 
            -
              s.add_dependency('activesupport', '= 1.0 | 
| 65 | 
            +
              s.add_dependency('actionpack', '= 1.9.0' + PKG_BUILD)
         | 
| 66 | 
            +
              s.add_dependency('activerecord', '= 1.11.0' + PKG_BUILD)
         | 
| 67 | 
            +
              s.add_dependency('activesupport', '= 1.1.0' + PKG_BUILD)
         | 
| 68 68 |  | 
| 69 69 | 
             
              s.has_rdoc = true
         | 
| 70 70 | 
             
              s.requirements << 'none'
         | 
| @@ -86,14 +86,14 @@ end | |
| 86 86 | 
             
            # Publish beta gem
         | 
| 87 87 | 
             
            desc "Publish the API documentation"
         | 
| 88 88 | 
             
            task :pgem => [:package] do 
         | 
| 89 | 
            -
              Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails. | 
| 90 | 
            -
              `ssh davidhh@wrath.rubyonrails. | 
| 89 | 
            +
              Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
         | 
| 90 | 
            +
              `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
         | 
| 91 91 | 
             
            end
         | 
| 92 92 |  | 
| 93 93 | 
             
            # Publish documentation
         | 
| 94 94 | 
             
            desc "Publish the API documentation"
         | 
| 95 95 | 
             
            task :pdoc => [:rdoc] do 
         | 
| 96 | 
            -
              Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails. | 
| 96 | 
            +
              Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.org", "public_html/aws", "doc").upload
         | 
| 97 97 | 
             
            end
         | 
| 98 98 |  | 
| 99 99 |  | 
    
        data/TODO
    CHANGED
    
    | @@ -1,10 +1,31 @@ | |
| 1 | 
            -
            =  | 
| 2 | 
            -
              -  | 
| 3 | 
            -
                 | 
| 4 | 
            -
                currently fudge it if we don't know the protocol.
         | 
| 1 | 
            +
            = Post-1.0
         | 
| 2 | 
            +
              - Document/Literal SOAP support
         | 
| 3 | 
            +
                - URL-based dispatching, URL identifies method
         | 
| 5 4 |  | 
| 6 | 
            -
              -  | 
| 7 | 
            -
                 | 
| 5 | 
            +
              - Add :rest dispatching mode, a.l.a. Backpack API. Clean up dispatching
         | 
| 6 | 
            +
                in general. Support vanilla XML-format as a "Rails" protocol?
         | 
| 7 | 
            +
                XML::Simple deserialization into params?
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  web_service_dispatching_mode :rest
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def method1(params)
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def method2(params)
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
             | 
| 18 | 
            +
                  /ws/method1
         | 
| 19 | 
            +
                    <xml>
         | 
| 20 | 
            +
                  /ws/method2
         | 
| 21 | 
            +
                    <yaml>
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              - Allow locking down a controller to only accept messages for a particular
         | 
| 24 | 
            +
                protocol.  This will allow us to generate fully conformant error messages
         | 
| 25 | 
            +
                in cases where we currently fudge it if we don't know the protocol.
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              - Allow AWS user to participate in typecasting, so they can centralize
         | 
| 28 | 
            +
                workarounds for buggy input in one place
         | 
| 8 29 |  | 
| 9 30 | 
             
            = Refactoring
         | 
| 10 31 | 
             
              - Don't have clean way to go from SOAP Class object to the xsd:NAME type
         | 
    
        data/lib/action_web_service.rb
    CHANGED
    
    | @@ -59,6 +59,7 @@ ActionController::Base.class_eval do | |
| 59 59 | 
             
              include ActionWebService::Container::Direct
         | 
| 60 60 | 
             
              include ActionWebService::Container::Delegated
         | 
| 61 61 | 
             
              include ActionWebService::Container::ActionController
         | 
| 62 | 
            +
              include ActionWebService::Invocation
         | 
| 62 63 | 
             
              include ActionWebService::Dispatcher
         | 
| 63 64 | 
             
              include ActionWebService::Dispatcher::ActionController
         | 
| 64 65 | 
             
              include ActionWebService::Scaffolding
         | 
| @@ -8,7 +8,11 @@ module ActionWebService # :nodoc: | |
| 8 8 | 
             
                #
         | 
| 9 9 | 
             
                # It is attached to web service implementation classes like
         | 
| 10 10 | 
             
                # ActionWebService::Base and ActionController::Base derivatives by using
         | 
| 11 | 
            -
                #  | 
| 11 | 
            +
                # <tt>container.web_service_api</tt>, where <tt>container</tt> is an
         | 
| 12 | 
            +
                # ActionController::Base or a ActionWebService::Base.
         | 
| 13 | 
            +
                #
         | 
| 14 | 
            +
                # See ActionWebService::Container::Direct::ClassMethods for an example
         | 
| 15 | 
            +
                # of use.
         | 
| 12 16 | 
             
                class Base
         | 
| 13 17 | 
             
                  # Whether to transform the public API method names into camel-cased names 
         | 
| 14 18 | 
             
                  class_inheritable_option :inflect_names, true
         | 
| @@ -40,7 +44,7 @@ module ActionWebService # :nodoc: | |
| 40 44 | 
             
                    # A parameter specifier can be one of the following:
         | 
| 41 45 | 
             
                    #
         | 
| 42 46 | 
             
                    # * A symbol or string of representing one of the Action Web Service base types.
         | 
| 43 | 
            -
                    #   See ActionWebService:: | 
| 47 | 
            +
                    #   See ActionWebService::SignatureTypes for a canonical list of the base types.
         | 
| 44 48 | 
             
                    # * The Class object of the parameter type
         | 
| 45 49 | 
             
                    # * A single-element Array containing one of the two preceding items. This
         | 
| 46 50 | 
             
                    #   will cause Action Web Service to treat the parameter at that position
         | 
| @@ -217,9 +221,9 @@ module ActionWebService # :nodoc: | |
| 217 221 | 
             
                  # String representation of this method
         | 
| 218 222 | 
             
                  def to_s
         | 
| 219 223 | 
             
                    fqn = ""
         | 
| 220 | 
            -
                    fqn << (@returns ? ( | 
| 224 | 
            +
                    fqn << (@returns ? (@returns[0].human_name(false) + " ") : "void ")
         | 
| 221 225 | 
             
                    fqn << "#{@public_name}("
         | 
| 222 | 
            -
                    fqn << @expects.map{ |p|  | 
| 226 | 
            +
                    fqn << @expects.map{ |p| p.human_name }.join(", ") if @expects
         | 
| 223 227 | 
             
                    fqn << ")"
         | 
| 224 228 | 
             
                    fqn
         | 
| 225 229 | 
             
                  end
         | 
| @@ -236,13 +240,6 @@ module ActionWebService # :nodoc: | |
| 236 240 | 
             
                        end
         | 
| 237 241 | 
             
                      end
         | 
| 238 242 | 
             
                    end
         | 
| 239 | 
            -
             | 
| 240 | 
            -
                    def friendly_param(type, show_name=true)
         | 
| 241 | 
            -
                      name = type.name.to_s
         | 
| 242 | 
            -
                      type_type = type.array?? type.element_type.type.to_s : type.type.to_s
         | 
| 243 | 
            -
                      str = type.array?? (type_type + '[]') : type_type
         | 
| 244 | 
            -
                      show_name ? (str + " " + name) : str
         | 
| 245 | 
            -
                    end
         | 
| 246 243 | 
             
                end
         | 
| 247 244 | 
             
              end
         | 
| 248 245 | 
             
            end
         | 
| @@ -7,7 +7,7 @@ module ActionWebService # :nodoc: | |
| 7 7 | 
             
                end
         | 
| 8 8 |  | 
| 9 9 | 
             
                # Performs casting of arbitrary values into the correct types for the signature
         | 
| 10 | 
            -
                class BaseCaster
         | 
| 10 | 
            +
                class BaseCaster # :nodoc:
         | 
| 11 11 | 
             
                  def initialize(api_method)
         | 
| 12 12 | 
             
                    @api_method = api_method
         | 
| 13 13 | 
             
                  end
         | 
| @@ -39,6 +39,7 @@ module ActionWebService # :nodoc: | |
| 39 39 |  | 
| 40 40 | 
             
                    def cast(value, signature_type) # :nodoc:
         | 
| 41 41 | 
             
                      return value if signature_type.nil? # signature.length != params.length
         | 
| 42 | 
            +
                      return nil if value.nil?
         | 
| 42 43 | 
             
                      unless signature_type.array? || signature_type.structured?
         | 
| 43 44 | 
             
                        return value if canonical_type(value.class) == signature_type.type
         | 
| 44 45 | 
             
                      end
         | 
| @@ -62,6 +63,12 @@ module ActionWebService # :nodoc: | |
| 62 63 | 
             
                        Integer(value)
         | 
| 63 64 | 
             
                      when :string
         | 
| 64 65 | 
             
                        value.to_s
         | 
| 66 | 
            +
                      when :base64
         | 
| 67 | 
            +
                        if value.is_a?(ActionWebService::Base64)
         | 
| 68 | 
            +
                          value
         | 
| 69 | 
            +
                        else
         | 
| 70 | 
            +
                          ActionWebService::Base64.new(value.to_s)
         | 
| 71 | 
            +
                        end
         | 
| 65 72 | 
             
                      when :bool
         | 
| 66 73 | 
             
                        return false if value.nil?
         | 
| 67 74 | 
             
                        return value if value == true || value == false
         | 
| @@ -24,10 +24,10 @@ module ActionWebService # :nodoc: | |
| 24 24 | 
             
                  # will be sent with HTTP POST.
         | 
| 25 25 | 
             
                  #
         | 
| 26 26 | 
             
                  # Valid options:
         | 
| 27 | 
            -
                  # [<tt>: | 
| 28 | 
            -
                  # | 
| 29 | 
            -
                  #  | 
| 30 | 
            -
                  # | 
| 27 | 
            +
                  # [<tt>:namespace</tt>]    If the remote server has used a custom namespace to
         | 
| 28 | 
            +
                  #                          declare its custom types, you can specify it here. This would
         | 
| 29 | 
            +
                  #                          be the namespace declared with a [WebService(Namespace = "http://namespace")] attribute
         | 
| 30 | 
            +
                  #                          in .NET, for example.
         | 
| 31 31 | 
             
                  # [<tt>:driver_options</tt>]    If you want to supply any custom SOAP RPC driver
         | 
| 32 32 | 
             
                  #                               options, you can provide them as a Hash here
         | 
| 33 33 | 
             
                  #
         | 
| @@ -43,10 +43,9 @@ module ActionWebService # :nodoc: | |
| 43 43 | 
             
                  #   client = ActionWebService::Client::Soap.new(api, 'https://some/service', :driver_options => opts)
         | 
| 44 44 | 
             
                  def initialize(api, endpoint_uri, options={})
         | 
| 45 45 | 
             
                    super(api, endpoint_uri)
         | 
| 46 | 
            -
                    @ | 
| 47 | 
            -
                    @method_namespace = options[:method_namespace] || 'urn:ActionWebService'
         | 
| 46 | 
            +
                    @namespace = options[:namespace] || 'urn:ActionWebService'
         | 
| 48 47 | 
             
                    @driver_options = options[:driver_options] || {}
         | 
| 49 | 
            -
                    @protocol = ActionWebService::Protocol::Soap::SoapProtocol.new
         | 
| 48 | 
            +
                    @protocol = ActionWebService::Protocol::Soap::SoapProtocol.new @namespace
         | 
| 50 49 | 
             
                    @soap_action_base = options[:soap_action_base]
         | 
| 51 50 | 
             
                    @soap_action_base ||= URI.parse(endpoint_uri).path
         | 
| 52 51 | 
             
                    @driver = create_soap_rpc_driver(api, endpoint_uri)
         | 
| @@ -73,7 +72,7 @@ module ActionWebService # :nodoc: | |
| 73 72 | 
             
                      driver = SoapDriver.new(endpoint_uri, nil)
         | 
| 74 73 | 
             
                      driver.mapping_registry = @protocol.marshaler.registry
         | 
| 75 74 | 
             
                      api.api_methods.each do |name, method|
         | 
| 76 | 
            -
                        qname = XSD::QName.new(@ | 
| 75 | 
            +
                        qname = XSD::QName.new(@namespace, method.public_name)
         | 
| 77 76 | 
             
                        action = soap_action(method.public_name)
         | 
| 78 77 | 
             
                        expects = method.expects
         | 
| 79 78 | 
             
                        returns = method.returns
         | 
| @@ -2,13 +2,13 @@ module ActionWebService # :nodoc: | |
| 2 2 | 
             
              module Container # :nodoc:
         | 
| 3 3 | 
             
                module ActionController # :nodoc:
         | 
| 4 4 | 
             
                  def self.append_features(base) # :nodoc:
         | 
| 5 | 
            -
                     | 
| 6 | 
            -
                       | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
                       | 
| 5 | 
            +
                    class << base
         | 
| 6 | 
            +
                      include ClassMethods
         | 
| 7 | 
            +
                      alias_method :inherited_without_api, :inherited
         | 
| 8 | 
            +
                      alias_method :inherited, :inherited_with_api
         | 
| 9 | 
            +
                      alias_method :web_service_api_without_require, :web_service_api
         | 
| 10 | 
            +
                      alias_method :web_service_api, :web_service_api_with_require
         | 
| 10 11 | 
             
                    end
         | 
| 11 | 
            -
                    base.extend(ClassMethods)
         | 
| 12 12 | 
             
                  end
         | 
| 13 13 |  | 
| 14 14 | 
             
                  module ClassMethods
         | 
| @@ -43,7 +43,7 @@ module ActionWebService # :nodoc: | |
| 43 43 | 
             
                      end
         | 
| 44 44 | 
             
                    end
         | 
| 45 45 |  | 
| 46 | 
            -
                    def  | 
| 46 | 
            +
                    def web_service_api_with_require(definition=nil) # :nodoc:
         | 
| 47 47 | 
             
                      return web_service_api_without_require if definition.nil?
         | 
| 48 48 | 
             
                      case definition
         | 
| 49 49 | 
             
                      when String, Symbol
         | 
| @@ -82,7 +82,7 @@ module ActionWebService # :nodoc: | |
| 82 82 | 
             
                    end
         | 
| 83 83 |  | 
| 84 84 | 
             
                    private
         | 
| 85 | 
            -
                      def  | 
| 85 | 
            +
                      def inherited_with_api(child)
         | 
| 86 86 | 
             
                        inherited_without_api(child)
         | 
| 87 87 | 
             
                        begin child.web_service_api(child.controller_path)
         | 
| 88 88 | 
             
                        rescue MissingSourceFile => e
         | 
| @@ -35,7 +35,7 @@ module ActionWebService # :nodoc: | |
| 35 35 | 
             
                    #   class ApiController < ApplicationController
         | 
| 36 36 | 
             
                    #     web_service_dispatching_mode :delegated
         | 
| 37 37 | 
             
                    #
         | 
| 38 | 
            -
                    #     web_service(:person) { PersonService.new( | 
| 38 | 
            +
                    #     web_service(:person) { PersonService.new(request.env) }
         | 
| 39 39 | 
             
                    #   end
         | 
| 40 40 | 
             
                    def web_service(name, object=nil, &block)
         | 
| 41 41 | 
             
                      if (object && block_given?) || (object.nil? && block.nil?)
         | 
| @@ -28,28 +28,33 @@ module ActionWebService # :nodoc: | |
| 28 28 | 
             
                      @method_params = invocation.method_ordered_params
         | 
| 29 29 | 
             
                      arity = method(invocation.api_method.name).arity rescue 0
         | 
| 30 30 | 
             
                      if arity < 0 || arity > 0
         | 
| 31 | 
            -
                         | 
| 31 | 
            +
                        params = @method_params
         | 
| 32 32 | 
             
                      else
         | 
| 33 | 
            -
                         | 
| 33 | 
            +
                        params = []
         | 
| 34 34 | 
             
                      end
         | 
| 35 | 
            -
                       | 
| 35 | 
            +
                      web_service_filtered_invoke(invocation, params)
         | 
| 36 36 | 
             
                    end
         | 
| 37 37 |  | 
| 38 38 | 
             
                    def web_service_delegated_invoke(invocation)
         | 
| 39 | 
            +
                      web_service_filtered_invoke(invocation, invocation.method_ordered_params)
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    def web_service_filtered_invoke(invocation, params)
         | 
| 39 43 | 
             
                      cancellation_reason = nil
         | 
| 40 | 
            -
                      return_value = invocation.service.perform_invocation(invocation.api_method.name,  | 
| 44 | 
            +
                      return_value = invocation.service.perform_invocation(invocation.api_method.name, params) do |x|
         | 
| 41 45 | 
             
                        cancellation_reason = x
         | 
| 42 46 | 
             
                      end
         | 
| 43 47 | 
             
                      if cancellation_reason
         | 
| 44 48 | 
             
                        raise(DispatcherError, "request canceled: #{cancellation_reason}")
         | 
| 45 49 | 
             
                      end
         | 
| 46 | 
            -
                      web_service_create_response(invocation.protocol, invocation.api, invocation.api_method, return_value)
         | 
| 50 | 
            +
                      web_service_create_response(invocation.protocol, invocation.protocol_options, invocation.api, invocation.api_method, return_value)
         | 
| 47 51 | 
             
                    end
         | 
| 48 52 |  | 
| 49 53 | 
             
                    def web_service_invocation(request)
         | 
| 50 54 | 
             
                      public_method_name = request.method_name
         | 
| 51 55 | 
             
                      invocation = Invocation.new
         | 
| 52 56 | 
             
                      invocation.protocol = request.protocol
         | 
| 57 | 
            +
                      invocation.protocol_options = request.protocol_options
         | 
| 53 58 | 
             
                      invocation.service_name = request.service_name
         | 
| 54 59 | 
             
                      if web_service_dispatching_mode == :layered
         | 
| 55 60 | 
             
                        case invocation.protocol
         | 
| @@ -109,18 +114,19 @@ module ActionWebService # :nodoc: | |
| 109 114 | 
             
                      invocation
         | 
| 110 115 | 
             
                    end
         | 
| 111 116 |  | 
| 112 | 
            -
                    def web_service_create_response(protocol, api, api_method, return_value)
         | 
| 117 | 
            +
                    def web_service_create_response(protocol, protocol_options, api, api_method, return_value)
         | 
| 113 118 | 
             
                      if api.has_api_method?(api_method.name)
         | 
| 114 119 | 
             
                        return_type = api_method.returns ? api_method.returns[0] : nil
         | 
| 115 120 | 
             
                        return_value = api_method.cast_returns(return_value)
         | 
| 116 121 | 
             
                      else
         | 
| 117 122 | 
             
                        return_type = ActionWebService::SignatureTypes.canonical_signature_entry(return_value.class, 0)
         | 
| 118 123 | 
             
                      end
         | 
| 119 | 
            -
                      protocol.encode_response(api_method.public_name + 'Response', return_value, return_type)
         | 
| 124 | 
            +
                      protocol.encode_response(api_method.public_name + 'Response', return_value, return_type, protocol_options)
         | 
| 120 125 | 
             
                    end
         | 
| 121 126 |  | 
| 122 127 | 
             
                    class Invocation # :nodoc:
         | 
| 123 128 | 
             
                      attr_accessor :protocol
         | 
| 129 | 
            +
                      attr_accessor :protocol_options
         | 
| 124 130 | 
             
                      attr_accessor :service_name
         | 
| 125 131 | 
             
                      attr_accessor :api
         | 
| 126 132 | 
             
                      attr_accessor :api_method
         | 
| @@ -6,10 +6,12 @@ module ActionWebService # :nodoc: | |
| 6 6 | 
             
                module ActionController # :nodoc:
         | 
| 7 7 | 
             
                  def self.append_features(base) # :nodoc:
         | 
| 8 8 | 
             
                    super
         | 
| 9 | 
            +
                    class << base
         | 
| 10 | 
            +
                      include ClassMethods
         | 
| 11 | 
            +
                      alias_method :inherited_without_action_controller, :inherited
         | 
| 12 | 
            +
                      alias_method :inherited, :inherited_with_action_controller
         | 
| 13 | 
            +
                    end
         | 
| 9 14 | 
             
                    base.class_eval do
         | 
| 10 | 
            -
                      class << self
         | 
| 11 | 
            -
                        alias_method :inherited_without_action_controller, :inherited
         | 
| 12 | 
            -
                      end
         | 
| 13 15 | 
             
                      alias_method :web_service_direct_invoke_without_controller, :web_service_direct_invoke
         | 
| 14 16 | 
             
                    end
         | 
| 15 17 | 
             
                    base.add_web_service_api_callback do |klass, api|
         | 
| @@ -24,12 +26,11 @@ module ActionWebService # :nodoc: | |
| 24 26 | 
             
                        klass.class_eval 'def api; dispatch_web_service_request; end'
         | 
| 25 27 | 
             
                      end
         | 
| 26 28 | 
             
                    end
         | 
| 27 | 
            -
                    base.extend(ClassMethods)
         | 
| 28 29 | 
             
                    base.send(:include, ActionWebService::Dispatcher::ActionController::InstanceMethods)
         | 
| 29 30 | 
             
                  end
         | 
| 30 31 |  | 
| 31 32 | 
             
                  module ClassMethods # :nodoc:
         | 
| 32 | 
            -
                    def  | 
| 33 | 
            +
                    def inherited_with_action_controller(child)
         | 
| 33 34 | 
             
                      inherited_without_action_controller(child)
         | 
| 34 35 | 
             
                      child.send(:include, ActionWebService::Dispatcher::ActionController::WsdlAction)
         | 
| 35 36 | 
             
                    end
         | 
| @@ -40,53 +41,53 @@ module ActionWebService # :nodoc: | |
| 40 41 | 
             
                      def dispatch_web_service_request
         | 
| 41 42 | 
             
                        exception = nil
         | 
| 42 43 | 
             
                        begin
         | 
| 43 | 
            -
                           | 
| 44 | 
            +
                          ws_request = discover_web_service_request(request)
         | 
| 44 45 | 
             
                        rescue Exception => e
         | 
| 45 46 | 
             
                          exception = e
         | 
| 46 47 | 
             
                        end
         | 
| 47 | 
            -
                        if  | 
| 48 | 
            -
                           | 
| 48 | 
            +
                        if ws_request
         | 
| 49 | 
            +
                          ws_response = nil
         | 
| 49 50 | 
             
                          exception = nil
         | 
| 50 51 | 
             
                          bm = Benchmark.measure do
         | 
| 51 52 | 
             
                            begin
         | 
| 52 | 
            -
                               | 
| 53 | 
            +
                              ws_response = invoke_web_service_request(ws_request)
         | 
| 53 54 | 
             
                            rescue Exception => e
         | 
| 54 55 | 
             
                              exception = e
         | 
| 55 56 | 
             
                            end
         | 
| 56 57 | 
             
                          end
         | 
| 57 | 
            -
                          log_request( | 
| 58 | 
            +
                          log_request(ws_request, request.raw_post)
         | 
| 58 59 | 
             
                          if exception
         | 
| 59 60 | 
             
                            log_error(exception) unless logger.nil?
         | 
| 60 | 
            -
                            send_web_service_error_response( | 
| 61 | 
            +
                            send_web_service_error_response(ws_request, exception)
         | 
| 61 62 | 
             
                          else
         | 
| 62 | 
            -
                            send_web_service_response( | 
| 63 | 
            +
                            send_web_service_response(ws_response, bm.real)
         | 
| 63 64 | 
             
                          end
         | 
| 64 65 | 
             
                        else
         | 
| 65 66 | 
             
                          exception ||= DispatcherError.new("Malformed SOAP or XML-RPC protocol message")
         | 
| 66 67 | 
             
                          log_error(exception) unless logger.nil?
         | 
| 67 | 
            -
                          send_web_service_error_response( | 
| 68 | 
            +
                          send_web_service_error_response(ws_request, exception)
         | 
| 68 69 | 
             
                        end
         | 
| 69 70 | 
             
                      rescue Exception => e
         | 
| 70 71 | 
             
                        log_error(e) unless logger.nil?
         | 
| 71 | 
            -
                        send_web_service_error_response( | 
| 72 | 
            +
                        send_web_service_error_response(ws_request, e)
         | 
| 72 73 | 
             
                      end
         | 
| 73 74 |  | 
| 74 | 
            -
                      def send_web_service_response( | 
| 75 | 
            -
                        log_response( | 
| 76 | 
            -
                        options = { :type =>  | 
| 77 | 
            -
                        send_data( | 
| 75 | 
            +
                      def send_web_service_response(ws_response, elapsed=nil)
         | 
| 76 | 
            +
                        log_response(ws_response, elapsed)
         | 
| 77 | 
            +
                        options = { :type => ws_response.content_type, :disposition => 'inline' }
         | 
| 78 | 
            +
                        send_data(ws_response.body, options)
         | 
| 78 79 | 
             
                      end
         | 
| 79 80 |  | 
| 80 | 
            -
                      def send_web_service_error_response( | 
| 81 | 
            -
                        if  | 
| 81 | 
            +
                      def send_web_service_error_response(ws_request, exception)
         | 
| 82 | 
            +
                        if ws_request
         | 
| 82 83 | 
             
                          unless self.class.web_service_exception_reporting
         | 
| 83 84 | 
             
                            exception = DispatcherError.new("Internal server error (exception raised)")
         | 
| 84 85 | 
             
                          end
         | 
| 85 | 
            -
                          api_method =  | 
| 86 | 
            -
                          public_method_name = api_method ? api_method.public_name :  | 
| 86 | 
            +
                          api_method = ws_request.api_method
         | 
| 87 | 
            +
                          public_method_name = api_method ? api_method.public_name : ws_request.method_name
         | 
| 87 88 | 
             
                          return_type = ActionWebService::SignatureTypes.canonical_signature_entry(Exception, 0)
         | 
| 88 | 
            -
                           | 
| 89 | 
            -
                          send_web_service_response( | 
| 89 | 
            +
                          ws_response = ws_request.protocol.encode_response(public_method_name + 'Response', exception, return_type, ws_request.protocol_options)
         | 
| 90 | 
            +
                          send_web_service_response(ws_response)
         | 
| 90 91 | 
             
                        else
         | 
| 91 92 | 
             
                          if self.class.web_service_exception_reporting
         | 
| 92 93 | 
             
                            message = exception.message
         | 
| @@ -100,13 +101,10 @@ module ActionWebService # :nodoc: | |
| 100 101 | 
             
                      end
         | 
| 101 102 |  | 
| 102 103 | 
             
                      def web_service_direct_invoke(invocation)
         | 
| 103 | 
            -
                        @params ||= {}
         | 
| 104 104 | 
             
                        invocation.method_named_params.each do |name, value|
         | 
| 105 | 
            -
                           | 
| 105 | 
            +
                          params[name] = value
         | 
| 106 106 | 
             
                        end
         | 
| 107 | 
            -
                         | 
| 108 | 
            -
                        @assigns ||= {}
         | 
| 109 | 
            -
                        @params['action'] = invocation.api_method.name.to_s
         | 
| 107 | 
            +
                        params['action'] = invocation.api_method.name.to_s
         | 
| 110 108 | 
             
                        if before_action == false
         | 
| 111 109 | 
             
                          raise(DispatcherError, "Method filtered")
         | 
| 112 110 | 
             
                        end
         | 
| @@ -115,27 +113,27 @@ module ActionWebService # :nodoc: | |
| 115 113 | 
             
                        return_value
         | 
| 116 114 | 
             
                      end
         | 
| 117 115 |  | 
| 118 | 
            -
                      def log_request( | 
| 116 | 
            +
                      def log_request(ws_request, body)
         | 
| 119 117 | 
             
                        unless logger.nil?
         | 
| 120 | 
            -
                          name =  | 
| 121 | 
            -
                          api_method =  | 
| 122 | 
            -
                          params =  | 
| 118 | 
            +
                          name = ws_request.method_name
         | 
| 119 | 
            +
                          api_method = ws_request.api_method
         | 
| 120 | 
            +
                          params = ws_request.method_params
         | 
| 123 121 | 
             
                          if api_method && api_method.expects
         | 
| 124 122 | 
             
                            params = api_method.expects.zip(params).map{ |type, param| "#{type.name}=>#{param.inspect}" }
         | 
| 125 123 | 
             
                          else
         | 
| 126 124 | 
             
                            params = params.map{ |param| param.inspect }
         | 
| 127 125 | 
             
                          end
         | 
| 128 | 
            -
                          service =  | 
| 126 | 
            +
                          service = ws_request.service_name
         | 
| 129 127 | 
             
                          logger.debug("\nWeb Service Request: #{name}(#{params.join(", ")}) Entrypoint: #{service}")
         | 
| 130 128 | 
             
                          logger.debug(indent(body))
         | 
| 131 129 | 
             
                        end
         | 
| 132 130 | 
             
                      end
         | 
| 133 131 |  | 
| 134 | 
            -
                      def log_response( | 
| 132 | 
            +
                      def log_response(ws_response, elapsed=nil)
         | 
| 135 133 | 
             
                        unless logger.nil?
         | 
| 136 134 | 
             
                          elapsed = (elapsed ? " (%f):" % elapsed : ":")
         | 
| 137 | 
            -
                          logger.debug("\nWeb Service Response" + elapsed + " => #{ | 
| 138 | 
            -
                          logger.debug(indent( | 
| 135 | 
            +
                          logger.debug("\nWeb Service Response" + elapsed + " => #{ws_response.return_value.inspect}")
         | 
| 136 | 
            +
                          logger.debug(indent(ws_response.body))
         | 
| 139 137 | 
             
                        end
         | 
| 140 138 | 
             
                      end
         | 
| 141 139 |  | 
| @@ -152,7 +150,7 @@ module ActionWebService # :nodoc: | |
| 152 150 | 
             
                    SoapHttpTransport = 'http://schemas.xmlsoap.org/soap/http'
         | 
| 153 151 |  | 
| 154 152 | 
             
                    def wsdl
         | 
| 155 | 
            -
                      case  | 
| 153 | 
            +
                      case request.method
         | 
| 156 154 | 
             
                      when :get
         | 
| 157 155 | 
             
                        begin
         | 
| 158 156 | 
             
                          options = { :type => 'text/xml', :disposition => 'inline' }
         | 
| @@ -167,15 +165,17 @@ module ActionWebService # :nodoc: | |
| 167 165 |  | 
| 168 166 | 
             
                    private
         | 
| 169 167 | 
             
                      def base_uri
         | 
| 170 | 
            -
                        host =  | 
| 171 | 
            -
                         | 
| 168 | 
            +
                        host = request.env['HTTP_HOST'] || request.env['SERVER_NAME'] || 'localhost'
         | 
| 169 | 
            +
                        relative_url_root = request.relative_url_root
         | 
| 170 | 
            +
                        scheme = request.ssl? ? 'https' : 'http'
         | 
| 171 | 
            +
                        '%s://%s%s/%s/' % [scheme, host, relative_url_root, self.class.controller_path]
         | 
| 172 172 | 
             
                      end
         | 
| 173 173 |  | 
| 174 174 | 
             
                      def to_wsdl
         | 
| 175 175 | 
             
                        xml = ''
         | 
| 176 176 | 
             
                        dispatching_mode = web_service_dispatching_mode
         | 
| 177 177 | 
             
                        global_service_name = wsdl_service_name
         | 
| 178 | 
            -
                        namespace = 'urn:ActionWebService'
         | 
| 178 | 
            +
                        namespace = wsdl_namespace || 'urn:ActionWebService'
         | 
| 179 179 | 
             
                        soap_action_base = "/#{controller_name}"
         | 
| 180 180 |  | 
| 181 181 | 
             
                        marshaler = ActionWebService::Protocol::Soap::SoapMarshaler.new(namespace)
         |