Created
September 29, 2010 14:42
-
-
Save eimermusic/602864 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
require 'mail' | |
require 'savon' | |
# I needed to send "SOAP with Attachments" and found soap4r too horrible. | |
# Since I saw no support for it in Savon I tried to hack something together | |
# to see if it could be done. I share that messy code here | |
# this is updated for Savon 0.8.1 | |
module Savon | |
module SOAP | |
class Part < Mail::Part | |
# placeholder for SOAP-sepcific improvements | |
end | |
class XML | |
attr_accessor :parts_sort_order | |
# adds a Part object to the current SOAP "message" | |
# Parts are really attachments | |
def add_part(part) | |
@parts ||= Array.new | |
@parts << part | |
end | |
# check if any parts have been added | |
def has_parts? | |
@parts ||= Array.new | |
[email protected]? | |
end | |
# returns the mime message for a multipart request | |
def request_message | |
if @parts.empty? | |
return nil | |
end | |
@request_message = Part.new do | |
content_type 'multipart/related; type="text/xml"' | |
end | |
soap_body = self.to_xml | |
soap_message = Part.new do | |
content_type 'text/xml; charset=utf-8' | |
add_content_transfer_encoding | |
body soap_body | |
end | |
@request_message.add_part(soap_message) | |
@parts.each do |part| | |
@request_message.add_part(part) | |
end | |
#puts @request_message | |
@request_message | |
end | |
end | |
class Request | |
def setup(request, soap) | |
request.url = soap.endpoint | |
if soap.has_parts? # do multipart stuff if soap has parts | |
request_message = soap.request_message | |
# takes relevant http headers from the "Mail" message and makes them Net::HTTP compatible | |
request.headers["Content-Type"] ||= ContentType[soap.version] | |
request.headers.delete "SOAPAction" | |
request_message.header.fields.each do |field| | |
request.headers[field.name] = field.to_s | |
end | |
request_message.body.set_sort_order soap.parts_sort_order if soap.parts_sort_order && soap.parts_sort_order.any? | |
puts request.inspect | |
request.body = request_message.body.encoded | |
else | |
request.headers["Content-Type"] ||= ContentType[soap.version] | |
request.body = soap.to_xml | |
end | |
request | |
end | |
end | |
end | |
end | |
# Usage Example | |
my_header = {'myns:SomeHeader' => 'Some Header Data'} | |
my_body = { | |
'myns:SomeBodyTag' => 'Some Body Data', | |
'myns:Attachment' => 'attachment_name.jpg' | |
} | |
mime_attachment = Savon::Part.new do | |
content_type 'image/jpeg' | |
cid= 'attachment_name.jpg' # this should work... | |
body File.read('path/to/an/image.jpg').force_encoding("BINARY") | |
end | |
# ...but this is needed for a working cid | |
mime_attachment.add_content_id 'attachment_name.jpg' | |
soapclient = Savon::Client.new do | |
wsdl.endpoint = "http://example.com/api/soap" | |
wsdl.namespace = "http://example.com/some/namespace" | |
http.auth.basic 'uname', 'pass' # if you are allowed to post attachments you are likely to need a login | |
end | |
response = soapclient.request :myns, :example_action, 'xmlns:mm7'=>'http://example.com/some/namespace2' do | |
soap.namespaces["xmlns:mm7"] = "http://example.com/some/namespace" | |
soap.header = my_header | |
soap.body = my_body | |
soap.add_part(mime_attachment) | |
end | |
# results: | |
=begin | |
----==_mimepart_4ca34d61dbe3f_7d880445d4c280f3 | |
Date: Wed, 29 Sep 2010 16:29:54 +0200 | |
Message-ID: <4ca34d626abd2_7d880445d4c28299@localhost> | |
Mime-Version: 1.0 | |
Content-Type: text/xml; | |
charset=utf-8 | |
Content-Transfer-Encoding: 7bit | |
Content-ID: <4ca34d6269827_7d880445d4c28127@localhost> | |
<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://example.com/some/namespace"><env:Header><myns:SomeHeader>Some Header Data</myns:SomeHeader></env:Header><env:Body><myns:exampleAction><myns:SomeBodyTag>Some Body Data</myns:SomeBodyTag><myns:Attachment>attachment_name.jpg</myns:Attachment></myns:exampleAction></env:Body></env:Envelope> | |
----==_mimepart_4ca34d61dbe3f_7d880445d4c280f3 | |
Date: Wed, 29 Sep 2010 16:29:54 +0200 | |
Message-ID: <4ca34d626d11a_7d880445d4c28477@localhost> | |
Mime-Version: 1.0 | |
Content-Type: image/jpeg; | |
charset=UTF-8 | |
Content-Transfer-Encoding: base64 | |
Content-ID: <attachment_name.jpg> | |
/9j/4AAQSkZJRgABAgEBLAEsAAD/4RLmRXhpZgAATU0AKgAAAAgABwESAAMA | |
AAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAEx | |
AAIAAAAeAAAAcgEyAAIAAAAUAAAAkIdpAAQAAAABAAAApAAAANAALcbAAAAn | |
... and so on until... | |
+7FWs2XxbwP3ZuLeB+7FWstftD5jNxbwP3Zaq3IbHqO2BX//2Q== | |
----==_mimepart_4ca34d61dbe3f_7d880445d4c280f3-- | |
=end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This code its too old, but there is a new PR for savon on: savonrb/savon#761