troelskn-handsoap 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION.yml +1 -1
- data/lib/handsoap/service.rb +130 -5
- metadata +4 -4
data/VERSION.yml
CHANGED
data/lib/handsoap/service.rb
CHANGED
@@ -189,12 +189,28 @@ module Handsoap
|
|
189
189
|
on_after_create_http_client(http_client)
|
190
190
|
http_client.headers = headers
|
191
191
|
http_client.http_post post_body
|
192
|
-
|
192
|
+
if %r|\Amultipart.*boundary=\"?([^\";,]+)\"?|n.match(http_client.content_type)
|
193
|
+
boundary = $1.dup
|
194
|
+
parts = Handsoap.parse_multipart(boundary, http_client.body_str)
|
195
|
+
is_multipart = true
|
196
|
+
else
|
197
|
+
parts = [{:head => http_client.header_str, :body => http_client.body_str}]
|
198
|
+
is_multipart = false
|
199
|
+
end
|
200
|
+
return { :status => http_client.response_code, :body => http_client.body_str, :content_type => http_client.content_type, :parts => parts, :multipart => is_multipart }
|
193
201
|
elsif Handsoap.http_driver == :httpclient
|
194
202
|
http_client = HTTPClient.new
|
195
203
|
on_after_create_http_client(http_client)
|
196
204
|
response = http_client.post(uri, post_body, headers)
|
197
|
-
|
205
|
+
if %r|\Amultipart.*boundary=\"?([^\";,]+)\"?|n.match(response.contenttype)
|
206
|
+
boundary = $1.dup
|
207
|
+
parts = Handsoap.parse_multipart(boundary, response.content)
|
208
|
+
is_multipart = true
|
209
|
+
else
|
210
|
+
parts = [{:head => response.all.join("\r\n"), :body => response.content}]
|
211
|
+
is_multipart = false
|
212
|
+
end
|
213
|
+
return { :status => response.status, :body => response.content, :content_type => response.contenttype, :parts => parts, :multipart => is_multipart }
|
198
214
|
else
|
199
215
|
raise "Unknown http driver #{Handsoap.http_driver}"
|
200
216
|
end
|
@@ -220,12 +236,23 @@ module Handsoap
|
|
220
236
|
logger.puts "--- Response ---"
|
221
237
|
logger.puts "HTTP Status: %s" % [response[:status]]
|
222
238
|
logger.puts "Content-Type: %s" % [response[:content_type]]
|
223
|
-
|
224
|
-
|
239
|
+
if response[:multipart]
|
240
|
+
num = 0
|
241
|
+
response[:parts].each do |part|
|
242
|
+
num += 1
|
243
|
+
logger.puts "--- Part ##{num} ---"
|
244
|
+
logger.puts part[:head].gsub(/\r\n/, "\n")
|
245
|
+
logger.puts "---"
|
246
|
+
logger.puts Handsoap.pretty_format_envelope(part[:body])
|
247
|
+
end
|
248
|
+
else
|
249
|
+
logger.puts "---"
|
250
|
+
logger.puts Handsoap.pretty_format_envelope(response[:body])
|
251
|
+
end
|
225
252
|
end
|
226
253
|
# Start the parsing pipe-line.
|
227
254
|
# 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])
|
255
|
+
xml_document = parse_soap_response_document(response[:parts].first[:body]) # Strictly speaking, the main part doesn't need to be first, but until proven otherwise, we'll just assume that.
|
229
256
|
soap_fault = parse_soap_fault(xml_document)
|
230
257
|
# Is the response a soap-fault?
|
231
258
|
unless soap_fault.nil?
|
@@ -245,6 +272,10 @@ module Handsoap
|
|
245
272
|
def xml_document.document
|
246
273
|
self
|
247
274
|
end
|
275
|
+
# I should probably use a class for this response object instead ...
|
276
|
+
def xml_document.parts
|
277
|
+
response[:parts]
|
278
|
+
end
|
248
279
|
return xml_document
|
249
280
|
end
|
250
281
|
# Creates a standard SOAP envelope and yields the +Body+ element.
|
@@ -293,6 +324,100 @@ module Handsoap
|
|
293
324
|
return xml_string
|
294
325
|
end
|
295
326
|
|
327
|
+
# Parses a multipart http-response body into parts.
|
328
|
+
# +boundary+ is a string of the boundary token.
|
329
|
+
# +content_io+ is either a string or an IO. If it's an IO, then content_length must be specified.
|
330
|
+
# +content_length+ (optional) is an integer, specifying the length of +content_io+
|
331
|
+
#
|
332
|
+
# This code is lifted from cgi.rb
|
333
|
+
#
|
334
|
+
def self.parse_multipart(boundary, content_io, content_length = nil)
|
335
|
+
if content_io.kind_of? String
|
336
|
+
content_length = content_io.length
|
337
|
+
content_io = StringIO.new(content_io, 'r')
|
338
|
+
elsif !(content_io.kind_of? IO) || content_length.nil?
|
339
|
+
raise "Second argument must be String or IO with content_length"
|
340
|
+
end
|
341
|
+
|
342
|
+
boundary = "--" + boundary
|
343
|
+
quoted_boundary = Regexp.quote(boundary, "n")
|
344
|
+
buf = ""
|
345
|
+
bufsize = 10 * 1024
|
346
|
+
boundary_end = ""
|
347
|
+
|
348
|
+
# start multipart/form-data
|
349
|
+
content_io.binmode if defined? content_io.binmode
|
350
|
+
boundary_size = boundary.size + "\r\n".size
|
351
|
+
content_length -= boundary_size
|
352
|
+
status = content_io.read(boundary_size)
|
353
|
+
if nil == status
|
354
|
+
raise EOFError, "no content body"
|
355
|
+
elsif boundary + "\r\n" != status
|
356
|
+
raise EOFError, "bad content body"
|
357
|
+
end
|
358
|
+
|
359
|
+
parts = []
|
360
|
+
|
361
|
+
loop do
|
362
|
+
head = nil
|
363
|
+
if 10240 < content_length
|
364
|
+
require "tempfile"
|
365
|
+
body = Tempfile.new("CGI")
|
366
|
+
else
|
367
|
+
begin
|
368
|
+
require "stringio"
|
369
|
+
body = StringIO.new
|
370
|
+
rescue LoadError
|
371
|
+
require "tempfile"
|
372
|
+
body = Tempfile.new("CGI")
|
373
|
+
end
|
374
|
+
end
|
375
|
+
body.binmode if defined? body.binmode
|
376
|
+
|
377
|
+
until head and /#{quoted_boundary}(?:\r\n|--)/n.match(buf)
|
378
|
+
|
379
|
+
if (not head) and /\r\n\r\n/n.match(buf)
|
380
|
+
buf = buf.sub(/\A((?:.|\n)*?\r\n)\r\n/n) do
|
381
|
+
head = $1.dup
|
382
|
+
""
|
383
|
+
end
|
384
|
+
next
|
385
|
+
end
|
386
|
+
|
387
|
+
if head and ( ("\r\n" + boundary + "\r\n").size < buf.size )
|
388
|
+
body.print buf[0 ... (buf.size - ("\r\n" + boundary + "\r\n").size)]
|
389
|
+
buf[0 ... (buf.size - ("\r\n" + boundary + "\r\n").size)] = ""
|
390
|
+
end
|
391
|
+
|
392
|
+
c = if bufsize < content_length
|
393
|
+
content_io.read(bufsize)
|
394
|
+
else
|
395
|
+
content_io.read(content_length)
|
396
|
+
end
|
397
|
+
if c.nil? || c.empty?
|
398
|
+
raise EOFError, "bad content body"
|
399
|
+
end
|
400
|
+
buf.concat(c)
|
401
|
+
content_length -= c.size
|
402
|
+
end
|
403
|
+
|
404
|
+
buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/n) do
|
405
|
+
body.print $1
|
406
|
+
if "--" == $2
|
407
|
+
content_length = -1
|
408
|
+
end
|
409
|
+
boundary_end = $2.dup
|
410
|
+
""
|
411
|
+
end
|
412
|
+
|
413
|
+
parts << {:head => head, :body => body.string}
|
414
|
+
break if buf.size == 0
|
415
|
+
break if content_length == -1
|
416
|
+
end
|
417
|
+
raise EOFError, "bad boundary end of body part" unless boundary_end =~ /--/
|
418
|
+
parts
|
419
|
+
end
|
420
|
+
|
296
421
|
end
|
297
422
|
|
298
423
|
# Legacy/BC code here. This shouldn't be used in new applications.
|
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.
|
4
|
+
version: 0.4.2
|
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-
|
12
|
+
date: 2009-08-03 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
|
|