Для моего проекта Ruby on Rails я использую гем Mail для создания многочастного HTTP-запроса POST, используя Net::HTTP::Post::Multipart
.Мой запрос HTTP POST содержит часть xml
, часть smil
и часть изображения jpeg
.
Сначала я использовал Nokogiri
для создания части xml
:
env_ns = {
"xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/"
}
mm7_ns = {
"xmlns:mm7" => "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-6-MM7-1-4"
}
builder = Nokogiri::XML::Builder.new do |xml|
xml['env'].Envelope(env_ns) do
xml.Header do
xml['mm7'].TransactionID(mm7_ns, 'xxxx-yyyy-zzzz')
end
xml.Body do
xml.SubmitReq("xmlns" => "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-6-MM7-1-4") do
xml.MM7Version(nil, '6.8.0')
xml.SenderIdentification do
xml.VASPID(nil, Settings.mms.vasp_id)
xml.VASID(nil, Settings.mms.vas_id)
xml.SenderAddress do
xml.Number(nil, 'XXXXXX')
end
end
xml.Recipients do
xml.To do
xml.Number(nil, '+1604XXXXXXX')
end
end
xml.DeliveryReport(nil, false)
xml.Subject(nil, 'a ruby photo')
xml.Content({"href"=>'cid:generic_content_id'})
end
end
end
end
Затем я настроил запрос, используя почтовый гем:
uri = URI.parse('http://example.com') ##This is not the actual url I'm using. Just for illustration purposes.
client = Net::HTTP.new(uri.host, uri.port)
mail = Mail.new do
content_type 'multipart/related; type="text/xml"'
end
Затем я создаю часть XML (я называю это soap_part
в коде) и часть smil идобавьте их в запрос:
soap_part = Mail::Part.new do
content_type 'text/xml; charset="us-ascii"'
body builder.to_xml
end
smil_part = Mail::Part.new do
content_type 'application/smil; name=presentation.smil; start=photo'
content_id 'presentation'
content_disposition 'attachment; filename=presentation.smil'
body '<smil xmlns="http://www.w3.org/2001/SMIL20/Language"><head><layout></layout></head><body><seq><img src="cid:photo"/></seq></body></smil>'
end
mail.add_part(soap_part)
mail.add_part(smil_part)
Затем я добавлю фотографию в виде вложения:
mail.add_file('script/photo.jpg')
mail.parts.last.content_id = 'photo'
Наконец, я отправляю запрос после установки некоторых параметров:
http_headers = {"Content-Type" => 'multipart/related'}
mail.header.fields.each do |field|
http_headers[field.name] = field.to_s
end
uri = URI(url)
request = Net::HTTP::Post::Multipart.new(uri, http_headers)
request["Content-Type"] ="multipart/related; boundary=#{mail.body.boundary}"
request.body = mail.body.encoded
response = client.request(request)
puts response.body
Используя wireshark, получаемый запрос был примерно таким:
POST /somecompany/servlet/messagerouter HTTP/1.1
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: */*
User-Agent: Ruby
Host: websvcs1.somecompany.com
Content-Type: multipart/related; boundary=--==_mimepart_5c740b7859587_45bfe6af142246e
Content-Length: 8046
Connection: close
----==_mimepart_5c740b7859587_45bfe6af142246e
Content-Type: text/xml;
charset=us-ascii
Content-Transfer-Encoding: 7bit
<?xml version="1.0"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<mm7:TransactionID xmlns:mm7="http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-6-MM7-1-4">xxxx-yyyy-zzzz</mm7:TransactionID>
</env:Header>
<env:Body>
<SubmitReq xmlns="http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-6-MM7-1-4">
<MM7Version>6.8.0</MM7Version>
<SenderIdentification>
<VASPID>ivrnet-qa</VASPID>
<VASID>ivrnet-qa</VASID>
<SenderAddress>
<Number>XXXXXX</Number>
</SenderAddress>
</SenderIdentification>
<Recipients>
<To>
<Number>+1604XXXXXXX</Number>
</To>
</Recipients>
<DeliveryReport>false</DeliveryReport>
<Subject>a ruby photo</Subject>
<Content href="cid:generic_content_id"/>
</SubmitReq>
</env:Body>
</env:Envelope>
----==_mimepart_5c740b7859587_45bfe6af142246e
Content-Type: application/smil;
charset=UTF-8;
name=presentation.smil;
start=photo
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename=presentation.smil
content-id: presentation
<smil xmlns="http://www.w3.org/2001/SMIL20/Language"><head><layout></layout></head><body><seq><img src="cid:photo"/></seq></body></smil>
----==_mimepart_5c740b7859587_45bfe6af142246e
Content-Type: image/jpeg;
charset=UTF-8;
filename=photo.jpg
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename=photo.jpg
content-id: photo
iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAC7mlDQ1BJQ0Mg...
----==_mimepart_5c740b7859587_45bfe6af142246e--
Ответ, который я получил от сервера:
<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Protocol</faultcode>
<faultstring>Missing content type.</faultstring>
<faultactor>/xiam-soap/servlet/messagerouter</faultactor>
</SOAP-ENV:Fault>
Согласно MIME Multipart / Related Content-введите
Я попытался изменить request["Content-Type"] ="multipart/related; boundary=#{mail.body.boundary}
на request["Content-Type"] ="multipart/related; boundary=#{mail.body.boundary}; type=Application/X-FixedRecord"
, но не уверен, что будет делать «Application / X-FixedRecord».Тем не менее, я все еще получаю точно такую же ошибку.
Как решить эту проблему?Благодарю.