我正在处理谷歌云存储.NET 客户端 有三个特性(在.NET 和我的客户端之间) 库和存储服务)组合在一个 令人不快的方式:
下载文件时(Google 云存储中的对象) 术语) ,服务器包含存储数据的散列 然后,客户端代码根据它的数据验证该哈希值 下载
Google 云存储的一个独立特性是用户可以 设置对象的 Content-Encoding,并将其包含为 当请求包含匹配的 接受-编码。(目前,让我们忽略 请求不包括...)
HttpClientHandler
可以解压缩 gzip (或者平减)内容
自动的,透明的
当这三者结合在一起,我们就有麻烦了 简短但完整的程序演示了这一点,但没有使用 客户端库(并打开一个可公开访问的文件) :
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
string url = "https://www.googleapis.com/download/storage/v1/b/"
+ "storage-library-test-bucket/o/gzipped-text.txt?alt=media";
var handler = new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.GZip
};
var client = new HttpClient(handler);
var response = await client.GetAsync(url);
byte[] content = await response.Content.ReadAsByteArrayAsync();
string text = Encoding.UTF8.GetString(content);
Console.WriteLine($"Content: {text}");
var hashHeader = response.Headers.GetValues("X-Goog-Hash").FirstOrDefault();
Console.WriteLine($"Hash header: {hashHeader}");
using (var md5 = MD5.Create())
{
var md5Hash = md5.ComputeHash(content);
var md5HashBase64 = Convert.ToBase64String(md5Hash);
Console.WriteLine($"MD5 of content: {md5HashBase64}");
}
}
}
.NET 核心项目文件:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
</Project>
产出:
Content: hello world
Hash header: crc32c=T1s5RQ==,md5=xhF4M6pNFRDQnvaRRNVnkA==
MD5 of content: XrY7u+Ae7tCTyyK7j1rNww==
如您所见,内容的 MD5与 MD5不同 (在我的客户端库中,我使用的是 crc32c 散列,但显示相同的行为。)
这不是 HttpClientHandler
中的一个错误——这是意料之中的,但也是一种痛苦
基本上,我需要在
内容之前 还有减压后。我不能找到任何方法
这么做。
为了在某种程度上说明我的需求,我知道如何防止 HttpClient
中的解压缩,而是在从流中读取时进行解压缩——但是我需要能够在不改变使用 HttpClient
中的结果 HttpResponseMessage
的任何代码的情况下完成这项工作。(有很多代码处理响应,我只想在一个中心位置进行更改。)
我有一个计划,我已经制定了原型,目前为止还在运作 到目前为止发现,但是有点丑。它涉及到创建一个三层 处理人:
HttpClientHandler
自动解压失效。Stream
子类替换内容流的新处理程序
它委托给原始内容流,但在读取数据时对其进行哈希处理。DecompressionHandler
代码的仅解压缩处理程序。虽然这种方法有效,但也有缺点:
如果微软将 DecompressionHandler
公开,那将有助于
很多-但这可能需要比我需要更长的时间。
我正在寻找的是一个替代方法,如果可能的话-
我以前忽略了一些东西,这些东西让我能够理解其中的内容
减压。我不想重新发明 HttpClient
-反应
例如,我不想谈论
那边的事情。这是一个非常具体的拦截点
我在找。