从谷歌云存储下载总是不正确的哈希

sjk*_*jkp 3 c# google-cloud-storage

我正在尝试从谷歌云存储中下载一些文件(来自谷歌播放发布的应用程序的日志文件).

我的代码看起来像这样

Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "my-service-account-credential.json", EnvironmentVariableTarget.Process);
StorageClient storageClient = StorageClient.Create();

var bucketName = "mybucketname";
var buckets = storageClient.GetBucket(bucketName);
var objects = storageClient.ListObjects(bucketName).ToList();
foreach (var o in objects)
{
    try
    {
        Directory.CreateDirectory(Path.GetDirectoryName(o.Name));
        using (var fs = File.Open(o.Name, FileMode.OpenOrCreate))
        {
            await storageClient.DownloadObjectAsync(bucketName, o.Name, fs);                                               
        }
    }
    catch (Exception e)
    {
        if (e.Message.StartsWith("Incorrect hash"))
        {
            continue;
        }
        throw;
    }
}
Run Code Online (Sandbox Code Playgroud)

代码实际上似乎工作正常(通过查看实际下载的文件内容来判断,它是csv文件).但正如你所看到的,我已经实现了一个令人讨厌的尝试catch/hack,因为我下载的每个文件都抛出一个异常,说明散列是不正确的.我假设客户端库将下载内容的散列与存储桶的散列进行比较,这些不相同导致它成为异常.

例外是:

System.IO.IOException: Incorrect hash: expected 'DXpVGw==' (base64), was '2RMrcw==' (base64)
   at Google.Cloud.Storage.V1.StorageClientImpl.<DownloadObjectAsyncImpl>d__48.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at MyClass.GoogleBucket.Functions.<DownloadGoogleBucketLogs>d__1.MoveNext() in mycode.cs:line 51
Run Code Online (Sandbox Code Playgroud)

所以我的问题是你如何下载对象,没有得到这个例外,显然我不应该做我做过的事情.

Jon*_*eet 6

TL; DR:当它出来时更新到2.1.0.(如果你绝望,那么在此之前获取并构建源代码.)

这是一个棘手的问题.

问题是,它HttpClient是动态自动解压缩数据,但服务器提供的哈希是针对压缩内容的.

我们现在已经对REST API支持库和Google.Cloud.Storage.V1库进行了更改,以在解压缩之前拦截和散列下载的数据.这些更改在Github中合并,并将在2.1.0版本中,我期望在1月初发生.

请注意,这不会修复单独的极端情况,其中禁用客户端解压缩,导致服务器端解压缩,但仍然具有压缩内容的散列.我们单独跟踪它,但它不会影响此处的示例代码,因为如果您StorageService在初始化程序中创建了一个显式的,禁用的gzip支持,然后创建了一个StorageClient包装该服务,您只会看到它.