Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

Question Patch Request not available in UWR

Discussion in 'Unity Cloud Content Delivery' started by roshaantariq, Nov 14, 2020.

  1. roshaantariq

    roshaantariq

    Joined:
    Dec 6, 2017
    Posts:
    32
    Hi,

    I am trying to upload the content to my created entry but the Patch request is not available in UWR and I tried to use a work around but then I get the 400 Bad Request Response.

    Code (CSharp):
    1. private IEnumerator UploadContentForEntryAsync(string bucketID, string entryID, string filePath, string fileName)
    2.     {
    3.         string requestURL = "https://content-api.cloud.unity3d.com/api/v1/buckets/" + bucketID + "/entries/" + entryID + "/content";
    4.  
    5.         byte[] dataInBytes = File.ReadAllBytes(filePath);
    6.  
    7.         //List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
    8.         //formData.Add(new MultipartFormFileSection("file", dataInBytes));
    9.  
    10.         WWWForm formData1 = new WWWForm();
    11.         formData1.AddBinaryData("file", dataInBytes);
    12.  
    13.         using (UnityWebRequest uploadContentForEntryRequest = new UnityWebRequest(requestURL,"patch"))
    14.         {
    15.             uploadContentForEntryRequest.method = "patch";
    16.             uploadContentForEntryRequest.SetRequestHeader("Authorization", "Basic " + GetAuthToken());
    17.             uploadContentForEntryRequest.SetRequestHeader("Accept", "application/json");
    18.             uploadContentForEntryRequest.SetRequestHeader("Content-Type", "application/rtf");
    19.  
    20.             //byte[] bo = UnityWebRequest.GenerateBoundary();
    21.             //byte[] b = UnityWebRequest.SerializeFormSections(formData, bo);
    22.  
    23.             UploadHandlerRaw uploadHandler = new UploadHandlerRaw(formData1.data);
    24.             //uploadHandler.contentType = "multipart/form-data";
    25.             uploadContentForEntryRequest.uploadHandler = uploadHandler;
    26.  
    27.             DownloadHandlerBuffer downloadHandler = new DownloadHandlerBuffer();
    28.             uploadContentForEntryRequest.downloadHandler = downloadHandler;
    29.  
    30.             UploadContentForEntryRequestStatus = RequestStatus.InProgress;
    31.             yield return uploadContentForEntryRequest.SendWebRequest();
    32.  
    33.             if (uploadContentForEntryRequest.isHttpError || uploadContentForEntryRequest.isNetworkError)
    34.             {
    35.                 Debug.LogError("Error Occurred - UploadContentForEntryAsync");
    36.                 Debug.LogError("Error: " + uploadContentForEntryRequest.error);
    37.                 Debug.LogError("Response Code: " + uploadContentForEntryRequest.responseCode);
    38.                 UploadContentForEntryRequestStatus = RequestStatus.Failed;
    39.             }
    40.  
    41.             else
    42.             {
    43.                 Debug.Log("Request Successful");
    44.  
    45.                 switch (uploadContentForEntryRequest.responseCode)
    46.                 {
    47.                     case 204:
    48.                         Debug.Log("Result: Uploaded File Successfully");
    49.                         break;
    50.  
    51.                     default:
    52.                         Debug.LogError("Other Response Code - UploadContentForEntryAsync: " + uploadContentForEntryRequest.responseCode);
    53.                         break;
    54.                 }
    55.  
    56.                 UploadContentForEntryRequestStatus = RequestStatus.Success;
    57.             }
    58.         };
    59.  
    60.         StopCoroutine(currentRoutineExecuting);
    61.     }
     
  2. timtunity3d

    timtunity3d

    Unity Technologies

    Joined:
    Oct 1, 2015
    Posts:
    134
    Hi,

    I've opened a ticket for myself to document this better. But it should work if you change your ContentType to this:

    Code (CSharp):
    1. uploadContentForEntryRequest.SetRequestHeader("Content-Type", "application/offset+octet-stream");
    The ContentType referred to here is telling the web server how you're uploading it. The content type of the file you're uploading is saved when you create the entry from the ContentType field in the JSON you POST.
     
  3. roshaantariq

    roshaantariq

    Joined:
    Dec 6, 2017
    Posts:
    32
    I have done the same but still getting 406 HTTP Response in return, below is my updated code
    Code (CSharp):
    1. string requestURL = "https://content-api.cloud.unity3d.com/api/v1/buckets/" + bucketID + "/entries/" + entryID + "/content";
    2.  
    3.         byte[] dataInBytes = File.ReadAllBytes(filePath);
    4.        
    5.         using (UnityWebRequest uploadContentForEntryRequest = new UnityWebRequest(requestURL,"PATCH"))
    6.         {
    7.             uploadContentForEntryRequest.method = "PATCH";
    8.             uploadContentForEntryRequest.SetRequestHeader("Authorization", "Basic " + GetAuthToken());
    9.             uploadContentForEntryRequest.SetRequestHeader("Accept", "application/json");
    10.             uploadContentForEntryRequest.SetRequestHeader("Content-Type", "application/offset+octet-stream");
    11.  
    12.             UploadHandlerRaw uploadHandler = new UploadHandlerRaw(dataInBytes);
    13.             uploadContentForEntryRequest.uploadHandler = uploadHandler;
    14.  
    15.             DownloadHandlerBuffer downloadHandler = new DownloadHandlerBuffer();
    16.             uploadContentForEntryRequest.downloadHandler = downloadHandler;
    17.  
    18.             UploadContentForEntryRequestStatus = RequestStatus.InProgress;
    19.             yield return uploadContentForEntryRequest.SendWebRequest();
    20.  
    21.             if (uploadContentForEntryRequest.isHttpError || uploadContentForEntryRequest.isNetworkError)
    22.             {
    23.                 Debug.LogError("Error Occurred - UploadContentForEntryAsync");
    24.                 Debug.LogError("Error: " + uploadContentForEntryRequest.error);
    25.                 Debug.LogError("Response Code: " + uploadContentForEntryRequest.responseCode);
    26.                 UploadContentForEntryRequestStatus = RequestStatus.Failed;
    27.             }
    28.  
    29.             else
    30.             {
    31.                 Debug.Log("Request Successful");
    32.  
    33.                 switch (uploadContentForEntryRequest.responseCode)
    34.                 {
    35.                     case 204:
    36.                         Debug.Log("Result: Uploaded File Successfully");
    37.                         break;
    38.  
    39.                     default:
    40.                         Debug.LogError("Other Response Code - UploadContentForEntryAsync: " + uploadContentForEntryRequest.responseCode);
    41.                         break;
    42.                 }
    43.  
    44.                 UploadContentForEntryRequestStatus = RequestStatus.Success;
    45.             }
    46.         };
     
  4. timtunity3d

    timtunity3d

    Unity Technologies

    Joined:
    Oct 1, 2015
    Posts:
    134
    So did you get any more information with the 406 error code? That code usually means that the file you uploaded does not match the information you sent with CreateEntry. The most likely culprits are file size and ContentHash. The md5sum you specify when you create the entry must match the md5sum of the content uploaded and the file sizes must match. The detailed error message for the 406 should hopefully give you information on whether it's a Size or Checksum Mismatch.
     
  5. roshaantariq

    roshaantariq

    Joined:
    Dec 6, 2017
    Posts:
    32
    Hmm... If I'm using the same file then how can the file size be different or how can the checksum be different? Can you please share the recommended way for calculating the file checksum?
     
  6. timtunity3d

    timtunity3d

    Unity Technologies

    Joined:
    Oct 1, 2015
    Posts:
    134
    The checksum should simply be an md5sum. There are quite a few resources online for generating them in CSharp. They should be lower case letters and digits. No dashes.
     
  7. roshaantariq

    roshaantariq

    Joined:
    Dec 6, 2017
    Posts:
    32
    I have compared my calculated checksum with an online checksum tool and both generated the same checksum (screenshot attached)
     

    Attached Files:

  8. roshaantariq

    roshaantariq

    Joined:
    Dec 6, 2017
    Posts:
    32
    I got the error/logical error, the checksum I calculated was correct the only mistake was that I was sending the checksum in uppercase instead of lowercase. As soon as I converted the checksum string to lowercase the API accepted the request and uploaded the file successfully.

    What I would suggest is that the document/API should specify if the API accepts the checksum or any string/data in a specific format, if I haven't been notified about the lowercase scenario I wouldn't have resolved the issue
     
  9. timtunity3d

    timtunity3d

    Unity Technologies

    Joined:
    Oct 1, 2015
    Posts:
    134
    Sorry about that. I can totally understand the frustration. I've added a task to better document the hashes.
     
  10. roshaantariq

    roshaantariq

    Joined:
    Dec 6, 2017
    Posts:
    32
    sure, no problem. And thank you for all the help :)