Ошибка WCF при использовании SSL/TLS

У нас есть приложение, использующее привязку http со следующей конфигурацией на стороне клиента:

    <binding name="SecureStreamedHttpBinding"
             transferMode="Streamed"
             maxReceivedMessageSize="8000000000"
             maxBufferSize="65536"
             sendTimeout="00:20:00">
      <security mode="Transport">
        <transport clientCredentialType="None" />
      </security>
    </binding>

И эта конфигурация на стороне сервера:

    <binding name="SecureStreamedHttpBinding_IHub"
             transferMode="Streamed"
             maxReceivedMessageSize="8000000000"
             maxBufferSize="65536"
             receiveTimeout="00:20:00">
      <security mode="Transport">
        <transport clientCredentialType="None"/>
      </security>
    </binding>

Канал открывается клиентом путем создания ChannelFactory и последующего вызова CreateChannel:

               ChannelFactory<IHub> channelFactory = new ChannelFactory<IHub>(endpointConfigurationName);
           IHub hub = channelFactory.CreateChannel();
           ((IClientChannel)hub).Open();

Иногда, когда мы пытаемся передать большие файлы по этому соединению, мы получаем от сервера сообщение об ошибке: «Удаленный сервер вернул неожиданный ответ: (413) Запрос объекта слишком велик». Я говорю иногда, потому что кажется, что существует ряд факторов времени/скорости, которые могут вызывать появление и исчезновение ошибки. Например, ошибки кажутся более распространенными на машинах с высокой пропускной способностью. Они кажутся менее распространенными, когда начинаются после того, как соединение установлено. Однако влияние времени/скорости непоследовательно.

Если TLS отключен, у нас никогда не возникает проблем.

Мы подключили Wire Sharked к соединению и обнаружили, что клиент отправляет сообщение «FIN» на порт примерно в то же время, что и ошибка, но мы не знаем точно, когда возникает ошибка 413, потому что мы не видим ее в Проволочная акула. Так что мы не знаем, причина это или следствие.

Мы также просмотрели информацию об отслеживании неудачных запросов от IIS и обнаружили, что «Сущность запроса слишком велика» указана вместе с данными, которые передавались в то время, но мы не уверены, как интерпретировать то, что мы видим.

Мы не знаем, почему клиент выдает FIN? Это нормально? Является ли это причиной ошибки «Request Entity Too Large» на сервере или наоборот. Или просто совпадение? В любом случае эффект заключается в том, что мы должны перезапустить передачу файла в этот момент. Любая мысль о том, что может быть основной причиной ошибки?

Заранее спасибо за вашу помощь.


person James R    schedule 29.03.2016    source источник
comment
Насколько велики отправляемые файлы? Каков наихудший сценарий? Я имею в виду ваш maxReceivedMessageSize или maxBufferSize   -  person Bill Sambrone    schedule 29.03.2016
comment
Максимальный размер файла реально составляет около 4 ГБ, но мы хотели установить ограничение на 8 ГБ на всякий случай. Мы установили максимальный размер буфера на 65536. Одна вещь, которую мы видели, заключается в том, что установка большего числа для uploadReadAheadSize полезна, но вы не можете установить это значение больше, чем около 2 ГБ, поэтому это не помогает с действительно большими файлами.   -  person James R    schedule 29.03.2016
comment
Еще одно замечание: хотя максимальный размер файла, который мы ожидаем передать, составляет 4 ГБ, это будут данные в двоичном коде, которые, как я полагаю, увеличат размер файла до более чем 5 ГБ.   -  person James R    schedule 29.03.2016


Ответы (1)


Итак, прошло некоторое время с тех пор, как я коснулся WCF, но я думаю, что нашел одну возможную вещь. Ваша проблема может быть не в WCF, а в IIS. Проведя некоторое расследование, вы можете столкнуться с проблемами с сертификатом SSL из-за размера запроса.

Этот другой ответ SO хорошо читается, хотя он лишь частично охватывает вашу проблему:

IIS7 - (413) Объект запроса слишком велик | uploadReadAheadSize

Если вы застряли, возможно, стоит попробовать включить согласование клиента для SSL в поле IIS. Скопируйте/вставьте код из исходной ссылки на случай, если он выйдет из строя:

Одна из причин, перечисленных в сообщении об ошибке, гласит: «Веб-сервер не может обслужить запрос, поскольку он пытается согласовать сертификат клиента, но объект запроса слишком велик». Решением этой проблемы было установить значение clientcertnegotiation=enable. Получение этого набора на IIS 7 было немного сложным. Следующее, но запускается через командную строку:

netsh http показать sslcert

ПРИМЕЧАНИЕ. Эти настройки понадобятся вам для следующего набора команд.

Чтобы удалить текущие настройки (вы не можете изменить существующие настройки, вы должны удалить и прочитать) netsh http delete sslcert :

IP-адрес и порт получаются из результатов команды show. Пример: netsh http удалить sslcert 0.0.0.0:443

Чтобы правильно добавить настройки сертификата: netsh http add sslcert ipport=: certhash= appid= certstorename= clientcertnegotiation=enable

Оригинальная статья:

http://forums.newatlanta.com/messages.cfm?threadid=554611A2-E03F-43DB-92F996F4B6222BC0&#top

Кроме того, обратите внимание на увеличение размера загрузки для чтения с опережением: http://www.iis.net/configreference/system.webserver/serverruntime

person Bill Sambrone    schedule 29.03.2016
comment
В моем конкретном случае только установка каждого параметра, как описано выше, решила проблему. Я также установил ограничения в соответствии с weblog.west-wind.com/posts/2016/apr/06/ - person Anton Krouglov; 28.06.2019