Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between doGet and doHead methods

I understand that doHead method does not send the body over http, however doGet does not either. Is there a clear difference between the two? Thanks in advance.

like image 302
Rollerball Avatar asked Feb 14 '23 17:02

Rollerball


2 Answers

Short answer

HEAD only sends back the same header information that the corresponding GET request would do, but with no entity body. And GET would send those same headers and the entity body. Of course in the rare/ arguable cases in which GET would send back nothing in its body, then GET and HEAD would behave similarly.

The book HTTP The Definitive Guide adds:

This allows a client to inspect the headers for a resource without having to actually get the resource. Using HEAD, you can:

  • Find out about a resource (e.g., determine its type) without getting it.
  • See if an object exists, by looking at the status code of the response.
  • Test if the resource has been modified, by looking at the headers.

Server developers must ensure that the headers returned are exactly those that a GET request would return. The HEAD method also is required for HTTP/1.1 compliance.

So, whether doHead invokes doGet may just be an implementation detail, but if so, the doHead would need to strip the body of doGet before sending the response. This implementation would be inefficient, though, since ideally doHead should not incur in the difficulties of performing the entire doGet request to determine which headers to send back.

The calculation of some headers may pose difficulties though. For instance, the "Content-Length" header implies we need to know the size of the actual resource and so HEAD may require to "GET" the resource to determine the actual size in bytes of the corresponding GET request, but it will not burden the network with actually sending the resource back, although it may have burdened the server with the retrieval of the resource in order to determine which headers to send back (i.e. Content-Length, Content-Type, Content-Language, etc.)

Long answer

The HTTP specification says

9.4 HEAD

The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification.

The response to a HEAD request MAY be cacheable in the sense that the information contained in the response MAY be used to update a previously cached entity from that resource. If the new field values indicate that the cached entity differs from the current entity (as would be indicated by a change in Content-Length, Content-MD5, ETag or Last-Modified), then the cache MUST treat the cache entry as stale.

Whereas for GET it says:

9.3 GET

The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process.

The semantics of the GET method change to a "conditional GET" if the request message includes an If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range header field. A conditional GET method requests that the entity be transferred only under the circumstances described by the conditional header field(s). The conditional GET method is intended to reduce unnecessary network usage by allowing cached entities to be refreshed without requiring multiple requests or transferring data already held by the client.

The semantics of the GET method change to a "partial GET" if the request message includes a Range header field. A partial GET requests that only part of the entity be transferred, as described in section 14.35. The partial GET method is intended to reduce unnecessary network usage by allowing partially-retrieved entities to be completed without transferring data already held by the client.

The response to a GET request is cacheable if and only if it meets the requirements for HTTP caching described in section 13.

See section 15.1.3 for security considerations when used for forms.

If you read the source code for javax.servlet.http.HttpServlet you can see that its documentation says:

Receives an HTTP HEAD request from the protected service method and handles the request. The client sends a HEAD request when it wants to see only the headers of a response, such as Content-Type or Content-Length. The HTTP HEAD method counts the output bytes in the response to set the Content-Length header accurately. If you override this method, you can avoid computing the response body and just set the response headers directly to improve performance. Make sure that the doHead method you write is both safe and idempotent (that is, protects itself from being called multiple times for one HTTP HEAD request). If the HTTP HEAD request is incorrectly formatted, doHead returns an HTTP "Bad Request" message.

And the default method implementation looks as follows:

protected void doHead(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
   NoBodyResponse response = new NoBodyResponse(resp);
   doGet(req, response);
   response.setContentLength();
}

If you read the code for NoBodyResponse you will see it is just a response whose output streams discards all data, and just counts the bytes to determine the proper Content-Length of the corresponding GET response.

So, this the way the Servlet specification proposes how to generate valid HEAD responses. You may override this behavior to make it more efficient, as long as you stick to the HTTP specification guidelines.

like image 120
Edwin Dalorzo Avatar answered Feb 24 '23 14:02

Edwin Dalorzo


doGet() is used when you want to intercept on HTTP GET requests. whereas

From the docs of DoHead:

Receives an HTTP HEAD request from the protected service method and handles the request. The client sends a HEAD request when it wants to see only the headers of a response, such as Content-Type or Content-Length. The HTTP HEAD method counts the output bytes in the response to set the Content-Length header accurately.

If you override this method, you can avoid computing the response body and just set the response headers directly to improve performance. Make sure that the doHead method you write is both safe and idempotent (that is, protects itself from being called multiple times for one HTTP HEAD request).

If the HTTP HEAD request is incorrectly formatted, doHead returns an HTTP "Bad Request" message.

like image 32
Rahul Tripathi Avatar answered Feb 24 '23 15:02

Rahul Tripathi