Подтвердить что ты не робот

Почему "Content-Length: 0" в запросах POST?

Клиент иногда отправляет запросы POST с Content-Length: 0 при отправке формы (от 10 до более 40 полей).

Мы протестировали его с разными браузерами и из разных мест, но не смогли воспроизвести ошибку. Клиент использует Internet Explorer 7 и прокси.

Мы попросили их позволить их системному администратору увидеть проблему с их стороны. Выполнение некоторых тестов без прокси и т.д.

Тем временем (полгода спустя и до сих пор нет ответа) мне любопытно, знает ли кто-нибудь о подобных проблемах с запросом Content-Length: 0. Возможно, изнутри некоторой сети Windows со специальным прокси для крупных компаний.

Есть ли известная проблема с Internet Explorer 7? С прокси-системой? Сама сеть Windows?

Google только что показал что-то в контексте NTLM (и такой) аутентификации, но мы не используем это в веб-приложении. Может быть, это так, как прокси работает в сети клиентов с входами Windows? (Я не эксперт по Windows, просто угадываю.)

У меня нет дополнительной информации об инфраструктуре.

ОБНОВЛЕНИЕ: В декабре 2010 года об этом можно было сообщить одному администратору, в том числе. ссылки из ответов здесь. Контакт был вызван другой проблемой, вызванной прокси. С тех пор нет отзывов. И сообщения об ошибках все еще существуют. Я смеюсь, чтобы не плакать.

ОБНОВЛЕНИЕ 2: Эта проблема существует с середины 2008 года. Каждые несколько месяцев клиент раздражается и хочет, чтобы он был исправлен как можно скорее. Мы снова отправляем им все старые электронные письма и просим их связаться со своими администраторами, чтобы либо исправить, либо выполнить дополнительные тесты. В декабре 2010 года мы смогли отправить некоторую информацию одному администратору. Нет отзывов. Проблема не исправлена, и мы не знаем, пытались ли они даже. А в мае 2011 клиент снова пишет и хочет, чтобы это было исправлено. Тот же человек, который имеет всю информацию с 2008 года.

Спасибо за все ответы. Вы помогли многим людям, как я вижу из некоторых комментариев здесь. Жаль, что реальный мир для меня этот гротеск.

ОБНОВЛЕНИЕ 3: Май 2012, и мне было интересно, почему мы не получили еще одно требование исправить это (см. ОБНОВЛЕНИЕ 2). Посмотрел протокол ошибок, который сообщает об этой единственной ошибке каждый раз, когда это происходит (около 15 в день). Это прекратило конец января 2012 года. Никто ничего не сказал. Они, должно быть, что-то сделали с их сетью. Уже все хорошо. С лета 2008 года по январь 2012 года. Слишком плохо, я не могу сказать вам, что они сделали.

ОБНОВЛЕНИЕ 4: сентябрь 2015 года. Веб-сайт должен был собрать некоторые данные и доставить их на главный сайт клиента. Был API с учетной записью. Когда бы ни возникала проблема, они связывались с нами, даже если проблема была явно на другой стороне. В течение нескольких недель мы не можем отправить их данные. Учетная запись больше не доступна. У них была перезагрузка, и я больше не могу найти страницы, которые использовали данные нашего сайта. Отчет об ошибке не ответил, и никто не жаловался. Я думаю, они только что закончили этот проект.

ОБНОВЛЕНИЕ 5: Март 2017. API перестает работать летом 2015 года. Клиент, похоже, продолжает платить за сайт и все еще обращается к нему в феврале 2017 года. Я предполагаю, что они используют это как архив. Они больше не создают или не обновляют данные, поэтому эта ошибка, вероятно, не будет появляться после загадочного исправления января 2012 года. Но это была бы другая проблема. Я ухожу.

4b9b3361

Ответ 1

Internet Explorer не отправляет поля формы, если они отправляются с сайта, прошедшего проверку подлинности (NTLM), на сайт без аутентификации (анонимный).

Это функция для ситуаций с ответами (NTLM- или Kerberos-защищенные веб-сайты), где IE может ожидать, что первый запрос POST немедленно приведет к HTTP-аутентификации 401 Требуемый ответ (который включает в себя вызов), и только второй Запрос POST (который включает ответ на вызов) фактически будет принят. В этих ситуациях IE не загружает, возможно, большой объект запроса с первым запросом по причинам производительности. Благодаря EricLaw для публикации этого фрагмента информации в комментариях.

Такое поведение возникает каждый раз, когда HTTP POST выполняется с NTLM-аутентифицированной (то есть Intranet) страницы на неидентифицированной (то есть в Интернете) странице или если не аутентифицированная страница является частью набора фреймов, где страница набора фреймов аутентифицируется.

Обход - это либо использовать запрос GET в качестве метода формы, либо убедиться, что страница, не прошедшая проверку подлинности, открывается в новой вкладке/окне (целевой объект/ссылка) без частично аутентифицированного набора фреймов. Как только модель аутентификации для всего окна будет согласована, IE снова начнет отправлять содержимое формы.


Ответ 2

Это легко воспроизвести с помощью MS-IE и фильтра проверки подлинности NTLM на стороне сервера. У меня такая же проблема с JCIFS (1.2.), Struts 1. и MS-IE 6/7 на XP-SP2. Наконец он был исправлен. Существует несколько способов решения проблемы.

  • Измените метод формы из POST (настройка по умолчанию) для GET. Для большинства страниц с малогабаритными формами он работает хорошо. К сожалению, у меня есть возможно более 50 записей для отправки HTTP-потока обратно на сервер. IE имеет ограничение GET 2038 байтов (не длину параметра, а всю длину URL). Так что это быстрое обходное решение, но не применимое для меня.

  • отправить GET перед выполнением действия POST. Это было рекомендовано в MS-KB. В моем проекте много устаревших процедур, и я не рискнул бы в нужное время. Я никогда не пробовал этого, потому что по-прежнему требуется дополнительная обработка аутентификации, когда GET получен фильтрующим слоем на основе моего понимания из MS-KB, и я не хотел бы менять поведение с другими браузерами, например. Firefox, Opera.

  • обнаружение, если POST был отправлен с нулевой длиной контента (вы можете получить его из хэш-структуры свойств заголовка с помощью своей структуры). Если это так, запускайте цикл проверки подлинности NTLM, чтобы получить код вызова из DC или кеша и ожидать ответа NTLM. Когда принимается сообщение NTLM type2 msg и сеанс по-прежнему действителен, вам не нужно аутентифицировать пользователя, а просто перенаправлять его на ожидаемое действие, если длина содержимого POST не равна нулю. Кстати, это увеличит сетевой трафик. Поэтому перед установкой изменения plz проверьте настройку времени жизни кэша и настройку SMT-сессии soTimeOut. Или, что более просто, вы можете просто отправить 401-несанкционированный статус в MS-IE, и браузер отправит обратно запрос POST с данными в ответ.

  • MS-KB предоставил исправление с KB-923155 (я не смог опубликовать несколько ссылок из-за низкого номера репутации: {), но, похоже, он не работает. Будет ли кто-нибудь опубликовать работоспособные исправления? Спасибо:) Вот ссылка для справки, http://www.websina.com/bugzero/kb/browser-ie.html

Ответ 3

У нас есть клиент в нашей системе с точно такой же проблемой. Мы подключили его к прокси-серверу. Microsoft IAS. Он лишает тело POST и отправляет длину контента: 0. Не так много, что мы можем сделать, чтобы работать, но и хотим использовать запросы GET, поскольку это предоставляет имена пользователей/пароли и т.д. В строке URL. В нашей системе почти 7 000 пользователей, и только одна проблема... и только одна из них использует Microsoft IAS, поэтому она должна быть такой.

Ответ 4

Хорошая вероятность того, что прокси-сервер между ними реализует HTTP 1.0.

В HTTP 1.0 вы должны использовать поле заголовка Content-Length: (см. раздел 10.4 здесь)

Допустимая длина контента требуется на все HTTP/1.0 POST-запросы. Сервер HTTP/1.0 должен отвечать 400 (плохой запрос), если он не может определить длину запроса содержимого сообщения.

Запрос, отправляемый в прокси-сервер, является HTTP 1.1 и поэтому не нужно использовать поле заголовка Content-Length. Обычно используется заголовок Content-Length, но не всегда. См. Следующий отрывок из HTTP 1.1 RFC S. 14.13.

Приложения СЛЕДУЕТ использовать это поле для указать длину передачи тело сообщения, если это не запрещено правилами в разделе 4.4. Любая длина содержимого больше или равным нулю, является допустимым значением.

Раздел 4.4 описывает, как определить длина тела сообщения, если Content-Length не указывается.

Таким образом, прокси-сервер не видит заголовок Content-Length, который он предполагает, абсолютно необходим в HTTP 1.0, если есть тело. Поэтому он принимает 0, так что запрос в конечном итоге достигнет сервера. Помните, что прокси не знает правил спецификации HTTP 1.1, поэтому он не знает, как обрабатывать ситуацию, когда нет заголовка Content-Length.

Вы на 100% уверены, что ваш запрос указывает заголовок Content-Length? Если он использует другое средство, как определено в разделе 4.4, потому что он считает, что сервер равен 1.1 (поскольку он не знает про прокси 1.0 между ними), тогда у вас будет описанная вами проблема.

Возможно, вы можете использовать HTTP GET вместо обхода проблемы.

Ответ 5

Это известная проблема для Internet explorer 6, но не для 7, о которой я знаю. Вы можете установить это исправление для исправления IE6 KB831167.

Вы можете прочитать об этом здесь.

Некоторые вопросы для вас:

  • Вы знаете, какой тип прокси-сервера?
  • Знаете ли вы, действительно ли тело отправлено в запросе?
  • Всегда ли это происходит каждый раз? Или только иногда?
  • Есть ли в запросе какие-либо двоичные данные? Возможно, данные начинаются с \0, а прокси-сервер имеет ошибку с двоичными данными.

Ответ 6

Если пользователь использует прокси-сервер ISA, который использует аутентификацию NTLM, то это звучит как эта проблема, у которой есть решение (патч для прокси-сервера ISA)

http://support.microsoft.com/kb/942638
Запросы POST, которые не имеют тела POST, могут быть отправлены на веб-сервер, опубликованный в ISA Сервер 2006

Ответ 7

Вы уверены, что эти запросы поступают от "клиента"?

У меня была проблема с ботами; они иногда проверяют сайты для форм "Связаться с нами", отправляя пустые запросы POST на основе URI действия в тегах FORM, которые они обнаруживают во время обхода.

Ответ 8

Присутствие и возможные значения заголовка ContentLength в HTTP описаны в HTTP (я предполагаю, что 1/1) RFC:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13

В HTTP, он ДОЛЖЕН быть отправлен всякий раз, когда длина сообщения может быть определена до передачи

См. также:

Если сообщение получено как с      Поле заголовка Transfer-Encoding и поле заголовка Content-Length,      последний ДОЛЖЕН быть проигнорирован. http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4

Возможно, ваше сообщение несет заголовок Transfer-Encoding?

Далее отредактируйте: также обратите внимание, что "СЛЕДУЕТ", как используется в RFC, очень важно и не эквивалентно "MUST":

3. СЛЕДУЕТ Это слово или прилагательное "РЕКОМЕНДОВАНО" означают, что    могут существовать обоснованные причины в определенных обстоятельствах, чтобы игнорировать    конкретный пункт, но следует понимать все последствия и    тщательно взвешивались перед выбором другого курса. Ссылка: http://www.ietf.org/rfc/rfc2119.txt

Ответ 9

Google также показывает это как ошибку IE (некоторые версии, в любом случае) после того, как соединение https попадает в тайм-аут keepalive и повторно подключается к серверу. Решение, похоже, настраивает сервер, чтобы не использовать keepalive для IE под https.

Ответ 10

Исправление Microsoft для KB821814 может установить Content-Length в 0:

В исправлении, описанном в этой статье, реализовано изменение кода в Wininet.dll:

  • Обнаружение условия RESET в запросе POST.
  • Сохраните данные, которые должны быть опубликованы.
  • Повторите запрос POST с длиной содержимого, равной 0. Это предотвращает появление RESET и позволяет завершить процесс аутентификации.
  • Повторите первоначальный запрос POST.

Ответ 11

У нас был клиент, который использовал тот же сайт в анонимном режиме и в режиме NTLM (на разных портах). Мы выяснили, что в нашем случае 401 был связан с приложением Riverbed Steelhead, используемым для оптимизации http. Первым сигналом, указывающим на это направление, был заголовок X-RBT-Optimized-By. Проблема заключалась в функции Gratuitous 401:

Эта функция может использоваться как для каждого запроса, так и для каждого соединения аутентификации, но это наиболее эффективно при использовании с запросом аутентификация. При аутентификации по запросу каждый запрос должен быть аутентифицируется на сервере до того, как сервер будет обслуживать объект клиенту. Однако большинство браузеров не кэшируют сервер ответ, требующий аутентификации, и, следовательно, он будет для каждого запроса GET. С Gratuitous 401 клиентская сторона Устройство Steelhead будет кэшировать ответ сервера и когда клиент отправляет запрос GET без каких-либо заголовков аутентификации, он будет локально отвечать сообщением -401 Unauthorized‖ и, следовательно, сохранять в оба конца. Обратите внимание, что модуль HTTP не участвует в фактическая аутентификация. То, что делает модуль HTTP, - это сообщить клиент требует, чтобы сервер требовал аутентификации, не требуя он должен расточать одну поездку в оба конца.

Ответ 12

curl отправляет PUT/POST запросы с Content-Length: 0 при настройке на использование прокси-сервера HTTP. Это трюк, чтобы преодолеть требуемую буферизацию в случае первого несанкционированного запроса PUT/POST на прокси-сервер. В случае GET/HEAD запросов curl просто повторяет запрос. Схема для PUT/POST выглядит так:

  • Отправьте первый запрос PUT/POST с Content-Length на 0.

  • Получите ответ. Код состояния HTTP 407 означает, что мы должны использовать прокси-сервер авторизации. Подготовьте заголовки для проверки подлинности прокси для отправки запроса.

  • Отправьте запрос еще раз с заполненными заголовками для проверки подлинности прокси и настоящих данных на POST/PUT.

Ответ 13

У меня также была проблема, когда запросы от браузера IE 11 клиента имели Content-Length: 0 и не включали ожидаемое содержимое POST. Когда клиент использовал Firefox или Chrome, ожидаемый контент был включен в запрос.

Я решил, что клиент использовал URL-адрес HTTP вместо URL-адреса HTTPS (например, http://..., not https://...), и наше приложение использует HSTS. Кажется, в IE 11 может быть ошибка, что при обновлении запроса на HTTPS из-за HSTS содержимое запроса теряется.

Получение клиентом корректировки URL-адреса https://... привело к тому, что содержимое было включено в запрос POST и разрешило проблему.

Я еще не исследовал, действительно ли это ошибка в IE 11 на этом этапе.