HttpContent.ReadAsByteArrayAsync() 在 DelegatingHandler 内部失败且没有错误

HttpContent.ReadAsByteArrayAsync() fails without error inside DelegatingHandler

我正在尝试为 API 实施 HMAC 安全性。一切正常,直到我尝试 post 一个文件。

可以在此处找到 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) implements a DelegatingHandler (HMACDelegatingHandler) 以便将 HMAC header 附加到请求。

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

构建签名时,从 helper class 调用以下代码:

private static async Task<byte[]> 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 字节左右时就会出现问题。

这个post提供了一个解决方案:。

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

var content = await httpContent.ReadAsByteArrayAsync();

有了这个:

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

var content = ms.ToArray();

它应该停止挂起。