Поддержка заголовка "Ожидать: 100-продолжить" с помощью ASP.NET MVC

Я реализую API REST с помощью ASP.NET MVC, и небольшой камень преткновения появился в виде заголовка запроса Expect: 100-continue для запросов с телом сообщения.

RFC 2616 утверждает, что:

Получив запрос, который включает заголовок запроса Expect         поле с ожиданием "100-продолжить", исходный сервер ДОЛЖЕН         либо ответьте со статусом 100 (Продолжить) и продолжайте читать         из входного потока или отвечать окончательным кодом состояния.         сервер происхождения НЕ ДОЛЖЕН ждать тело запроса перед отправкой         ответ 100 (Продолжить). Если он отвечает окончательным статусом         код, он МОЖЕТ закрыть транспортное соединение или МОЖЕТ продолжить         читать и отбрасывать остальную часть запроса. Это НЕ ДОЛЖНО         выполнить запрошенный метод, если он возвращает окончательный код состояния.

Мне кажется, что мне нужно сделать два ответа на запрос, т.е. он должен немедленно отправить ответ HTTP 100 Continue, а затем продолжить чтение из исходного потока запросов (т.е. HttpContext.Request.InputStream) без прекращения запроса, и затем, наконец, отправив результирующий код состояния (ради аргумента, скажем, это результат без содержимого).

Итак, вопросы:

  • Я читаю право спецификации, что мне нужно сделать два ответа на запрос?
  • Как это сделать в ASP.NET MVC?

w.r.t. (2) Я попытался использовать следующий код, прежде чем продолжить чтение потока ввода...

HttpContext.Response.StatusCode = 100;
HttpContext.Response.Flush();
HttpContext.Response.Clear();

... но когда я пытаюсь установить окончательный код статуса 204, я получаю ошибку:

System.Web.HttpException: сервер не может установить статус после отправки HTTP-заголовков.

Ответ 1

100-continue должен обрабатываться IIS. Есть ли причина, по которой вы хотите сделать это явно?

Ответ 2

Структура .NET по умолчанию всегда отправляет заголовок expect: 100-continue для каждого сообщения HTTP 1.1. Это поведение можно программно контролировать по запросу с помощью свойства System.Net.ServicePoint.Expect100Continue:

HttpWebRequest httpReq = GetHttpWebRequestForPost();
httpReq.ServicePoint.Expect100Continue = false;

Он также может программно управляться глобально:

System.Net.ServicePointManager.Expect100Continue = false;

... или глобально через конфигурацию:

<system.net>
  <settings>
    <servicePointManager expect100Continue="false"/>
  </settings>
</system.net>

Спасибо Лэнсу Олсону и Phil Haack за эту информацию.

Ответ 3

IIS обрабатывает 100.

Тем не менее, это не два ответа. В HTTP, когда Expect: 100-continue входит как часть заголовков сообщений, клиент должен ждать, пока он не получит ответ перед отправкой содержимого.

Из-за того, как asp.net архивирован, вы мало контролируете выходной поток. Любые данные, которые записываются в поток, автоматически помещаются в ответ 200 с закодированной кодировкой всякий раз, когда вы скрываете, будь то вы в буферизованном режиме или нет.

К сожалению, все эти вещи скрыты во внутренних методах по всему месту, и в результате вы полагаетесь на asp.net, как и на MVC, вы почти не можете обойти его.

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

Себ