2016-08-11 3 views
2

Я пытаюсь реализовать защиту HMAC для API. Все работает нормально, пока я не попытаюсь опубликовать файл.HttpContent.ReadAsByteArrayAsync() выходит из строя без ошибок внутри DelegatingHandler

Решение 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.

При создании подписи, следующий код вызывается из 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 никогда не отправляется.

Любые идеи, что происходит?

ответ

2

Проверяя это с помощью различных размеров файла, я обнаружил, что проблема возникла, когда файлы получили отметку в 50 000 байт.

Это сообщение предоставлено решение: HttpContent.ReadAsStringAsync causes request to hang (or other strange behaviours).

Если заменить erroring линию в HMACHelper (строка 66):

var content = await httpContent.ReadAsByteArrayAsync(); 

с этим:

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

var content = ms.ToArray(); 

Он должен остановить висит.

Смежные вопросы