2017-01-30 2 views
2

В новом приложении Phoenix присутствует по умолчанию Plug.Head, и я был заинтригован его значением.Почему полезно преобразовывать запросы HEAD в GET-запросы?

Я знаю, что «the HEAD method is identical to GET except that the server MUST NOT send a message body in the response».

Я думаю, что official Phoenix guides являются первосортный, но это бросил меня в Routing guide:

Plug.Head - преобразует запросы ГОЛОВЫ, чтобы получить запросы и раздевает тело

ответа Если Запросы HEAD без тела, тогда зачем это нужно? Я подумал, что, возможно, обуздать искаженные запросы, но глядя на Plug.Head implementation, он просто переключает метод HEAD на GET.

def call(%Conn{method: "HEAD"} = conn, []), do: %{conn | method: "GET"} 
    def call(conn, []), do: conn 
end 

Ближайший вещь, которую я смог найти по этой теме является question on ServerFault, но это было связано с NGINX и порочной логики приложения, где запросы HEAD, необходимых для преобразования в GET и соответствующие ответы Вернись к HEAD.

ответ

1

AFAICT, идея состоит в том, что Plug.Head просто гарантирует, что запрос обрабатывается как GET; вторая часть реализации HEAD, которая не отправляет тело, осуществляется адаптерами подключаемого соединения. Документация для большинства обратных вызовов, например send_resp, указывает, что «если запрос имеет метод "HEAD", адаптер не должен отправлять ответ клиенту».

+0

Благодарим за подключение адаптеров! Хотя цитируемый комментарий является либо неточным, либо я еще далек от большой картины, потому что я как бы пропускаю слово «** body **» от «адаптер не должен отправлять ответ ** body ** клиенту». Ответ отправляется независимо от метода запроса, только тело исключается из ответа на HEAD. Но опять же я, возможно, неправильно истолковываю, как работают адаптеры. –

+0

Правильный ответ. Серверы не должны отправлять тело в ** ответ ** на запрос HEAD ** **. Не имеет значения, имеет ли сам запрос HEAD ** ** тело. –

1

Поскольку Феникс во многом вдохновлен Rails, вы можете смело держать пари Plug.Head вдохновлен Rack::Head.

Запрос ГОЛОВЫ возвращает тот же ответ, как GET, но только с заголовками. Таким образом, чтобы создать правильные заголовки, они перенаправляются на действия GET в вашем приложении Phoenix.

Однако, чтобы создать правильное (пустое) тело, корпус ответчика должен быть удален. Поскольку Rack::Head является промежуточным программным обеспечением, он получает это после получения ответа от контроллеров.

Напротив, архитектура плагина больше похожа на конвейер, Plug.Head модифицирует метод и передает conn, но не видит его снова.

Если вы видите cdegroot's answer, эта ответственность передается в Plug.Conn.Adapter для реализации (то есть на веб-сервере).

+0

Итак, простой ответ заключается в том, что ** преобразование HEAD -> GET упрощает сопоставление маршрутов? ** Я протестировал простое приложение Phoenix с запросами 'curl' HEAD и GET, и ответы верны, а журналы отображают запрос HEAD правильно (хотя это неудивительно, поскольку «Plug.Logger» предшествует «Plug.Head»).Поэтому я предполагаю, что метод первоначального запроса сохраняется где-то, но это было бы материалом для другого вопроса. –

Смежные вопросы