在DelegatingHandler中,HttpContent.ReadAsByteArrayAsync()在没有错误的情况下失败

我正在尝试为API实现HMAC安全性。 一切正常,直到我尝试发布文件。

HMAC解决方案可以在这里找到 – https://github.com/gavinharriss/WebAPI.HMAC – 它是原始的一个分支,允许GET请求和POST请求。

附加文件的代码:

var requestContent = new MultipartFormDataContent(); var fileContent = new ByteArrayContent(file); requestContent.Add(fileContent, "file", filename); 

如果我立即调用HttpContent.ReadAsByteArrayAsync()没有问题,字节数组是可用的。

但是,HMAC HttpClient ( HMACHttpClient )实现了DelegatingHandler ( HMACDelegatingHandler ),以便将HMAC头附加到请求。

在HMACDelegatingHandler中 ,请求作为HttpRequestMessage传递, HttpRequestMessage.Content属性在辅助器中用于构建HMAC签名。

构建签名时,从助手类调用以下代码:

 private static async Task ComputeHash(HttpContent httpContent) { using (var md5 = MD5.Create()) { byte[] hash = null; if (httpContent != null) { var content = await httpContent.ReadAsByteArrayAsync(); // <-- Fails here if (content.Length != 0) { hash = md5.ComputeHash(content); } } return hash; } } 

当单步执行代码时, var content = await httpContent.ReadAsByteArrayAsync()行被命中,然后没有,没有错误。 请求似乎只是噗,但一切仍在运行, HttpClient请求永远不会被发送。

有什么想法正在发生什么?

在使用各种大小的文件对此进行测试后,我发现当文件大约有50,000字节标记时会出现问题。

这篇文章提供了一个解决方案: HttpContent.ReadAsStringAsync导致请求挂起(或其他奇怪的行为) 。

如果替换HMACHelper中的错误行(第66行):

 var content = await httpContent.ReadAsByteArrayAsync(); 

有了这个:

 var ms = new MemoryStream(); await httpContent.CopyToAsync(ms); ms.Seek(0, SeekOrigin.Begin); var content = ms.ToArray(); 

它应该停止悬挂。