Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it useful to convert HEAD requests to GET requests?

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.

like image 334
toraritte Avatar asked Oct 18 '22 18:10

toraritte


2 Answers

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).

like image 92
Jay Jun Avatar answered Oct 21 '22 07:10

Jay Jun


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."

like image 44
cdegroot Avatar answered Oct 21 '22 08:10

cdegroot