添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account Support for multipart/mixed headers that can generate boundary strings and Content-Disposition #11471 Support for multipart/mixed headers that can generate boundary strings and Content-Disposition #11471 stephenlprice opened this issue Nov 22, 2022 · 2 comments

Is there an existing request for this feature?

  • I have searched the existing issues for this feature request and I know that duplicates will be closed
  • Is your feature request related to a problem?

    I have a Postman collection for a Public REST API that is nearly ready to share with our customers. A key workflow on our platform allows users to upload files to their environment via the UI/REST . These "publishing" methods require support for the following header:

    multipart/mixed:
    Content-Type: multipart/mixed; boundary=<calculated when request is sent>

    Adding the header manually in this way does not work:
    Content-Type: multipart/mixed; boundary=--------------------------808837830458042221641451

    I believe this is caused because Postman will also add Content-Disposition: form-data; to the request body as shown in the raw logs for the request. Whereas the manual boundary string is being sent correctly, this mismatched Content-Disposition attribute is unexpected since it should be Content-Disposition: mixed; :

    POST /api/3.16/sites/14d41e12-74ea-4b7d-83bd-ed254673e929/datasources?datasourceType=tdsx HTTP/1.1
    Content-Type: multipart/mixed; boundary=--------------------------808837830458042221641451
    X-Tableau-Auth: 1lSU84EiSBKAXGt_hPU5Gg|VJS7K3mbSJcRro0BSGXoPBBsYu5IBC6k|14d41e12-74ea-4b7d-83bd-ed254673e929
    User-Agent: PostmanRuntime/7.29.2
    Accept: */*
    Cache-Control: no-cache
    Postman-Token: a05306e4-79d0-43de-96f1-8d50b5426a21
    Host: 10ay.online.tableau.com
    Accept-Encoding: gzip, deflate, br
    Connection: keep-alive
    Cookie: AWSELB=A1C7138F06714863BC67FB7B4BBB58E53F877896C9BF741843C826233D1F67A88AB8B733971A833BFCC5EF7A67795ABA4A5EC3D87B74C8D6293A5A1263BB5EFE685E5ECE1C4DFAAE9CBCF370BFCEBB3C0290447EB5; hid=10aypd-hap02
    Content-Length: 1601179
    ----------------------------808837830458042221641451
    Content-Disposition: form-data; name="request_payload"
    Content-Type: text/xml
    <tsRequest>
    <datasource name="SuperStore"
    useRemoteQueryAgent="False"
    description="SuperStore Sales Data Source">
    <project id="4972f17f-a8f8-4a92-a3ec-8f89371cda49" />
    </datasource>
    </tsRequest>
    ----------------------------808837830458042221641451
    Content-Disposition: form-data; name="tableau_datasource"; filename="Sample - Superstore.tdsx"
    Content-Type: application/octet-stream
    <Sample - Superstore.tdsx>
    ----------------------------808837830458042221641451--
    

    Our servers respond to the above request with:

    <error code="400000">
        <summary>Bad Request</summary>
        <detail>Payload is either malformed or incomplete</detail>
    </error>

    Our endpoint requires that the Request Body look like this:

    --boundary-string
    Content-Disposition: name="request_payload"
    Content-Type: text/xml
    <tsRequest>
        <datasource name="Sales"
        useRemoteQueryAgent="False"
        description="Sales Data Source">
            <connectionCredentials name="janedoe"
    	    password="xxxxxx"
    	    embed="True" />
            <project id="ff2a8360-3c2b-4b05-a793-7607c602e1fb" />
        </datasource>
    </tsRequest>
    --boundary-string
    Content-Disposition: name="tableau_datasource"; filename="Sales.TDSX"
    Content-Type: application/octet-stream
    	content-of-datasource-file
    --boundary-string--

    Describe the solution you'd like

    We would like the same level of support for multipart/mixed as is currently offered for multipart/form-data headers. We also have methods that use multipart/form-data and users are able to successfully send requests with Postman.

    Currently, multipart/form-data headers are created by the Postman UI automatically and result in this:
    Content-Type: multipart/form-data; boundary=<calculated when request is sent>

    Which will result in a header that looks like this when sent:
    Content-Type: multipart/form-data; boundary=--------------------------808837830458042221641451

    It is not necessary to significantly alter the current Postman UI, perhaps provide a dropdown so users can choose between mixed and form-data content types under the form-data selector. This will effectively create valid boundary strings automatically for the end user.

    Additionally when selecting multipart/mixed, the Content-Disposition must be set to the correct value (Content-Disposition: mixed;?) rather than Content-Disposition: form-data;.

    Describe alternatives you've considered

    Manually writing the header value. This creates valid Content-Type and boundary strings but will still add form-data as the Content-Disposition.

    I have also tried sending requests using a multipart/form-data header generated automatically by the UI and I get the following error response from our servers:

    <error code="406000">
        <summary>Bad Request</summary>
        <detail>Content type 'multipart/form-data;boundary=--------------------------615924037189507167035811' not supported</detail>
    </error>

    Users can send successful requests via cURL however, it is possible that lack of first-class support for multipart/mixed will make it difficult or impossible to adequately describe the method in a collection and generate valid code without requiring users to understand how to configure a cURL request to make it work.

    There are other similar GH issues that are either open or have been closed as duplicates:
    #8203
    #6933
    #1104
    #6140

    Additional context

    In other words, a key workflow/scenario on our platform is currently blocked since our aim is to enable internal and external stakeholders to send requests and generate valid code without needing to have enough expertise to do so from our API documentation alone.

    This is stopping us from making a public release of the collection to Salesforce's Public Workspace.

    The following cURL request generated by Postman works:

    curl --location --request POST 'https://10ay.online.tableau.com/api/3.16/sites/{{your-site-id}}/datasources?datasourceType=tdsx' \
    --header 'Content-Type: multipart/mixed; boundary=--------------------------808837830458042221641451' \
    --header 'X-Tableau-Auth: {{valid-api-key}}' \
    --header 'Cookie: AWSELB=A1C7138F06714863BC67FB7B4BBB58E53F877896C9BF741843C826233D1F67A88AB8B733971A833BFCC5EF7A67795ABA4A5EC3D87B74C8D6293A5A1263BB5EFE685E5ECE1C4DFAAE9CBCF370BFCEBB3C0290447EB5; hid=10aypd-hap02' \
    --form 'request_payload="<tsRequest>
    	<datasource name=\"SuperStore\"
    	useRemoteQueryAgent=\"False\"
    	description=\"SuperStore Sales Data Source\">
    		<project id=\"4972f17f-a8f8-4a92-a3ec-8f89371cda49\" />
      </datasource>
    </tsRequest>";type=text/xml' \
    --form 'tableau_datasource=@"Sample - Superstore.tdsx"'

    W3 defines multipart/mixed as:

    7.2.2 The Multipart/mixed (primary) subtype
    The primary subtype for multipart, "mixed", is intended for use when the body parts are independent and intended to be displayed serially. Any multipart subtypes that an implementation does not recognize should be treated as being of subtype "mixed".

    Microsoft describes it as:

    multipart/mixed [RFC1521]: The multipart/mixed content type is used when the body parts are independent and need to be bundled in a particular order. When a UA does not recognize a multipart subtype, it will treat the message as multipart/mixed.

    If you look at RFC1521 it indicates that "mixed" is the primary subtype of the multipart content type and a pretty big gap for Postman in that case. On the other hand multipart/form-data is defined under RFC1867 for "Form-based File Upload in HTML".