2016-01-21 106 views
0

我想用python sdk上傳blob到azure blob存儲。上傳後,我想在服務器端傳遞MD5散列值進行驗證。python azure blob storage md5檢查使用put_block_blob_from_path上傳blob上傳失敗

下面的代碼:

blob_service.put_block_blob_from_path(
     container_name='container_name', 
     blob_name='upload_dir/'+object_name, 
     file_path=object_name, 
     content_md5=object_md5Hash 
) 

但我得到這個錯誤:

AzureHttpError: The MD5 value specified in the request did not match with the MD5 value calculated by the server. 

該文件是200MB〜和錯誤立即拋出。不上傳文件。所以我懷疑它可能會比較提供的散列或第一塊散列或其他東西。

任何想法?

回答

0

我回顧了Azure Blob Storage SDK的函數put_block_blob_from_path的源代碼。它在功能評論中解釋了該案例,請參閱下面的內容並參考https://github.com/Azure/azure-storage-python/blob/master/azure/storage/blob/blobservice.py

content_md5:

Optional. An MD5 hash of the blob content. This hash is used to verify the integrity of the blob during transport. When this header is specified, the storage service checks the hash that has arrived with the one that was sent. If the two hashes do not match, the operation will fail with error code 400 (Bad Request).

0

我覺得這裏有兩件事。

  • 的Bug SDK - 我相信你已經發現了SDK中的錯誤。我在Github上查看了這個函數的源代碼,我發現當大塊上傳成塊時,SDK首先嚐試創建一個空塊blob。對於塊blob,這不是必需的。當它創建空塊blob時,它不會發送任何數據。但是,您正在設置content-md5,並且SDK將您發送的content-md5與空白內容的content-md5進行比較,並且由於它們不匹配,您會收到錯誤消息。

要解決的臨時問題,請修改源代碼中blobservice.py和註釋掉的代碼下面幾行:

self.put_blob(
     container_name, 
     blob_name, 
     None, 
     'BlockBlob', 
     content_encoding, 
     content_language, 
     content_md5, 
     cache_control, 
     x_ms_blob_content_type, 
     x_ms_blob_content_encoding, 
     x_ms_blob_content_language, 
     x_ms_blob_content_md5, 
     x_ms_blob_cache_control, 
     x_ms_meta_name_values, 
     x_ms_lease_id, 
    ) 

我已經創建了Github上一個新的難題是:https://github.com/Azure/azure-storage-python/issues/99

  • 不正確的用法 - 我注意到,你傳遞文件的MD5散列content_md5參數。這不適合你。實際上,您應該在x_ms_blob_content_md5參數中傳遞md5散列。所以,你的電話應該是:
blob_service.put_block_blob_from_path(
     container_name='container_name', 
     blob_name='upload_dir/'+object_name, 
     file_path=object_name, 
     x_ms_blob_content_md5=object_md5Hash 
) 
+0

這是一個錯誤,我們應該拋出一個更好的錯誤消息,而不是點擊服務,但驗證必須分塊的大型上傳內容根本行不通。 x_ms_blob_content_md5將存儲md5,但該服務不會對其進行驗證。 content_md5驗證特定請求的內容,但由於有多個分塊的blob,它將無法工作。 –

+0

@ EmilyGerner-Microsoft - 我認爲這個錯誤是在嘗試在分塊上傳之前先創建一個空塊blob。這一步恕我直言,是完全沒有必要的,並會造成問題。例如,如果分塊上載失敗怎麼辦。在這種情況下,用戶將在他們的存儲帳戶中擁有一個零字節的blob。我同意你對content_md5/x_ms_blob_content_md5的評論。 –

+0

是的,你是對的 - 這個額外的put實際上已經在下一個lib版本中被刪除了。有一次,如果任何訪問條件不匹配,則會縮短上傳次數,否則在put block列表操作上傳後會失敗。就像我說的那樣,刪除了。 content_md5仍然會被應用到put block列表操作,儘管哪一個仍然沒有意義,所以對於下一個版本,我們還會添加一條錯誤消息,以便在上傳之前關閉該場景。接得好! –

1

這是有點在一個SDK的錯誤,我們應該拋出一個更好的錯誤消息,而不是打的服務,但驗證大量上載以來的內容進行分塊根本不起作用。 x_ms_blob_content_md5將存儲md5,但該服務不會對其進行驗證。儘管如此,你可以下載。 content_md5由服務器驗證了特定請求的正文,但由於有多個分塊的blob,它永遠不會工作。

因此,如果blob足夠小(低於BLOB_MAX_DATA_SIZE)以放入單個請求,content_md5將正常工作。否則,我只是推薦使用HTTPS並在x_ms_blob_content_md5中存儲MD5,如果您認爲您可能想要使用HTTP進行下載並在下載時進行驗證。 HTTPS已經爲網絡上的位翻轉提供了驗證,因此使用它進行上傳/下載將會有很大幫助。如果您因爲某種原因無法使用HTTPS上傳/下載,則可以考慮使用put塊並放置阻止列表API來自行分塊Blob。我們打算在圖書館本身爲單放和分塊操作添加自動MD5計算,這將完全解決這個問題。對於下一個版本,如果爲分塊下載指定了content_md5,我們將添加改進的錯誤消息。

+0

感謝您的回答。爲什麼不這樣做,它會驗證上傳完成後的整個blob?如果不能將它用於必須分塊的斑點,那麼包含該參數(content_md5)似乎不明智。 Re https,你能指出顯示如何做到這一點的任何資源嗎?謝謝! – chorbs

+0

默認情況下,Https處於打開狀態,但如果您需要使用'協議'參數設置blob服務,則可以明確發送它。 *上傳後,該服務沒有驗證完整blob *的情況,如果它是以塊的形式完成的。由於通用HTTP協議,內容MD5僅用於當前請求主體。因此,每個塊的MD5是可以通過lib實現的正確解決方案(或者如果要用put塊手動實現)。 –