You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Duncan McGregor <du...@oneeyedmen.com> on 2006/04/04 22:54:55 UTC

If-Range bug in DefaultServlet?

Hi

I've been making If-Range requests to Tomcat (5.5.16) and it seems  
not to be sending back content when the request and current ETags  
don't match.

RFC 2616 section 14.27 says

If the entity tag given in the If-Range header matches the current  
entity tag for the entity, then the server SHOULD provide the  
specified sub-range of the entity using a 206 (Partial content)  
response. If the entity tag does not match, then the server SHOULD  
return the entire entity using a 200 (OK) response.

Am I doing something wrong, or is the servlet behaviour not as it  
SHOULD be?

Thanks in anticipation

Duncan McGregor

The following testcase shows the current behaviour:

import java.io.IOException;

import junit.framework.TestCase;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;

import com.enterprisedt.net.ftp.FTPClient;

public class TomcatIfRangeTest extends TestCase {

     protected HttpClient httpClient;
     protected GetMethod getMethod;
     private FTPClient ftpClient;

     @Override
     public void setUp() throws Exception {
         httpClient = new HttpClient();
         ftpClient = new FTPClient();
         ftpClient.setRemoteHost("localhost");
         ftpClient.setControlPort(2122);
         ftpClient.connect();
         ftpClient.login("user", "user");
     }

     public void testIfRange() throws Exception {
         upload("contents", "delme.txt");
         assertEquals(HttpStatus.SC_OK, get("http://localhost:8080/ 
zirisEdge/public/delme.txt"));
         String etag = headerValue("ETag");
         assertEquals("contents", responseBody());

         assertEquals(HttpStatus.SC_PARTIAL_CONTENT,
                 get("http://localhost:8080/zirisEdge/public/delme.txt",
                         "If-Range", etag,
                         "Range", "bytes=1-3"
                 ));
         assertEquals(etag, headerValue("ETag"));
         assertEquals("ont", responseBody());

         upload("new contents", "delme.txt");
         assertEquals(HttpStatus.SC_OK,
                 get("http://localhost:8080/zirisEdge/public/delme.txt",
                         "If-Range", etag,
                         "Range", "bytes=1-3"
                 ));
         assertFalse(etag.equals(headerValue("ETag")));
         assertEquals("new contents", responseBody());
	  // FAILS as responseBody is ""
     }

     protected int get(String url, String...headerValues) throws  
HttpException, IOException {
         getMethod = new GetMethod(url);
         for (int i = 0; i < headerValues.length; i += 2) {
             getMethod.addRequestHeader(headerValues[i], headerValues 
[i +1]);
         }
         return httpClient.executeMethod(getMethod);
     }

     protected String responseBody() throws IOException {
         return getMethod.getResponseBodyAsString();
     }

     protected String headerValue(String headerName) {
         Header header = getMethod.getResponseHeader(headerName);
         return header != null ? header.getValue() : null;
     }

     protected void upload(String contents, String path) throws  
Exception {
         ftpClient.put(contents.getBytes(), path);
         Thread.sleep(5000); // TODO - is this a cache timeout?
     }


}


  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org