Search code examples
c#ibm-cloud-infrastructure

Softlayer Object Storage ETag MD5 Checksum Calculation


I'm trying to figure out how to calculate the correct checksum when passing data to the Softlayer Object Storage.

I know the ETag is the issue because if I remove it form the request it works, however I'd prefer to use it to verify the uploads are not corrupt.

This is my method:

    public bool SaveFile(byte[] file, eFetchStorageContainers container, string internalFileName, string fileName = "", bool overPublicNetwork = false)
    {
        Authenticate(overPublicNetwork);

        client = new RestClient(storage_url);
        var resourcePath = string.Format("/{0}/{1}", container, internalFileName);
        var req = new RestRequest(resourcePath, RestSharp.Method.PUT);

        req.AddHeader("X-Auth-Token", auth_token);
        req.AddFile(internalFileName, file, fileName);

        var md5Checksum = BitConverter.ToString(MD5.Create().ComputeHash(file)).Replace("-", string.Empty).ToLower();
        req.AddHeader("ETag", md5Checksum);

        var resp = client.Execute(req);

        return false;
    } 

Here is how the ETag is defined:

enter image description here

I believe the problem lies in the fact that i'm getting the checksum for the file and not the request body.

  1. I want to verify that I should be getting the checksum of the Request Body and NOT the file alone.

  2. If the above is true I'm not even sure how to get the checksum for the body - would love some guidance...


Solution

  • I actually figured this out, I was using RestSharp however its impossible to get the request body.

    I moved over to HttpClient and was able to access the request body to create a checksum.

    var httpClient = new HttpClient();
    httpClient.DefaultRequestHeaders.Add("X-Auth-Token", auth_token);
    var bytes = new ByteArrayContent(file);
    var formData = new MultipartFormDataContent();
    formData.Add(bytes, internalFileName, internalFileName);
    
    // this creates a checksum to send over for verification of non corrupted transfers
    // this is also prevents us from using RestSharp due to its inability to create a checksum of the request body prior to sending
    var md5Checksum = BitConverter.ToString(MD5.Create().ComputeHash(formData.ReadAsByteArrayAsync().Result)).Replace("-", string.Empty).ToLower();
    httpClient.DefaultRequestHeaders.Add("ETag", md5Checksum);
    
    var url = string.Format("{0}/{1}{2}/{3}", storage_url, containerName, folderId, internalFileName);
    var resp = httpClient.PutAsync(url, formData).Result;
    
    httpClient.Dispose();