Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions lib/savon/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require "savon/header"
require "savon/message"
require "savon/effective_options"
require "savon/mtom"
require "nokogiri"
require "builder"
require "gyoku"
Expand All @@ -18,6 +19,8 @@ module Savon
# serialization is delegated to {Savon::Message}, the Header element to
# {Savon::Header}, and Hash-to-XML conversion to Gyoku.
class Builder
include Mtom

attr_reader :multipart

SCHEMA_TYPES = {
Expand Down Expand Up @@ -277,15 +280,17 @@ def build_multipart_message(message_xml)

# the mail.body.encoded algorithm reorders the parts, default order is [ "text/plain", "text/enriched", "text/html" ]
# should redefine the sort order, because the soap request xml should be the first
multipart_message.body.set_sort_order ["text/xml"]
multipart_message.body.set_sort_order ['application/xop+xml', 'text/xml']

multipart_message.body.encoded(multipart_message.content_transfer_encoding)
end

def init_multipart_message(message_xml)
multipart_message = Mail.new
apply_mtom_encoding(multipart_message, message_xml) if @locals[:mtom]
type = xml_part_content_type
xml_part = Mail::Part.new do
content_type 'text/xml'
content_type type
body message_xml
# in Content-Type the start parameter is recommended (RFC 2387)
content_id '<soap-request-body@soap>'
Expand Down
19 changes: 19 additions & 0 deletions lib/savon/mtom.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module Savon
# MTOM request encoding (https://www.w3.org/TR/soap12-mtom/) for {Savon::Builder}.
module Mtom
private

def apply_mtom_encoding(multipart_message, message_xml)
multipart_message.transport_encoding = 'binary'
message_xml.force_encoding('BINARY')
end

def xml_part_content_type
return 'text/xml' unless @locals[:mtom]

"application/xop+xml; charset=#{@globals[:encoding]}; type=\"text/xml\""
end
end
end
22 changes: 15 additions & 7 deletions lib/savon/operation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,22 @@ def soap_headers(builder)

if builder.multipart
# RFC 2387 §3 (multipart/related) - SOAP envelope is the root body part
headers["Content-Type"] = [
"multipart/related",
"type=\"#{SOAP_REQUEST_TYPE[@globals[:soap_version]]}\"",
"start=\"#{builder.multipart[:start]}\"",
"boundary=\"#{builder.multipart[:multipart_boundary]}\""
].join("; ")
content_type = ["multipart/related"]

if @locals[:mtom]
# SOAP 1.2 MTOM §3.1 - the root part is an XOP package
content_type << "type=\"application/xop+xml\""
content_type << "start-info=\"application/soap+xml\""
else
content_type << "type=\"#{SOAP_REQUEST_TYPE[@globals[:soap_version]]}\""
end

content_type << "start=\"#{builder.multipart[:start]}\""
content_type << "boundary=\"#{builder.multipart[:multipart_boundary]}\""

headers["Content-Type"] = content_type.join("; ")
headers["MIME-Version"] = "1.0"
headers["Accept-Encoding"] = "gzip,deflate"
headers["Accept-Encoding"] = "gzip,deflate" unless @locals[:mtom]
else
headers["Content-Type"] = CONTENT_TYPE[@globals[:soap_version]] % @globals[:encoding]
end
Expand Down
8 changes: 7 additions & 1 deletion lib/savon/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,8 @@ def initialize(options = {})
defaults = {
advanced_typecasting: true,
response_parser: :nokogiri,
multipart: false
multipart: false,
mtom: false
}

super defaults.merge(options)
Expand Down Expand Up @@ -562,6 +563,11 @@ def attachments(attachments)
@options[:attachments] = attachments
end

# MTOM attachments https://www.w3.org/TR/soap12-mtom/
def mtom(mtom)
@options[:mtom] = mtom
end

# Value of the SOAPAction HTTP header.
def soap_action(soap_action)
@options[:soap_action] = soap_action
Expand Down
2 changes: 1 addition & 1 deletion lib/savon/transport/logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def headers_to_log(headers)
end

def body_to_log(body)
LogMessage.new(body, @globals[:filters], @globals[:pretty_print_xml]).to_s
LogMessage.new(body, @globals[:filters], @globals[:pretty_print_xml]).to_s.force_encoding(@globals[:encoding])
end
end
end
Expand Down
Loading