2013-11-09 33 views
2

我正在使用Amazon S3進行實施。我使用Amazon C# SDK,並嘗試使用putObject方法上傳創建的ZIP文件。使用MD5哈希上傳流將導致「您指定的Content-MD5無效」

當我上傳的文件,我得到以下錯誤:

{Amazon.S3.AmazonS3Exception: The Content-MD5 you specified was invalid 

我產生的罰款和工作的MemoryStream,我可以把它上傳到Amazon S3沒有錯誤。但是,當我提供以下行時,會給我帶來問題:

request.MD5Digest = md5; 

我是否證明了MD5的正確方法?我的MD5代是否正確?或者還有其他問題嗎?

要求我上傳的代碼

Once the Zip file has been created and you have calculated an MD5 sum value of that file, you should 
transfer the file to the AWS S3 bucket identified in the S3Access XML. 
Transfer the file using the AmazonS3, PutObjectRequest and TransferManagerclasses. 
Ensure the following meta data attributes are included via adding an ObjectMetaDataclass instance to the 
PutObjectRequest: 
• MD5Sum (via setContentMD5) 
• Mime ContentType (setContentType) 

我上傳的代碼

的client.PutObject()給出了錯誤:

public void UploadFile(string bucketName, Stream uploadFileStream, string remoteFileName, string md5) 
     { 
      using (client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKeyID, secretAccessKeyID, config)) 
      { 
       try 
       { 
        StringBuilder stringResp = new StringBuilder(); 

        PutObjectRequest request = new PutObjectRequest(); 
        // request.MD5Digest = md5; 
        request.BucketName = bucketName; 
        request.InputStream = uploadFileStream; 
        request.Key = remoteFileName; 
        request.MD5Digest = md5; 

        using (S3Response response = client.PutObject(request)) 
        { 
         WebHeaderCollection headers = response.Headers; 
         foreach (string key in headers.Keys) 
         { 
          stringResp.AppendLine(string.Format("Key: {0}, value: {1}", key,headers.Get(key).ToString())); 
          //log headers ("Response Header: {0}, Value: {1}", key, headers.Get(key)); 
         } 
        } 
       } 
       catch (AmazonS3Exception amazonS3Exception) 
       { 
        if (amazonS3Exception.ErrorCode != null && (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId") || amazonS3Exception.ErrorCode.Equals("InvalidSecurity"))) 
        { 
         //log exception - ("Please check the provided AWS Credentials."); 
        } 
        else 
        { 
         //log exception -("An error occurred with the message '{0}' when writing an object", amazonS3Exception.Message); 
        } 
       } 
      } 
     } 

總體方法

我的過程方法(查看整體流程)。很抱歉的代碼的當前狀態,這是更僞代碼比生產代碼:

public void Process(List<Order> order) 
    { 
     var zipName = UserName + "-" + DateTime.Now.ToString("yy-MM-dd-hhmmss") + ".zip"; 
     var zipPath = HttpContext.Current.Server.MapPath("~/Content/zip-fulfillment/" + zipName); 

     CreateZip(order, zipPath); 


     var s3 = GetS3Access(); 

     var amazonService = new AmazonS3Service(s3.keyid, s3.secretkey, "s3.amazonaws.com"); 
     var fileStream = new MemoryStream(HelperMethods.GetBytes(zipPath)); 
     var md5val = HelperMethods.GetMD5HashFromStream(fileStream); 
     fileStream.Position = 0; 
     amazonService.UploadFile(s3.bucket, fileStream, zipName, md5val); 

     var sqsDoc = DeliveryXml(md5val, s3.bucket, "Test job"); 

     amazonService.SendSQSMessage(sqsDoc.ToString(), s3.postqueue); 
    } 

MD5散列方法:

此方法用於從我的MemoryStream創建一個MD5哈希:

public static string GetMD5HashFromStream(Stream stream) 
    { 

     MD5 md5 = new MD5CryptoServiceProvider(); 
     byte[] retVal = md5.ComputeHash(stream); 

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

編輯

只需添加fileStream.Positi整體方法中的on = 0。儘管如此,仍然完全一樣

回答

7

我懷疑問題可能是,在計算流的散列之後,數據流會留在數據的 ......所以當其他數據從其中讀取時,將不會有數據。嘗試呼叫後添加這GetMD5HashFromStream

fileStream.Position = 0; 

這將「倒帶」流,所以你可以從它再次讀取。

編輯:剛纔看了一下文檔,雖然上面是a的問題,但並不是唯一的問題。目前,要追加MD5哈希的六角表示 - 但documentation狀態:

Content-MD5: The base64-encoded 128-bit MD5 digest of the message

注意「base64編碼」的一部分。所以你要改變你的MD5代碼爲:

public static string GetMD5HashFromStream(Stream stream) 
{ 
    using (MD5 md5 = MD5.Create()) 
    { 
     byte[] hash = md5.ComputeHash(stream); 
     return Convert.ToBase64String(hash); 
    } 
} 
+0

我剛剛嘗試過,並沒有解決問題。嗯,非常感謝你的建議 - 這也是一個問題 –

+0

@LarsHoldgaard:看我的編輯。希望這會排序... –

+0

是的!非常感謝(再次)...真的幫助:) Thnx –