2016-02-22 49 views
2

我必須通過多部分/相關HTTP POST將文件發送到SOAP服務器。如何將Python中的多部分/相關請求發送到SOAP服務器?

我已經建立了消息從頭開始是這樣的:

from email.mime.application import MIMEApplication 
from email.encoders import encode_7or8bit 
from email.mime.multipart import MIMEMultipart 
from email.mime.base import MIMEBase 

envelope = """<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:xmime5="http://www.w3.org/2005/05/xmlmime" xmlns:osc-data="http://oracc.org/wsdl/ows.xsd" xmlns:osc-meth="http://oracc.org/wsdl/ows.wsdl"><SOAP-ENV:Body><osc-meth:Request><osc-data:keys><osc-data:key>atf</osc-data:key><osc-data:key>tests/mini</osc-data:key><osc-data:key>00atf/hyphens.atf</osc-data:key></osc-data:keys><osc-data:data><osc-data:item xmime5:contentType="*/*"><xop:Include href="cid:id6"/></osc-data:item></osc-data:data></osc-meth:Request></SOAP-ENV:Body></SOAP-ENV:Envelope>""" 

mtompkg = MIMEMultipart('related',boundary='============boundary============', charset='utf-8', type='application/xop+xml', start='<SOAP-ENV:Envelope>') 
#Doesn't like the hyphen in start-info when passing as MIMEMultipart param 
mtompkg.set_param('start-info', 'application/soap+xml') 
mtompkg['Host'] = "http://oracc.museum.upenn.edu:8085" 
mtompkg['Connection'] = "close" 
del(mtompkg['mime-version']) 

rootpkg = MIMEApplication(envelope, 'xop+xml', encode_7or8bit) 
rootpkg.set_param('charset', 'utf-8') 
rootpkg.set_param('type', 'application/soap+xml') 
rootpkg.add_header('Content-ID', '<SOAP-ENV:Envelope>') 
del(rootpkg['Content-Transfer-Encoding']) 
rootpkg.add_header('Content-Transfer-Encoding', 'binary') 
del(rootpkg['mime-version']) 

mtompkg.attach(rootpkg) 

document = MIMEBase('*','*') 
document['Content-Transfer-Encoding'] = "binary" 
document['Content-ID'] = "<id6>" 
filename = "./request.zip" 
document.set_payload(open(filename,'rb').read()) 
del(document['mime-version']) 

mtompkg.attach(document) 

bound = '--%s' % (mtompkg.get_boundary(),) 
marray = mtompkg.as_string().split(bound) 
mtombody = bound 
mtombody += bound.join(marray[1:]) 

mtompkg.add_header("Content-Length", str(len(mtombody))) 

導致樣品一個我從SOAP服務器開發者,我們知道有相匹配的信息工作正常:

Content-Type: multipart/related; start="<SOAP-ENV:Envelope>"; charset="utf-8"; 
type="application/xop+xml"; boundary="============boundary============"; 
start-info="application/soap+xml" 
Host: http://MY_URL:SOME_PORT 
Connection: close 
Content-Length: 1429 

--============boundary============ 
Content-Type: application/xop+xml; charset="utf-8"; type="application/soap+xml" 
Content-ID: <SOAP-ENV:Envelope> 
Content-Transfer-Encoding: binary 

<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:xmime5="http://www.w3.org/2005/05/xmlmime" xmlns:osc-data="http://oracc.org/wsdl/ows.xsd" xmlns:osc-meth="http://oracc.org/wsdl/ows.wsdl"><SOAP-ENV:Body><osc-meth:Request><osc-data:keys><osc-data:key>atf</osc-data:key><osc-data:key>tests/mini</osc-data:key><osc-data:key>00atf/hyphens.atf</osc-data:key></osc-data:keys><osc-data:data><osc-data:item xmime5:contentType="*/*"><xop:Include href="cid:id6"/></osc-data:item></osc-data:data></osc-meth:Request></SOAP-ENV:Body></SOAP-ENV:Envelope> 
--============boundary============ 
Content-Type: */* 
Content-Transfer-Encoding: binary 
Content-ID: <id6> 

P�AtG.�Uen00atf/hyphens.atfUT cOVJOVux 
             �S 
              04A.傢���+����b��L.�Ē4+���T�Ҽ���T.�PNb^�BEi���BuN飦�ڌDݤLݢR.��\+�Ĥ̢�h0��P�AtG.�Uen��00atf/hyphens.atfUTcOVux 
                    �PKW� 
--============boundary============-- 

發送它,我已經嘗試過請求,urllib2和httplib,我得到的行爲是服務器永遠掛起。我試着設置一個超時希望能給我從服務器的某種輸出,但它不起作用。這是我已經試過:

隨着請求:

import requests 
url = 'http://MY_URL:SOME_PORT' 
headers = dict(mtompkg.items()) 
body = mtompkg.as_string().split('\n\n', 1)[1] 
response = requests.post(url, data=body, headers=headers) 

用的urllib2:

import urllib2 
request = urllib2.Request('http://MY_URL:SOME_PORT', body, headers) 
urllib2.urlopen(request).read() 

隨着httplib的:

import urlparse 
import httplib 
schema, netloc, url, params, query, fragments = urlparse.urlparse('http://MY_URL:SOME_PORT') 
http = httplib.HTTPConnection(netloc) 
http.connect() 
http.putrequest("POST", 'http://MY_URL:SOME_PORT') 
http.putheader('Content-type', mtompkg['Host']) 
http.putheader('Content-type',mtompkg['Content-Type']) 
http.putheader('Content-Length", str(1429)) 
http.endheaders() 
http.send(body) 
response = http.getresponse() 

更高級別的選項,如肥皂水,suds- jurko,SOAPpy等似乎不支持多種形式/相關附件。我沒有足夠的選項來測試,所以任何形式的幫助都會讓你倍感欣慰。

+0

HTTP://docs.python- requests.org/en/master/user/quickstart/#post-a-multipart-encoded-file –

+1

謝謝!我現在試試:) – zapatilla

+0

它似乎只適用於multipart/form-data,而不是multipart/related,這是我的情況。 – zapatilla

回答

1

我能夠得到這個工作,通過將下面的行此行後 體= mtompkg.as_string()。分裂( '\ n \ n',1)[1]

RFC規格詢問您要使用\ r \ n個代替\ n個蟒默認

體= body.replace( '\ n', '\ r \ N',5)

相關問題