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)
|