3

FileTransfer API を使用して eBay に一括データ交換呼び出しをアップロードしようとしています。これを行うには、xml 要求文字列を eBay サーバーに POST する必要がありますが、xml 要求には<Data>、転送するデータを含める必要があるセクションが含まれています (この場合は、別の xml ドキュメントを含む base64 でエンコードされた zip ファイルです)。 . eBay は、そのようなドキュメントを作成する方法の C# の例を示しています: https://ebay.custhelp.com/app/answers/detail/a_id/1561

httplib を使用して Python でこの例を再作成して、例とほぼ同じ方法で作成した文字列を POST しようとしました (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 リクエストを送信すると、ファイルは問題なく受け入れられます。<xop>しかし、上記のコードのように、MIME マルチパート/関連の添付ファイルと添付ファイル内のデータの場所を示すタグを使用して実行しようとすると、POST が成功せず、「エラー 302: 一時的に移動しました」という応答が返されます。 . これにより、MIME multipart/related xml リクエストの作成方法、「Content-type」ヘッダー宣言の作成方法、xop の使用、または 3 つすべての組み合わせに問題があると思われます。もの。

私の質問は次のとおりだと思います: MIME マルチパート/関連セクションを含み、xop も使用する xml リクエストを作成するにはどうすればよいですか?

助けてくれてありがとう!

ウェス

4

1 に答える 1

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
}

したがって、これらすべてから、問題はヘッダーとリクエストの両方の改行とタブ文字にあることがわかりました。

于 2011-12-15T16:16:16.610 に答える