How to resolve the InvalidMd5 error returned by the Windows Azure Blob storage service?

I am creating an application that should allow users to upload large images (up to 100 MB) to the Windows Azure Blob storage service. After reading Rob Gillen, an excellent article on optimizing file downloads for Windows Azure, I lent his approach to parallel loading file fragments using the CloudBlockBlob.PutBlock () method inside the Parallel.For loop (code available here ).

The problem is that whenever I try to upload a file, I get an InvalidMd5 exception from the repository client . Suspecting that the problem might be in the development repository, I also tried to run the code with my active Azure account, but I got the same error. Looking at traffic with Fiddler I can see that the "Content-MD5" header is set to a valid MD5 hash. The error description states that "An invalid MD5 value specified in the request. The MD5 value must be 128 bits and Base64 encoded." But, as far as I know, the value that I see is sent to Fiddler is valid (for example a91c588092cedbdb1b82c2d3786fd509) .

Here is the code I use to calculate the hash (kindly provided by Rob Gillen):

public static string GetMD5HashFromStream(byte[] data)
{
    MD5 md5 = new MD5CryptoServiceProvider();
    byte[] retVal = md5.ComputeHash(data);

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < retVal.Length; i++)
    {
        sb.Append(retVal[i].ToString("x2"));
    }
    return sb.ToString();
}

PutBlock():

blob.PutBlock(transferDetails[j].BlockId, new MemoryStream(buff), blockHash, options);

:

Convert.ToBase64String(Encoding.UTF8.GetBytes(blockHash))

- "InvalidMd5": (

MD5 PutBlock() base64 (, YTkxYzU4ODA5MmNlZGJkYjFiODJjMmQzNzg2ZmQ1MDk =), (, a91c588092cedbdb1b82c2d3786fd509), , .

Rob code , , . , Rob, - ParallelUpload(), Stream .

, - , , ! ! , .

+3
2

, MD5. . , , , , ( :)) . , :

1) MD5: , , , , , , , , . , GetMD5HashFromStream() 16 , MD5CryptoServiceProvider, 32 . 32- , Base64 PutBlock(), , , , blob. , :

:

public static string GetMD5HashFromStream(byte[] data)
{
    MD5 md5 = new MD5CryptoServiceProvider();
    byte[] retVal = md5.ComputeHash(data);

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < retVal.Length; i++)
    {
        sb.Append(retVal[i].ToString("x2"));
    }
    return sb.ToString();
}

PutBlock():

// calculate the block-level hash
string blockHash = Helpers.GetMD5HashFromStream(buff);
blob.PutBlock(transferDetails[j].BlockId, new MemoryStream(buff), blockHash, options);

:

MD5 md5 = new MD5CryptoServiceProvider();
byte[] blockHash = md5.ComputeHash(buff);
string convertedHash = Convert.ToBase64String(blockHash, 0, 16);
blob.PutBlock(transferDetails[j].BlockId, new MemoryStream(buff), convertedHash, options);

, , - - , , Azure ( v1.2)... , , .

2) : , , :

, , blob, 409 (), BlobAlreadyExists.

, :

public static bool IsDevelopmentStorageRunning()
{
    return new Microsoft.ServiceHosting.Tools.DevelopmentStorage.DevStore().IsRunning();
}

Microsoft.ServiceHosting.Tools.dll, "C:\Program Files\Windows Azure SDK\v1.2\bin" . Parallel.For, :

bool isDevStorageRunning = StorageProxy.IsDevelopmentStorageRunning();
ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = isDevStorageRunning ? 1 : 4;
Parallel.For(0, transferDetails.Length, parallelOptions, j => { ... });

, - , . , :)

+3

tishon,

, , (, ?).

, , md5, ... , , md5 , ( ):

-MD5: D1Mxthoqhlwm9cC0729mWA ==

, , , / ID base64, , Azure .

, , rob gillenfamily.net, ... , .

Rob

+3

Source: https://habr.com/ru/post/1772886/


All Articles