2011-12-12 73 views
3

我正嘗試使用他們的FileTransfer API將批量數據交換呼叫上傳到eBay。 爲了做到這一點,我必須將一個xml請求字符串發佈到eBay服務器,但xml 請求包含一個<Data>部分,該部分必須包含要傳輸的數據(在這種情況下,它是包含另一個數據的base64編碼zip文件xml文檔)。 eBay在C#中給出了一個如何構建這樣一個文檔的例子:https://ebay.custhelp.com/app/answers/detail/a_id/1561HTTP POST請求和MIME附件multipart/headers和xop的頭?

我一直試圖在python中使用httplib重新創建這個例子來發佈一個字符串我已經以與例子大致相同的方式構建了一個字符串3個UUID唯一):

request = """ 
--MIMEBoundaryurn_uuid_{XMLUUID} 
    Content-Type: application/xop+xml;charset=UTF-8;type="text/xml;charset=UTF-8"; 
    Content-Transfer-Encoding: binary 
    Content-ID:<0.urn:uuid:{REQUUID}> 
    <?xml version="1.0" encoding="utf-8"?> 
    <uploadFileRequest xmlns:sct=\"http://www.ebay.com/soaframework/common/types\" xmlns="http://www.ebay.com/marketplace/services"> 
    <fileAttachment> 
     <Size>{Size}</Size> 
     <Data><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" 
     href="cid:urn:uuid:{ATTCHMNTUUID}>"</Data> 
    </fileAttachment> 
    <fileFormat>{fileFormat}</fileFormat> 
    <fileReferenceId>{fileReferenceId}</fileReferenceId> 
    <taskReferenceId>{taskReferenceId}</taskReferenceId> 
    </uploadFileRequest> 
    --MIMEBoundaryurn_uuid_{XMLUUID} 
    Content-Type: application/octet-stream 
    Content-Transfer-Encoding: binary 
    Content-ID: <urn.uuid:{ATTCHMNTUUID}>\r\n 
    {Data} 
    --MIMEBoundaryurn_uuid_{XMLUUID}-- 
    """.replace("\t", "") 

request_dict = { 
    'Size': size, 
    'Data': payload, 
    'fileFormat': 'zip', 
    'fileReferenceId': '50000935383', 
    'taskReferenceId': '50000847753', 
    'REQUUID': reqUUID, 
    'XMLUUID': xmlUUID, 
    'ATTCHMNTUUID': attchmntUUID, 
} 


request = request.format(**request_dict) 

頁眉看起來像這樣:

headers = { 
'X-EBAY-SOA-OPERATION-NAME': 'uploadFile', 
'X-EBAY-SOA-SERVICE-NAME': 'FileTransferService', 
'X-EBAY-SOA-SECURITY-TOKEN': #Auth Token, 
'Content-type': "multipart/related; boundary=" + boundary + ";type=\"application/xop+xml\";start=\"<0." + "urn:uuid:" + str(requuid) + ">\";start-info=\"text/xml\"" 
} 

,然後我的帖子:

connection = httplib.HTTPSConnection('storage.sandbox.ebay.com') 
connection.request("POST", '/FileTransferService', request, headers) 

當我發佈沒有MIME附件信息的xml請求時,它接受沒有問題的文件。但是當我嘗試像上面的代碼那樣執行操作時,使用MIME多部分/相關附件和<xop>標記指出數據位於附件中的位置,POST未成功,我得到一個「Error 302:Moved Temporarily」響應。這使我相信某些事情與我如何構建MIME multipart/related xml請求,或者我如何構建「Content-type」頭聲明,或者我使用xop,或者很可能是所有三種的東西。

我想我的問題是:如何創建一個包含MIME multipart /相關部分的xml請求,並且還使用xop?

感謝您的幫助!

Wes

回答

2

我想通了我的要求有什麼問題。它是構造請求字符串和標題的組合。我採用了更有組織,更有計劃的方法,並且工作得很好。

下面是建立請求字符串的部分是什麼樣子:

########################################### 
# UUIDs 
########################################### 
reqUUID= uuid.uuid4() 
attchmntUUID = uuid.uuid4() 

########################################## 
# MIME strings 
########################################## 
URN_UUID_REQUEST = "<0.urn:uuid:%s>"% reqUUID 
URN_UUID_ATTACHMENT = "urn:uuid:%s" % attchmntUUID 
MIME_BOUNDARY = "MIME_boundary" 

request_dict = { 
    'Size': size, 
    'Data': payload, 
    'fileFormat': 'gzip', 
    'fileReferenceId': '50000945773', 
    'taskReferenceId': '50000858033', 
    'REQUUID': reqUUID, 
    'ATTCHMNTUUID': attchmntUUID, 
} 


def build_request(request_dict): 
    ''' 
    Build the request string with MIME Attachment 
    ''' 

    request = '<uploadFileRequest xmlns:sct="http://www.ebay.com/soaframework/common/types" xmlns="http://www.ebay.com/marketplace/services">\r\n' 
    request += '<taskReferenceId>%s</taskReferenceId>\r\n' % request_dict['taskReferenceId'] 
    request += '<fileReferenceId>%s</fileReferenceId>\r\n' % request_dict['fileReferenceId'] 
    request += '<fileFormat>%s</fileFormat>\r\n' % request_dict['fileFormat'] 
    request += '<fileAttachment>\r\n' 
    request += '<Size>%s</Size>\r\n'% request_dict['Size'] 
    request += '<Data><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:%s"/></Data>\r\n'%URN_UUID_ATTACHMENT 
    request += '</fileAttachment>\r\n' 
    request += '</uploadFileRequest>\r\n' 

    return request 


def build_mime_message(request, data): 
    ''' 
    Build the xml string with MIME attachments and the base64 encoded data string 
    ''' 

    request_part = '\r\n' 
    request_part += '--%s\r\n' % MIME_BOUNDARY 
    request_part += 'Content-Type: application/xop+xml; charset=UTF-8; type="text/xml; charset=UTF-8"\r\n' 
    request_part += 'Content-Transfer_Encoding: binary\r\n' 
    request_part += 'Content-ID: %s\r\n\r\n' % URN_UUID_REQUEST 
    request_part += '%s\r\n' % request 


    binary_part = '\r\n' 
    binary_part += '--%s\r\n' % MIME_BOUNDARY 
    binary_part += 'Content-Type: application/octet-stream\r\n' 
    binary_part += 'Content-Transfer-Encoding: base64\r\n' 
    binary_part += 'Content-ID: <%s>\r\n\r\n' % URN_UUID_ATTACHMENT 
    binary_part += '%s\r\n' % data 
    binary_part += '--%s--' % MIME_BOUNDARY 

    return request_part + binary_part 

request = build_request(request_dict) 
request = build_mime_message(request, data)#data is base64 encoded gzip compressed xml file 

和頭是這樣的:

content_type_string = 'multipart/related;' 
content_type_string += ' boundary=%s;' % MIME_BOUNDARY 
content_type_string += ' type="application/xop+xml";' 
content_type_string += ' start="%s";' % URN_UUID_REQUEST 
content_type_string += ' start-info="text/xml"' 

headers = { 
'X-EBAY-SOA-OPERATION-NAME': 'uploadFile', 
'X-EBAY-SOA-SERVICE-NAME': 'FileTransferService', 
'X-EBAY-SOA-SECURITY-TOKEN': #auth token, 
'Content-Length': len(request), 
'Content-Type': content_type_string 
} 
從所有這一切

所以,我得知這個問題是與標題和請求中的換行符和製表符。

+0

我想通過這個答案自己使用uploadFile調用。我不斷收到「請指定具有有效格式的文件」。我在內存中生成XML,然後使用base64.standard_b64encode(gzip.compress(full_xml))將其壓縮到base64中 – Nelluk