actionwebservice 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|