Поддержка заголовка «Expect: 100-continue» с ASP.NET MVC - PullRequest
13 голосов
/ 18 мая 2009

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

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

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

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

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

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

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

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

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

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

Ответы [ 3 ]

16 голосов
/ 24 июня 2009

.NET Framework по умолчанию всегда отправляет заголовок 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>

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

2 голосов
/ 12 июня 2009

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

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

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

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

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

Себ

2 голосов
/ 19 мая 2009

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

...