Пустой заголовок "Ожидать:" означает что-нибудь?

Многие библиотеки включают Expect: 100-continue во все HTTP 1.1 POST и PUT запросы по умолчанию.

Я намерен уменьшить воспринимаемую задержку, удалив на стороне клиента механизм 100-continue на тех запросах, для которых я знаю, что расходы на отправку данных сразу же меньше, чем ожидание обратного перехода на 100-continue, а именно на короткие запросы.

Конечно, мне все еще нужны все другие отличные функции HTTP 1.1, поэтому я хочу убить заголовок Expect: 100-continue. У меня есть два варианта:

  • полностью удалить заголовок ожидания, или
  • отправить пустой заголовок ожидания, Expect:\r\n

Есть ли разница между двумя?

Любое программное обеспечение, которое может сломаться для одного или другого?

Ответ 1

Ничего не следует разорвать, если вы удалите заголовок Expect, но я знаю, что в Microsoft IIS были проблемы с 100 Continue в прошлом. Например, IIS5 всегда отправляет 100 ответов на продолжение. Поэтому, интересно, хотя бы некоторые из его использования в библиотеках могли бы работать с аналогичным нарушением поведения на серверах.

Многие библиотеки, похоже, устанавливают этот заголовок, а затем фактически не обрабатывают 100 Continue правильно - например. они начинают посылать тело запроса немедленно, не дожидаясь 100 Continue, а затем не обрабатывают тот факт, что сервер может отправить код ошибки HTTP до того, как он закончит отправку тела запроса (первая часть ОК, это вторая часть, которая сломана - см. позже в моем ответе). Это заставляет меня поверить, что некоторые авторы только что скопировали его из других источников, не до конца понимая тонкости.

Я не вижу причины включать пустой заголовок Expect - если вы не собираетесь включать 100-continue (или какое-то другое предложение Expect), оставьте заголовок полностью. Единственная причина включать его - это работать со сломанными веб-серверами, но я не знаю о том, кто ведет себя таким образом.

Наконец, если вы просто хотите уменьшить задержки в обратном направлении, мне кажется, что на самом деле это не будет противоречить RFC, чтобы просто сразу начать передавать тело запроса. Вы не должны ждать бесконечно, чтобы отправить тело запроса (согласно RFC), так что вы ведете себя в спецификации ваш тайм-аут перед отправкой в ​​любом случае равен нулю.

Вы должны знать, что серверы могут не отправлять ответ 100 Continue, если они уже получили часть тела запроса, поэтому вам нужно обрабатывать серверы, которые отправляют 100 Continue, те, которые ничего не отправляют и ждут для полного запроса и те, которые немедленно отправляют любой код ошибки HTTP (который может быть 417, но скорее всего общий код 4xx). Таким образом, ваши короткие запросы не должны иметь накладных расходов (кроме заголовка Expect), но вам не придется ждать 100 Continue. Конечно, для этого подхода к работе вам нужно будет делать что-то таким образом, что позволяет прервать запрос, как только сервер вернет код ошибки (например, неблокирующий IO с помощью poll() или select()).

Выполнение этого способа может помочь сохранить код более согласованным между небольшими и большими запросами, одновременно уменьшая задержку. Недостатком является то, что это, возможно, не то, что имели в виду авторы RFC, даже если это явно не нарушает какие-либо требования. Кроме того, это может сделать ваш более поздний код более сложным, если вы уже не выполняете неблокирующий IO или аналогичный.