NetworkStream.DataAvailable не обозначает конец HTTP-ответа
Избегайте обрезанных загрузок HTTP, используя кадрирование сообщений вместо NetworkStream.DataAvailable в качестве условия завершения.
NetworkStream.DataAvailable == false означает, что нет байтов, готовых к немедленному чтению. Это не означает, что HTTP-ответ завершён. Цикл, останавливающийся здесь, может обрезать совершенно нормальную загрузку через SOCKS во время паузы между пакетами.
После того как SOCKS устанавливает TCP-соединение, правило завершения по-прежнему задаёт кадрирование HTTP:
- Тело с Content-Length заканчивается после объявленных байтов содержимого.
- Ответ chunked требует завершающего чанка и применимых trailer-ов.
- Ответ, ограниченный соединением, заканчивается вместе с соединением.
- Некоторые статусы и ответы на HEAD не имеют тела.
Прочитайте статус и заголовки, чтобы определить применимое правило. Ожидание только закрытия не является общим решением, потому что полный HTTP-ответ может оставить соединение открытым. Ёмкость одного буфера тоже никак не связана с длиной ответа.
Используйте реализацию кадрирования HTTP-клиента, если она поддерживает выбранный транспорт через прокси. В совместимой современной среде выполнения .NET рассмотрите встроенную поддержку SOCKS в HttpClient. Собственная реализация должна сохранять состояние разбора между частичными заголовками и чтениями тела, а также отличать успешное завершение от отмены, тайм-аута и неожиданного EOF. В непустом запросе на чтение ноль прочитанных байтов означает, что поток завершился; это отличается от отсутствия байтов в очереди прямо сейчас.
Прокси может сделать паузы заметными, но он не превращает пустую очередь приёма в маркер конца сообщения.