Означает ли пустой заголовок "Expect:" что-нибудь?
Многие библиотеки включают Expect: 100-continue
для всех запросов HTTP 1.1 POST и PUT по умолчанию.
Я намерен уменьшить предполагаемую задержку, удалив механизм 100-продолжения на стороне клиента для тех запросов, для которых, как я знаю, затраты на отправку данных сразу меньше, чем ожидание приема-передачи для 100-продолжения, а именно для коротких запросов.
Конечно, я все еще хочу все другие замечательные возможности 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
, Конечно, чтобы этот подход работал, вам нужно делать что-то, что позволяет прервать запрос, как только сервер вернет код ошибки (например, неблокирующий ввод-вывод с poll()
или же select()
).
Подобные действия могут помочь обеспечить более согласованный код между малыми и большими запросами, одновременно уменьшая задержку. Недостатком является то, что это, возможно, не то, что авторы RFC имели в виду, даже если это явно не нарушает ни одно из требований. Кроме того, это может сделать ваш более поздний код более сложным, если вы еще не делаете неблокирующий ввод-вывод или подобное.