Announcement Announcement Module
Collapse
No announcement yet.
ResourceHttpRequestHandler 304 and Content-Length Header Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • ResourceHttpRequestHandler 304 and Content-Length Header

    I've been debugging an issue while using the Jetty ProxyServlet to proxy all requests to a backend server which uses the mvc:resources namespace element. I finally tracked the issue down to Jetty's ProxyServlet hanging while waiting for content from the backend server. Originally I thought this was a Jetty issue, but as I look at the HTTP headers, I think it is an issue with ResourceHttpRequestHandler.

    ResourceHttpRequestHandler, at line 124 always sets the HTTP headers of Content-Length and Content-Type. Immediately after this call, at line 125, the response is returned if it is found that the resource hasn't changed and a 304 can be returned. What this means is that a "304 Not Modified" status is returned but the Content-Length header is set.

    I've found conflicting reports as to who is in the wrong here, but RFC 2616 says,
    If the conditional GET used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers. Otherwise (i.e., the conditional GET used a weak validator), the response MUST NOT include other entity-headers; this prevents inconsistencies between cached entity-bodies and updated headers.
    So, in either case (strong or weak validators), it seems like the ResourceHttpRequestHandler should not be setting a Content-Length header because clients could hang waiting for the content.

    So is this a bug in Spring? Is there any workaround besides sub-classing the handler or disabling the cache?

    -mike

  • #2
    Possible Workaround

    I was able to workaround the issue by extending the ResourceHttpRequestHandler and creating a response wrapper that sets the content length to 0 if the status code is set to 304. Unfortunately there isn't a way to completely remove the header once it is set.

    Code:
    public void handleRequest(HttpServletRequest request,
          HttpServletResponse response) throws ServletException, IOException {
    
        HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(
            response) {
        
          @Override
          public void setStatus(int sc) {
            super.setStatus(sc);
    
            if (sc == SC_NOT_MODIFIED && containsHeader("Content-Length")) {
              log.debug("Clearing the content length because the status is NOT MODIFIED");
              setIntHeader("Content-Length", 0);
            }
          }
        };
    
        super.handleRequest(request, wrapper);
      }
    This made Jetty's ProxyServlet and Chrome happy so I'm pretty confident this is a Spring issue with returning the content length even on a 304.

    -mike

    Comment


    • #3
      Mike,
      Would you mind opening a JIRA reporting this issue at jira.springframework.org?

      Comment


      • #4
        Done. Find it here: https://jira.springsource.org/browse/SPR-8013

        -mike

        Comment

        Working...
        X