对于我的Ruby on Rails项目,我正在使用Mail gem通过Net::HTTP::Post::Multipart
创建多部分HTTP POST请求。我的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
然后我使用邮件gem设置请求:
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-type
我尝试将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'会做什么。但是,我仍然遇到完全相同的错误。
该如何解决?谢谢。