troelskn-handsoap 0.3.8 → 0.4.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/VERSION.yml +2 -2
- data/lib/handsoap/service.rb +76 -56
- data/lib/handsoap/xml_query_front.rb +7 -7
- metadata +4 -4
data/VERSION.yml
CHANGED
data/lib/handsoap/service.rb
CHANGED
|
@@ -24,40 +24,6 @@ module Handsoap
|
|
|
24
24
|
@xml_query_driver = Handsoap::XmlQueryFront.load_driver!(driver)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
SOAP_NAMESPACE = { 1 => 'http://schemas.xmlsoap.org/soap/envelope/', 2 => 'http://www.w3.org/2003/05/soap-envelope' }
|
|
28
|
-
|
|
29
|
-
class Response
|
|
30
|
-
def initialize(http_body, soap_namespace)
|
|
31
|
-
@http_body = http_body
|
|
32
|
-
@soap_namespace = soap_namespace
|
|
33
|
-
@document = :lazy
|
|
34
|
-
@fault = :lazy
|
|
35
|
-
end
|
|
36
|
-
def document?
|
|
37
|
-
!! document
|
|
38
|
-
end
|
|
39
|
-
def document
|
|
40
|
-
if @document == :lazy
|
|
41
|
-
begin
|
|
42
|
-
@document = Handsoap::XmlQueryFront.parse_string(@http_body, Handsoap.xml_query_driver)
|
|
43
|
-
rescue Handsoap::XmlQueryFront::ParseError => ex
|
|
44
|
-
@document = nil
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
return @document
|
|
48
|
-
end
|
|
49
|
-
def fault?
|
|
50
|
-
!! fault
|
|
51
|
-
end
|
|
52
|
-
def fault
|
|
53
|
-
if @fault == :lazy
|
|
54
|
-
nodes = document? ? document.xpath('/env:Envelope/env:Body/descendant-or-self::env:Fault', { 'env' => @soap_namespace }) : []
|
|
55
|
-
@fault = nodes.any? ? Fault.from_xml(nodes.first, :namespace => @soap_namespace) : nil
|
|
56
|
-
end
|
|
57
|
-
return @fault
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
27
|
class Fault < Exception
|
|
62
28
|
attr_reader :code, :reason, :details
|
|
63
29
|
def initialize(code, reason, details)
|
|
@@ -91,18 +57,33 @@ module Handsoap
|
|
|
91
57
|
def self.logger=(io)
|
|
92
58
|
@@logger = io
|
|
93
59
|
end
|
|
60
|
+
# Sets the endpoint for the service.
|
|
61
|
+
# Arguments:
|
|
62
|
+
# :uri => endpoint uri of the service. Required.
|
|
63
|
+
# :version => 1 | 2
|
|
64
|
+
# :envelope_namespace => Namespace of SOAP-envelope
|
|
65
|
+
# :request_content_type => Content-Type of HTTP request.
|
|
66
|
+
# You must supply either :version or both :envelope_namspace and :request_content_type.
|
|
67
|
+
# :version is simply a shortcut for default values.
|
|
94
68
|
def self.endpoint(args = {})
|
|
95
|
-
@protocol_version = args[:version] || raise("Missing option :version")
|
|
96
69
|
@uri = args[:uri] || raise("Missing option :uri")
|
|
70
|
+
if args[:version]
|
|
71
|
+
soap_namespace = { 1 => 'http://schemas.xmlsoap.org/soap/envelope/', 2 => 'http://www.w3.org/2003/05/soap-envelope' }
|
|
72
|
+
raise("Unknown protocol version '#{@protocol_version.inspect}'") if soap_namespace[args[:version]].nil?
|
|
73
|
+
@envelope_namespace = soap_namespace[args[:version]]
|
|
74
|
+
@request_content_type = args[:version] == 1 ? "text/xml" : "application/soap+xml"
|
|
75
|
+
end
|
|
76
|
+
@envelope_namespace = args[:envelope_namespace] unless args[:envelope_namespace].nil?
|
|
77
|
+
@request_content_type = args[:request_content_type] unless args[:request_content_type].nil?
|
|
78
|
+
if @envelope_namespace.nil? || @request_content_type.nil?
|
|
79
|
+
raise("Missing option :envelope_namespace, :request_content_type or :version")
|
|
80
|
+
end
|
|
97
81
|
end
|
|
98
82
|
def self.envelope_namespace
|
|
99
|
-
|
|
100
|
-
raise "Unknown protocol version '#{@protocol_version.inspect}'"
|
|
101
|
-
end
|
|
102
|
-
SOAP_NAMESPACE[@protocol_version]
|
|
83
|
+
@envelope_namespace
|
|
103
84
|
end
|
|
104
85
|
def self.request_content_type
|
|
105
|
-
@
|
|
86
|
+
@request_content_type
|
|
106
87
|
end
|
|
107
88
|
def self.uri
|
|
108
89
|
@uri
|
|
@@ -158,6 +139,11 @@ module Handsoap
|
|
|
158
139
|
# You can override this to provide filtering and logging.
|
|
159
140
|
def on_before_dispatch
|
|
160
141
|
end
|
|
142
|
+
# Hook that is called after the http_client is created.
|
|
143
|
+
#
|
|
144
|
+
# You can override this to customize the http_client
|
|
145
|
+
def on_after_create_http_client(http_client)
|
|
146
|
+
end
|
|
161
147
|
# Hook that is called when there is a response.
|
|
162
148
|
#
|
|
163
149
|
# You can override this to register common namespaces, useful for parsing the document.
|
|
@@ -172,13 +158,18 @@ module Handsoap
|
|
|
172
158
|
# Hook that is called if the dispatch returns a +Fault+.
|
|
173
159
|
#
|
|
174
160
|
# Default behaviour is to raise the Fault, but you can override this to provide logging and more fine-grained handling faults.
|
|
161
|
+
#
|
|
162
|
+
# See also: parse_soap_fault
|
|
175
163
|
def on_fault(fault)
|
|
176
164
|
raise fault
|
|
177
165
|
end
|
|
178
166
|
# Hook that is called if the response does not contain a valid SOAP enevlope.
|
|
179
167
|
#
|
|
180
168
|
# Default behaviour is to raise an error
|
|
181
|
-
|
|
169
|
+
#
|
|
170
|
+
# Note that if your service has operations that are one-way, you shouldn't raise an error here.
|
|
171
|
+
# This is however a fairly exotic case, so that is why the default behaviour is to raise an error.
|
|
172
|
+
def on_missing_document(http_response_body)
|
|
182
173
|
raise "The response is not a valid SOAP envelope"
|
|
183
174
|
end
|
|
184
175
|
def debug(message = nil) #:nodoc:
|
|
@@ -195,17 +186,20 @@ module Handsoap
|
|
|
195
186
|
def send_http_request(uri, post_body, headers)
|
|
196
187
|
if Handsoap.http_driver == :curb
|
|
197
188
|
http_client = Curl::Easy.new(uri)
|
|
189
|
+
on_after_create_http_client(http_client)
|
|
198
190
|
http_client.headers = headers
|
|
199
191
|
http_client.http_post post_body
|
|
200
192
|
return { :status => http_client.response_code, :body => http_client.body_str, :content_type => http_client.content_type }
|
|
201
193
|
elsif Handsoap.http_driver == :httpclient
|
|
202
|
-
|
|
194
|
+
http_client = HTTPClient.new
|
|
195
|
+
on_after_create_http_client(http_client)
|
|
196
|
+
response = http_client.post(uri, post_body, headers)
|
|
203
197
|
return { :status => response.status, :body => response.content, :content_type => response.contenttype }
|
|
204
198
|
else
|
|
205
199
|
raise "Unknown http driver #{Handsoap.http_driver}"
|
|
206
200
|
end
|
|
207
201
|
end
|
|
208
|
-
# Send document and parses the response into a +
|
|
202
|
+
# Send document and parses the response into a +XmlQueryFront::XmlElement+ (XmlDocument)
|
|
209
203
|
def dispatch(doc, action)
|
|
210
204
|
on_before_dispatch
|
|
211
205
|
headers = {
|
|
@@ -229,18 +223,29 @@ module Handsoap
|
|
|
229
223
|
logger.puts "---"
|
|
230
224
|
logger.puts Handsoap.pretty_format_envelope(response[:body])
|
|
231
225
|
end
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
226
|
+
# Start the parsing pipe-line.
|
|
227
|
+
# There are various stages and hooks for each, so that you can override those in your service classes.
|
|
228
|
+
xml_document = parse_soap_response_document(response[:body])
|
|
229
|
+
soap_fault = parse_soap_fault(xml_document)
|
|
230
|
+
# Is the response a soap-fault?
|
|
231
|
+
unless soap_fault.nil?
|
|
232
|
+
return on_fault(soap_fault)
|
|
235
233
|
end
|
|
236
|
-
|
|
234
|
+
# Does the http-status indicate an error?
|
|
235
|
+
if response[:status] >= 400
|
|
237
236
|
return on_http_error(response[:status], response[:body])
|
|
238
237
|
end
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
# Does the response contain a valid xml-document?
|
|
239
|
+
if xml_document.nil?
|
|
240
|
+
return on_missing_document(response[:body])
|
|
241
|
+
end
|
|
242
|
+
# Everything seems in order.
|
|
243
|
+
on_response_document(xml_document)
|
|
244
|
+
# BC hack
|
|
245
|
+
def xml_document.document
|
|
246
|
+
self
|
|
241
247
|
end
|
|
242
|
-
|
|
243
|
-
return soap_response
|
|
248
|
+
return xml_document
|
|
244
249
|
end
|
|
245
250
|
# Creates a standard SOAP envelope and yields the +Body+ element.
|
|
246
251
|
def make_envelope # :yields: Handsoap::XmlMason::Element
|
|
@@ -258,6 +263,21 @@ module Handsoap
|
|
|
258
263
|
end
|
|
259
264
|
return doc
|
|
260
265
|
end
|
|
266
|
+
# String -> [XmlDocument | nil]
|
|
267
|
+
def parse_soap_response_document(http_body)
|
|
268
|
+
begin
|
|
269
|
+
Handsoap::XmlQueryFront.parse_string(http_body, Handsoap.xml_query_driver)
|
|
270
|
+
rescue Handsoap::XmlQueryFront::ParseError => ex
|
|
271
|
+
nil
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
# XmlDocument -> [Fault | nil]
|
|
275
|
+
def parse_soap_fault(document)
|
|
276
|
+
unless document.nil?
|
|
277
|
+
node = document.xpath('/env:Envelope/env:Body/descendant-or-self::env:Fault', { 'env' => self.class.envelope_namespace }).first
|
|
278
|
+
Fault.from_xml(node, :namespace => self.class.envelope_namespace) unless node.nil?
|
|
279
|
+
end
|
|
280
|
+
end
|
|
261
281
|
end
|
|
262
282
|
|
|
263
283
|
def self.pretty_format_envelope(xml_string)
|
|
@@ -312,7 +332,7 @@ module Handsoap
|
|
|
312
332
|
private
|
|
313
333
|
# Helper to serialize a node into a ruby string
|
|
314
334
|
#
|
|
315
|
-
# *deprecated*. Use Handsoap::XmlQueryFront::
|
|
335
|
+
# *deprecated*. Use Handsoap::XmlQueryFront::XmlElement#to_s
|
|
316
336
|
def xml_to_str(node, xquery = nil)
|
|
317
337
|
n = xquery ? node.xpath(xquery, ns).first : node
|
|
318
338
|
return if n.nil?
|
|
@@ -321,7 +341,7 @@ module Handsoap
|
|
|
321
341
|
alias_method :xml_to_s, :xml_to_str
|
|
322
342
|
# Helper to serialize a node into a ruby integer
|
|
323
343
|
#
|
|
324
|
-
# *deprecated*. Use Handsoap::XmlQueryFront::
|
|
344
|
+
# *deprecated*. Use Handsoap::XmlQueryFront::XmlElement#to_i
|
|
325
345
|
def xml_to_int(node, xquery = nil)
|
|
326
346
|
n = xquery ? node.xpath(xquery, ns).first : node
|
|
327
347
|
return if n.nil?
|
|
@@ -330,7 +350,7 @@ module Handsoap
|
|
|
330
350
|
alias_method :xml_to_i, :xml_to_int
|
|
331
351
|
# Helper to serialize a node into a ruby float
|
|
332
352
|
#
|
|
333
|
-
# *deprecated*. Use Handsoap::XmlQueryFront::
|
|
353
|
+
# *deprecated*. Use Handsoap::XmlQueryFront::XmlElement#to_f
|
|
334
354
|
def xml_to_float(node, xquery = nil)
|
|
335
355
|
n = xquery ? node.xpath(xquery, ns).first : node
|
|
336
356
|
return if n.nil?
|
|
@@ -339,7 +359,7 @@ module Handsoap
|
|
|
339
359
|
alias_method :xml_to_f, :xml_to_float
|
|
340
360
|
# Helper to serialize a node into a ruby boolean
|
|
341
361
|
#
|
|
342
|
-
# *deprecated*. Use Handsoap::XmlQueryFront::
|
|
362
|
+
# *deprecated*. Use Handsoap::XmlQueryFront::XmlElement#to_boolean
|
|
343
363
|
def xml_to_bool(node, xquery = nil)
|
|
344
364
|
n = xquery ? node.xpath(xquery, ns).first : node
|
|
345
365
|
return if n.nil?
|
|
@@ -347,7 +367,7 @@ module Handsoap
|
|
|
347
367
|
end
|
|
348
368
|
# Helper to serialize a node into a ruby Time object
|
|
349
369
|
#
|
|
350
|
-
# *deprecated*. Use Handsoap::XmlQueryFront::
|
|
370
|
+
# *deprecated*. Use Handsoap::XmlQueryFront::XmlElement#to_date
|
|
351
371
|
def xml_to_date(node, xquery = nil)
|
|
352
372
|
n = xquery ? node.xpath(xquery, ns).first : node
|
|
353
373
|
return if n.nil?
|
|
@@ -13,7 +13,7 @@ module Handsoap
|
|
|
13
13
|
# :nokogiri
|
|
14
14
|
# :libxml
|
|
15
15
|
#
|
|
16
|
-
# The resulting object is a wrapper, of the type Handsoap::XmlQueryFront::
|
|
16
|
+
# The resulting object is a wrapper, of the type Handsoap::XmlQueryFront::XmlElement.
|
|
17
17
|
#
|
|
18
18
|
module XmlQueryFront
|
|
19
19
|
|
|
@@ -65,7 +65,7 @@ module Handsoap
|
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
# NodeSelection is a wrapper around Array, that implicitly delegates
|
|
68
|
+
# NodeSelection is a wrapper around Array, that implicitly delegates XmlElement methods to the first element.
|
|
69
69
|
#
|
|
70
70
|
# It makes mapping code prettier, since you often need to access the first element of a selection.
|
|
71
71
|
class NodeSelection < Array
|
|
@@ -102,7 +102,7 @@ module Handsoap
|
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
# Wraps the underlying (native) xml driver, and provides a uniform interface.
|
|
105
|
-
module
|
|
105
|
+
module XmlElement
|
|
106
106
|
def initialize(element, namespaces = {})
|
|
107
107
|
@element = element
|
|
108
108
|
@namespaces = namespaces
|
|
@@ -116,7 +116,7 @@ module Handsoap
|
|
|
116
116
|
# Checks that an xpath-query doesn't refer to any undefined prefixes in +ns+
|
|
117
117
|
def assert_prefixes!(expression, ns)
|
|
118
118
|
expression.scan(/([a-zA-Z_][a-zA-Z0-9_.-]*):[^:]+/).map{|m| m[0] }.each do |prefix|
|
|
119
|
-
raise "Undefined prefix '#{prefix}'" if ns[prefix].nil?
|
|
119
|
+
raise "Undefined prefix '#{prefix}' in #{ns.inspect}" if ns[prefix].nil?
|
|
120
120
|
end
|
|
121
121
|
end
|
|
122
122
|
# Returns the value of the element as an integer.
|
|
@@ -203,7 +203,7 @@ module Handsoap
|
|
|
203
203
|
#
|
|
204
204
|
# http://libxml.rubyforge.org/
|
|
205
205
|
class LibXMLDriver
|
|
206
|
-
include
|
|
206
|
+
include XmlElement
|
|
207
207
|
def node_name
|
|
208
208
|
@element.name
|
|
209
209
|
end
|
|
@@ -236,7 +236,7 @@ module Handsoap
|
|
|
236
236
|
#
|
|
237
237
|
# http://www.germane-software.com/software/rexml/
|
|
238
238
|
class REXMLDriver
|
|
239
|
-
include
|
|
239
|
+
include XmlElement
|
|
240
240
|
def node_name
|
|
241
241
|
@element.name
|
|
242
242
|
end
|
|
@@ -274,7 +274,7 @@ module Handsoap
|
|
|
274
274
|
#
|
|
275
275
|
# http://nokogiri.rubyforge.org/nokogiri/
|
|
276
276
|
class NokogiriDriver
|
|
277
|
-
include
|
|
277
|
+
include XmlElement
|
|
278
278
|
def node_name
|
|
279
279
|
@element.name
|
|
280
280
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: troelskn-handsoap
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Troels Knak-Nielsen
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2009-07-
|
|
12
|
+
date: 2009-07-31 00:00:00 -07:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies: []
|
|
15
15
|
|
|
@@ -33,7 +33,7 @@ files:
|
|
|
33
33
|
- lib/handsoap/service.rb
|
|
34
34
|
- lib/handsoap/xml_mason.rb
|
|
35
35
|
- lib/handsoap/xml_query_front.rb
|
|
36
|
-
has_rdoc:
|
|
36
|
+
has_rdoc: true
|
|
37
37
|
homepage: http://github.com/troelskn/handsoap
|
|
38
38
|
licenses:
|
|
39
39
|
post_install_message:
|
|
@@ -62,7 +62,7 @@ requirements:
|
|
|
62
62
|
rubyforge_project:
|
|
63
63
|
rubygems_version: 1.3.5
|
|
64
64
|
signing_key:
|
|
65
|
-
specification_version:
|
|
65
|
+
specification_version: 2
|
|
66
66
|
summary: Handsoap is a library for creating SOAP clients in Ruby
|
|
67
67
|
test_files: []
|
|
68
68
|
|