In a new Phoenix app the Plug.Head
plug is present by default and I was intrigued about its significance.
I know that "the HEAD method is identical to GET except that the server MUST NOT send a message body in the response".
I think the official Phoenix guides are top-notch but this threw me off in the Routing guide:
Plug.Head - converts HEAD requests to GET requests and strips the response body
If HEAD requests are without a body then why is this needed? I thought maybe to rein in malformed requests but looking at the Plug.Head implementation, it just switches the HEAD method to GET.
def call(%Conn{method: "HEAD"} = conn, []), do: %{conn | method: "GET"}
def call(conn, []), do: conn
end
The closest thing I was able to find on this topic is a question on ServerFault but it was related to NGINX and a flawed application logic where HEAD requests needed to be converted to GET and the respective GET responses back to HEAD.
Since Phoenix is largely inspired by Rails, you can safely bet Plug.Head
is inspired by Rack::Head
.
A HEAD request returns the same response as GET but with headers only. So to produce the correct headers, they're routed to GET actions in your Phoenix app.
However to produce the correct (empty) body, the response's body must be stripped. Because Rack::Head
is middleware, it gets to do so after it gets the response from controllers.
In contrast, Plug's architecture works more like a pipeline, Plug.Head
modifies the method and passes conn
along, but never sees it again.
If you see cdegroot's answer, the responsibility to strip the response's body is passed to the Plug.Conn.Adapter
to implement (i.e. the webserver).
AFAICT, the idea is that Plug.Head
just ensures that the request is processed as a GET
; the second part of implementing HEAD
, which is not sending a body, is done by the Plug connection adapters. The documentation for most callbacks, like send_resp, specifies that "If the request has method "HEAD"
, the adapter should not send the response to the client."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With