Search Unity

Bug [Solved] Unity Web Request POST doesn't work, even if it works in PostMan

Discussion in 'Scripting' started by Fangh, Apr 18, 2023.

  1. Fangh

    Fangh

    Joined:
    Apr 19, 2013
    Posts:
    274
    I try to use this API : https://platform.openai.com/docs/api-reference/audio?lang=curl

    and I need to send a file in a form.

    This is my Postman request

    upload_2023-4-18_11-10-46.png
    upload_2023-4-18_11-11-10.png

    and it works.

    This is the curl version of it :

    curl --request POST \
    --url https://api.openai.com/v1/audio/transcriptions \
    --header 'Authorization: Bearer API_KEY' \
    --header 'Content-Type: multipart/form-data' \
    --cookie _cfuvid=7jLxP_RBpa8VZB6aqrEPYxvlnCLBOBa7drTr8x0bA.I-1681807430028-0-604800000 \
    --form file=@/Users/morgan/Documents/GitHub/Test/Assets/record.wav \
    --form model=whisper-1


    This is my UnityWebRequest :

    upload_2023-4-18_11-12-20.png

    And it give me 400 BAD REQUEST.

    Why ?
     
    Last edited: Apr 18, 2023
    Bunny83 likes this.
  2. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    Use Fiddler or similar and examine the sent request. Compare it against what Postman sends.
     
    Kurt-Dekker likes this.
  3. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,992
    Please don't post code in images. We can't refer to the code without retyping your code. Why do you add 2 file sections? You supposed to post form data as well as a file upload. Form data and binary file data will be in separate parts of the multipart request. The form data should be url encoded form data. However you add 2 file uploads to your request.

    I'm kinda surprised that Unity's new IMultipartFormSection system doesn't provide a more convenient way to add form data like the old WWWForm class did. The simplest solution would probably be to use a MultipartFormDataSection for your form field and set the contentType to "text/plain" or "text/html; charset=utf-8" with this constructor:

    Code (CSharp):
    1. public MultipartFormDataSection(string name, string data, string contentType);
    Though your major issue is that you manually overwrite your request contentType. Don't do that. A multipart content type requries a boundary marker which Unity generates internally for the multipart sections you pass into "Post". That boundary marker is appended after the content type. Since you overwrite the content type, you erase that and the request becomes malformed. See the example on wikipedia. Note that the boundary is usually a random sequence of characters as the boundary MUST NOT appear anywhere inside a section.

    Unity creates the boundary here and the content type (with the boundary) is set here.
     
    Fangh and Kurt-Dekker like this.
  4. Fangh

    Fangh

    Joined:
    Apr 19, 2013
    Posts:
    274
    Thank you. It works !
    I removed the contentType. I had no Idea I shouldn't use it ! Because I used some ContentType for other requests and it was working.

    This code is working :

    Code (CSharp):
    1.     IEnumerator Upload()
    2.     {
    3.         byte[] audioFileBytes = File.ReadAllBytes(audioFilePath);
    4.  
    5.         WWWForm form = new WWWForm();
    6.         form.AddField("model", modelName);
    7.         form.AddBinaryData("file", audioFileBytes, audioFilePath);
    8.  
    9.         using (UnityWebRequest request = UnityWebRequest.Post(url, form))
    10.         {
    11.             request.SetRequestHeader("Authorization", $"Bearer {key}");
    12.             //request.SetRequestHeader("Content-Type", "multipart/form-data");
    13.  
    14.             yield return request.SendWebRequest();
    15.  
    16.             if (request.result != UnityWebRequest.Result.Success)
    17.             {
    18.                 Debug.Log(request.error);
    19.             }
    20.             else
    21.             {
    22.                 Debug.Log("Form upload complete!");
    23.                 Debug.Log(request.downloadHandler.text);
    24.             }
    25.         }
    26. }
     
    WendelinReich and Bunny83 like this.