TL; версия DR
Когда при записи в поток запроса возникает ошибка передачи, я не могу получить доступ к ответу, даже если сервер отправляет его.
Полная версия
У меня есть приложение .NET, которое загружает файлы на сервер Tomcat, используя HttpWebRequest. В некоторых случаях сервер закрывает поток запросов досрочно (поскольку он отказывается от файла по той или иной причине, например, недопустимое имя файла) и отправляет ответ 400 с настраиваемым заголовком, чтобы указать причину ошибки.
Проблема заключается в том, что если загруженный файл большой, поток запросов закрывается, прежде чем закончить запись тела запроса, и я получаю IOException:
Сообщение: невозможно записать данные в транспортное соединение: существующее соединение было принудительно закрыто удаленным хостом.
InnerException:SocketException: существующее соединение было принудительно закрыто удаленным хостом
Я могу поймать это исключение, но затем, когда я вызываю GetResponse, я получаю WebException с предыдущим IOException как его внутреннее исключение и свойство null Response.  Поэтому я не могу получить ответ, даже если сервер отправляет его (отмечен с помощью WireShark).
Поскольку я не могу получить ответ, я не знаю, какова фактическая проблема. С точки зрения моего приложения, похоже, что соединение было прервано, поэтому я рассматриваю его как ошибку, связанную с сетью, и повторю загрузку... что, конечно же, снова не работает.
Как я могу обойти эту проблему и получить реальный ответ от сервера? Возможно ли это? Для меня текущее поведение выглядит как ошибка в HttpWebRequest, или, по крайней мере, серьезная проблема с дизайном...
Вот код, который я использовал для воспроизведения проблемы:
var request = HttpWebRequest.CreateHttp(uri);
request.Method = "POST";
string filename = "foo\u00A0bar.dat"; // Invalid characters in filename, the server will refuse it
request.Headers["Content-Disposition"] = string.Format("attachment; filename*=utf-8''{0}", Uri.EscapeDataString(filename));
request.AllowWriteStreamBuffering = false;
request.ContentType = "application/octet-stream";
request.ContentLength = 100 * 1024 * 1024;
// Upload the "file" (just random data in this case)
try
{
    using (var stream = request.GetRequestStream())
    {
        byte[] buffer = new byte[1024 * 1024];
        new Random().NextBytes(buffer);
        for (int i = 0; i < 100; i++)
        {
            stream.Write(buffer, 0, buffer.Length);
        }
    }
}
catch(Exception ex)
{
    // here I get an IOException; InnerException is a SocketException
    Console.WriteLine("Error writing to stream: {0}", ex);
}
// Now try to read the response
try
{
    using (var response = (HttpWebResponse)request.GetResponse())
    {
        Console.WriteLine("{0} - {1}", (int)response.StatusCode, response.StatusDescription);
    }
}
catch(Exception ex)
{
    // here I get a WebException; InnerException is the IOException from the previous catch
    Console.WriteLine("Error getting the response: {0}", ex);
    var webEx = ex as WebException;
    if (webEx != null)
    {
        Console.WriteLine(webEx.Status); // SendFailure
        var response = (HttpWebResponse)webEx.Response;
        if (response != null)
        {
            Console.WriteLine("{0} - {1}", (int)response.StatusCode, response.StatusDescription);
        }
        else
        {
            Console.WriteLine("No response");
        }
    }
}
Дополнительные примечания:
Если я правильно понимаю роль статуса 100 Continue, сервер не должен отправлять его мне, если он откажется от файла. Однако, похоже, что этот статус контролируется непосредственно Tomcat и не может контролироваться приложением. В идеале, я бы хотел, чтобы сервер не отправил мне 100 Continue в этом случае, но, по словам моих коллег, отвечающих за поддержку, нет простого способа сделать это. Поэтому я ищу решение для клиентской стороны; но если вы знаете, как решить проблему на стороне сервера, это также будет оценено.
Приложение, в котором я столкнулся с проблемой, относится к .NET 4.0, но я также воспроизвел его с 4.5.
Я не убираю время. Исключение составляет задолго до таймаута.
Я попробовал асинхронный запрос. Это ничего не меняет.
Я попытался установить версию протокола запроса на HTTP 1.0 с таким же результатом.
Кто-то еще уже зарегистрировал ошибку в Connect для этой проблемы: https://connect.microsoft.com/VisualStudio/feedback/details/779622/unable-to-get-servers-error-response-when-uploading-file-with-httpwebrequest