Announcement Announcement Module
Collapse
No announcement yet.
Request method 'HEAD' not supported, how to avoid this error Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Request method 'HEAD' not supported, how to avoid this error

    Hi
    We are using the Spring framework, for our website.
    We noticed the "Request method 'HEAD' not supported" in the log and traced down to the source code to see, that only GET and POST method are supported.

    How do we get rid of the error?
    Anyway to awoid HEAD request or even better make support for them?

    Supported methods at: org.springframework.web.servlet.support.WebContent Generator line 76-77


    Stack trace:
    Servlet.service() for servlet web threw exception
    org.springframework.web.servlet.support.RequestMet hodNotSupportedException: Request method 'HEAD' not supported
    at org.springframework.web.servlet.support.WebContent Generator.checkAndPrepare(WebContentGenerator.java :199)
    at org.springframework.web.servlet.support.WebContent Generator.checkAndPrepare(WebContentGenerator.java :178)
    at org.springframework.web.servlet.mvc.AbstractContro ller.handleRequest(AbstractController.java:116)
    at org.springframework.web.servlet.mvc.SimpleControll erHandlerAdapter.handle(SimpleControllerHandlerAda pter.java:44)
    at org.springframework.web.servlet.DispatcherServlet. doService(DispatcherServlet.java:532)
    at org.springframework.web.servlet.FrameworkServlet.s erviceWrapper(FrameworkServlet.java:366)
    at org.springframework.web.servlet.FrameworkServlet.d oHead(FrameworkServlet.java:353)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:714)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:810)

  • #2
    Do you have a specific requirement for clients to be able to access it with the HEAD method (or a monitoring utility that could be tuned to use GET rather than HEAD?)

    A possible workaround might be to front-end your site with apache/mod_proxy, or a LIMIT directive and custom error messages.

    Comment


    • #3
      most well behaved spiders will use HEAD to determine whether they need to perform a subsequent GET on the same resource.

      Comment


      • #4
        Good point. With mod_proxy it would be easy to host a static Apache driven site at <url> that is frendly to HEAD method requests, while passing back everything to /<context> (or do the same with any modern hardware load balancer).

        You could exclude /<context> in your robots.txt file.

        Comment


        • #5
          You can tell your controler to support the HEAD method using setSupportedMethods(String[] supportedMethodsArray) .

          Ollie

          Comment


          • #6
            Yes that'll work. A bit of a pain though as I now have to add that property to all my controllers.

            Shouldn't HEAD be supported by default? I thought that a servlet would normally execute the HEAD in the same way as a GET request. It needs to do this so that it can set the content-length header. It would just not return the response body to the client.

            Comment


            • #7
              Well, what we could do is add HEAD to the default list of supported methods. However, that would let all controllers receive HEAD requests by default... Would that lead to unexpected behavior? Such controllers would then usually behave just like for a GET request, which means unnecessarily creating the response body - how would a client that sent a HEAD request behave in such a case?

              Juergen

              Comment


              • #8
                Actually, all Controller implementations that do not derive from AbstractController won't have such a GET/POST check anyway, so receive HEAD requests already. So I guess that adding HEAD as default supported method wouldn't hurt existing controllers.

                Of course we could also remove the overridden doHead method in FrameworkServlet, do let the standard HttpServlet handle this. But that would remove the option to specifically handle HEAD requests in controllers, which one could do in a optimized fashion if it is straightforward to calculate the expected content length.

                Does the standard HttpServlet do anything special in its doHead implementation? It doesn't know a proper content length, so it can't properly handle HEAD anyway (unless the doHead method is overridden), I assume.

                Juergen

                Comment


                • #9
                  The HttpServlet class (in Tomcat at least) calls doGet with a 'NoBodyResponse' object from the doHead method. This object just counts the bytes written to it. The content length is then set on the response. Code shown below;

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


                  This means that the developer does not need to worry about implementing handlers for HEAD requests. They normally appear as GET requests, it is just that the body is not transmitted across the network to the client. Of course if there is an easy way to work out the content length without processing the request, the developer could override the doHead method.

                  If the WebContentGenerator allowed HEAD methods and the doHead method was not overidden in FrameworkServlet, Spring should then behave in the same way as standard servlets for HEAD requests.

                  In spring 1.1.3 doHead is overridden as final, so there is no way to directly handle HEAD requests, other than checking the method in the handleRequest method?

                  Mark

                  Comment


                  • #10
                    I've simply removed the overridden doHead method in FrameworkServlet, letting HttpServlet's default doHead behavior apply.

                    This means that a Controller will receive a handleRequest call with request method HEAD in such a case, passing in the NoBodyResponse managed by HttpServlet. So if no special check is made, the content length of the GET output will be captured.

                    If a Controller wants to specifically handle HEAD, it can simply perform a "HEAD".equals(request.getMethod()) check and call response.setContentLength accordingly. HttpServlet's NoBodyResponse will detect that value and use it.

                    Please give one of the next nightly 1.1.5-dev snapshots (http://www.springframework.org/downloads/nightly) a try, if you have the chance!

                    Juergen

                    Comment


                    • #11
                      I have tried using the 1.1.5-dev snapshot and it seems to work perfectly. Thanks. Looking forward to the 1.1.5 release.

                      Mark

                      Comment

                      Working...
                      X