Является ли использование заголовка местоположения в ответе HTTP 202 RFC-совместимым?

У меня есть отличная концептуальная дискуссия с моими коллегами об использовании заголовка Location в ответе "Принимаемый ответ".

История начала анализировать поведение функции PHP header() из здесь. Интересная выдержка:

Второй особый случай - заголовок "Location:". Он не только отправляет этот заголовок обратно в браузер, но также возвращает код статуса REDIRECT (302) в браузер, если код статуса 201 или 3xx уже не установлен.

Они не включали код статуса 202 в это поведение по умолчанию. Похоже, они не ожидают, что ответ 202 имеет местоположение и действительно:

header("HTTP/1.1 202");
header("Location: http://example.com");

перенаправить клиента на URL-адрес местоположения. Конечно, это изменение можно изменить с помощью третьего параметра функции header(), но мое внимание привлекло следующее: почему они поняли, что по умолчанию 202 не предполагается содержать заголовок Location?

Затем я просматриваю RFC, ища официальное значение статуса 202. Интересная выдержка:

Объект, возвращенный с этим ответом, ДОЛЖЕН включать указание текущего состояния запроса и указатель на монитор состояния или некоторую оценку того, когда пользователь может ожидать выполнения запроса.

В нем явно не указано заголовок Location, как это было в предыдущем (в том же документе RFC) 201. Вероятно, это было причиной того, почему парни PHP понимали, что ответ 202 не должен содержать заголовок местоположения. Будет ли указатель интерпретироваться как заголовок местоположения или ребята из PHP, ошибочно принятые? Если стандарт разрешает заголовок местоположения с ответом 202: не должно быть официальной документации более явной, как определение ответа 201?

Наконец, я просмотрел версию недавно RFC и нашел небольшое изменение в редакции:

Представление, отправленное с этим ответом, должно описывать текущий статус запроса и указывать (или внедрять) монитор состояния, который предоставляет пользователю оценку того, когда запрос будет выполнен.

Опять же, недостаточно явно предположить, что указывает на означает заголовок местоположения.

Короче говоря, после вышеупомянутых изменений: Я являюсь RFC-совместимым, используя заголовок Location с ответом 202?

Ответ 1

Наконец, я получил ответ от Р. Филдинга:

enter image description here

202 - статус успеха. Указанный указатель - это просто гипертекст в теле ответа. 303 следует отправить, если вы хотите использовать Location для перенаправления клиента на другой ресурс. Результатом перенаправленного запроса может быть 202.

.... Рой

Таким образом, заголовок Location не должен использоваться в ответе 202 Accepted. Ребята из PHP сделали правильную интерпретацию.

Изменить март, 2017: Извините, я забыл добавить другие сообщения, которые мы обменяли в том же потоке в тот момент, поэтому я отправляю сейчас запись:

me: В разделе раздела 4.1 RFC 7240 автор (J. Snell) приводит пример, используя Заголовок местоположения в 202 Принятый ответ. Он не прав? Это, как и многие люди понимают такое поведение с RFC 7231. Вы можете отправить мне любую ссылку об этом спорном вопросе?

Рой: Пример приведен без инструкции, поэтому он не ошибается потому что он не говорит, что это значит. Место может быть отправлено в любой сообщение. Это означает, что он определен только для определенных кодов состояния.

Например, если бы он сказал, что пользовательский агент будет использовать это поле "Место", чтобы предоставить пользователю индикатор состояния, затем он был бы неправ. Это может быть хорошей идеей, но это не часть стандарта.

PHP ошибочно полагает, что Location используется только в 201 и 3xx, но это разрешено, потому что его внутренний API не является HTTP; вместо этого он преобразует поток в HTTP.

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

Ответ 2

Из RFC-2616:

Объект, возвращаемый с этим ответом, ДОЛЖЕН включать указание текущего состояния запроса и указатель на монитор состояния или некоторую оценку того, когда пользователь может ожидать выполнения запроса. p >

Я думаю, что ключ здесь - "сущность", так как вопрос здесь заключается в том, включаем ли мы индикацию состояния в заголовках ответов или в теле ответа. Почти везде, на которое ссылается сущность, это, по-видимому, подразумевает тело ответа. Например:

10.5 Ошибка сервера 5xx

Коды состояния ответа, начинающиеся с цифры "5", указывают случаи, когда сервер знает, что он ошибся или не может выполнить запрос. За исключением случаев ответа на запрос HEAD, сервер ДОЛЖЕН включать объект, содержащий объяснение ситуации ошибки, и является ли это временным или постоянным условием. Пользовательские агенты ДОЛЖНЫ отображать любой включенный объект пользователю. Эти коды ответов применимы к любому методу запроса.

Я не видел, чтобы браузер отображал заголовки ответов пользователю. И для 303s:

10.3.4 303 См. Другие

В URI должен указываться другой URI. Если метод запроса не был HEAD, , объект ответа ДОЛЖЕН содержать короткую гипертекстовую заметку с гиперссылкой на новый URI (ы).

Вы не получите гипертекстовый ответ в заголовках.

Тем не менее, раздел 7 совершенно ясно, что означает объект:

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

Я думаю, что в вашем случае то, что вы делаете, соответствует требованиям RFC-2616. Однако, реалистично это все сводится к реализации клиента. Может ли клиент, получающий ваш ответ 202, обрабатывать заголовок Location: для ответа 2xx? Это должен быть ваш лакмусовый тест на то, как реагировать, а также тест, используемый для стандартизации во время их стандартизации/документации.

Ответ 3

Собственно, в соответствии с rfc 7240 http://tools.ietf.org/html/rfc7240#section-4.1 вы можете отправить код состояния 202 вместе с заголовком Location. Это было бы в асинхронном ответе, хотя, по-видимому, PHP не позволит вам это сделать.

Ответ 4

RFC допускает неопределенность в отношении этой концепции. Это означает, что спецификация в настоящее время не говорит о том, как "Location" используется с 202, но, с другой стороны, это не лицензия для библиотек, которая просто заменяет код состояния. Так что это окончательно ошибка PHP.