HTTP POST 请求和带有 MIME 附件多部分/相关和 xop 的标头?

发布于 2024-12-21 00:21:04 字数 2721 浏览 0 评论 0原文

我正在尝试使用 eBay 的 FileTransfer API 上传批量数据交换调用。 为了做到这一点,我必须将 xml 请求字符串发布到 eBay 服务器,但 xml 请求包含 部分,该部分必须包含您正在传输的数据(在本例中,它是包含另一个 xml 文档的 base64 编码的 zip 文件)。 eBay 给出了一个 C# 示例,说明如何构建此类文档: https://ebay .custhelp.com/app/answers/detail/a_id/1561

我一直在尝试使用 httplib 在 python 中重新创建这个示例,以发布我以与示例(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\""
}

然后是我的 POST:

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

当我发布不带 MIME 附件信息的 xml 请求时,它会毫无问题地接受文件。但是,当我尝试像上面的代码一样,使用 MIME 多部分/相关附件和 标记指出数据在附件中的位置时,POST 不成功并且我收到“错误 302:暂时移动”响应。这让我相信我构建 MIME 多部分/相关 xml 请求的方式,或者我构建“Content-type”标头声明的方式,或者我对 xop 的使用,或者很可能是所有三者的组合,有些东西是不正确的事物。

我想我的问题是:如何创建包含 MIME 多部分/相关部分并且还使用 xop 的 xml 请求?

感谢您的帮助!

韦斯

I'm trying to upload a bulk data exchange call to eBay using their FileTransfer API.
In order to do this, I've got to POST an xml request string to the eBay server but the xml
request contains a <Data> section that must include the data you're transferring( in this case it's a base64 encoded zipfile containing another xml document). eBay gives an example in C# of how to construct such a document: https://ebay.custhelp.com/app/answers/detail/a_id/1561

I've been trying to recreate this example in python using httplib to POST a string I've constructed in much the same fashion as the example(the 3 UUIDs are unique):

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 )

With headers that look like this:

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\""
}

and then my POST:

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

When I post the xml request without the MIME attachment information it accepts the file with no problems. But when I try to do it like the above code, with MIME multipart/related attachments and the <xop> tag pointing out where the data is located in the attachment, the POST isn't successful and I get a "Error 302: Moved Temporarily" response. This leads me to believe that something isn't right with how I constructed the MIME multipart/related xml request, or how I constructed the "Content-type" header declaration, or my use of xop, or most likely a combination of all three things.

I guess my question is: How do I create an xml request that contains MIME multipart/related sections and also uses xop?

Thanks for the help!

Wes

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光病人 2024-12-28 00:21:04

我发现我的要求出了什么问题。它是构造请求字符串和标头的组合。我采用了一种更有组织性和程序性的方法来实现它,并且它奏效了。

构建请求字符串的部分如下所示:

###########################################
# 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
}

因此,从所有这些来看,我发现问题出在标头和请求中的换行符和制表符。

I figured out what was wrong with my request. It's a combination of constructing the request string and also the headers. I went with a much more organized and programmatic approach to it, and it worked.

Here's what the section that builds the request string looks like:

###########################################
# 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

And the headers look like this:

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
}

So from all of this, I gathered that the problem was with the newlines and the tab characters in both the header and request.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文