Merge remote-tracking branch 'origin/jetty-8'

Conflicts:
	jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
	jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
This commit is contained in:
Jan Bartel 2012-12-24 16:48:12 +11:00
commit 73d90623c7
3 changed files with 157 additions and 4 deletions

View File

@ -966,7 +966,9 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
// content-length header // content-length header
// //
writeHeaders(response,content,-1); writeHeaders(response,content,-1);
String mimetype=content.getContentType().toString(); String mimetype=(content.getContentType()==null?null:content.getContentType().toString());
if (mimetype==null)
LOG.warn("Unknown mimetype for "+request.getRequestURI());
MultiPartOutputStream multi = new MultiPartOutputStream(out); MultiPartOutputStream multi = new MultiPartOutputStream(out);
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
@ -993,7 +995,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
length+= length+=
((i>0)?2:0)+ ((i>0)?2:0)+
2+multi.getBoundary().length()+2+ 2+multi.getBoundary().length()+2+
HttpHeader.CONTENT_TYPE.asString().length()+2+mimetype.length()+2+ (mimetype==null?0:HttpHeader.CONTENT_TYPE.asString().length()+2+mimetype.length())+2+
HttpHeader.CONTENT_RANGE.asString().length()+2+header[i].length()+2+ HttpHeader.CONTENT_RANGE.asString().length()+2+header[i].length()+2+
2+ 2+
(ibr.getLast(content_length)-ibr.getFirst(content_length))+1; (ibr.getLast(content_length)-ibr.getFirst(content_length))+1;

View File

@ -23,6 +23,8 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.EnumSet; import java.util.EnumSet;
import javax.servlet.DispatcherType; import javax.servlet.DispatcherType;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.servlet.Filter; import javax.servlet.Filter;
@ -462,6 +464,153 @@ public class DefaultServletTest
} }
} }
@Test
public void testRangeRequests() throws Exception
{
testdir.ensureEmpty();
File resBase = testdir.getFile("docroot");
FS.ensureDirExists(resBase);
File data = new File(resBase, "data.txt");
createFile(data, "01234567890123456789012345678901234567890123456789012345678901234567890123456789");
String resBasePath = resBase.getAbsolutePath();
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
defholder.setInitParameter("dirAllowed", "false");
defholder.setInitParameter("redirectWelcome", "false");
defholder.setInitParameter("welcomeServlets", "false");
defholder.setInitParameter("gzip", "false");
defholder.setInitParameter("acceptRanges", "true");
defholder.setInitParameter("resourceBase", resBasePath);
String response = connector.getResponses("GET /context/data.txt HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n\r\n");
assertResponseContains("200 OK", response);
assertResponseContains("Accept-Ranges: bytes", response);
response = connector.getResponses("GET /context/data.txt HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n"+
"Range: bytes=0-9\r\n" +
"\r\n");
assertResponseContains("206 Partial", response);
assertResponseContains("Content-Type: text/plain", response);
assertResponseContains("Content-Length: 10", response);
assertResponseContains("Content-Range: bytes 0-9/80", response);
response = connector.getResponses("GET /context/data.txt HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n"+
"Range: bytes=0-9,20-29,40-49\r\n" +
"\r\n");
int start = response.indexOf("--jetty");
String body = response.substring(start);
String boundary = body.substring(0, body.indexOf("\r\n"));
assertResponseContains("206 Partial", response);
assertResponseContains("Content-Type: multipart/byteranges; boundary=", response);
assertResponseContains("Content-Range: bytes 0-9/80", response);
assertResponseContains("Content-Range: bytes 20-29/80", response);
assertResponseContains("Content-Length: " + body.length(), response);
assertTrue(body.endsWith(boundary + "--\r\n"));
response = connector.getResponses("GET /context/data.txt HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n"+
"Range: bytes=0-9,20-29,40-49,70-79\r\n" +
"\r\n");
start = response.indexOf("--jetty");
body = response.substring(start);
boundary = body.substring(0, body.indexOf("\r\n"));
assertResponseContains("206 Partial", response);
assertResponseContains("Content-Type: multipart/byteranges; boundary=", response);
assertResponseContains("Content-Range: bytes 0-9/80", response);
assertResponseContains("Content-Range: bytes 20-29/80", response);
assertResponseContains("Content-Range: bytes 70-79/80", response);
assertResponseContains("Content-Length: " + body.length(), response);
assertTrue(body.endsWith(boundary + "--\r\n"));
response = connector.getResponses("GET /context/data.txt HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n"+
"Range: bytes=0-9,20-29,40-49,60-60,70-79\r\n" +
"\r\n");
start = response.indexOf("--jetty");
body = response.substring(start);
boundary = body.substring(0, body.indexOf("\r\n"));
assertResponseContains("206 Partial", response);
assertResponseContains("Content-Type: multipart/byteranges; boundary=", response);
assertResponseContains("Content-Range: bytes 0-9/80", response);
assertResponseContains("Content-Range: bytes 20-29/80", response);
assertResponseContains("Content-Range: bytes 60-60/80", response);
assertResponseContains("Content-Range: bytes 70-79/80", response);
assertResponseContains("Content-Length: " + body.length(), response);
assertTrue(body.endsWith(boundary + "--\r\n"));
//test a range request with a file with no suffix, therefore no mimetype
File nofilesuffix = new File(resBase, "nofilesuffix");
createFile(nofilesuffix, "01234567890123456789012345678901234567890123456789012345678901234567890123456789");
response = connector.getResponses("GET /context/nofilesuffix HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n"+
"\r\n");
assertResponseContains("200 OK", response);
assertResponseContains("Accept-Ranges: bytes", response);
response = connector.getResponses("GET /context/nofilesuffix HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n"+
"Range: bytes=0-9\r\n" +
"\r\n");
assertResponseContains("206 Partial", response);
assertResponseContains("Content-Length: 10", response);
assertTrue(!response.contains("Content-Type:"));
assertResponseContains("Content-Range: bytes 0-9/80", response);
response = connector.getResponses("GET /context/nofilesuffix HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n"+
"Range: bytes=0-9,20-29,40-49\r\n" +
"\r\n");
start = response.indexOf("--jetty");
body = response.substring(start);
boundary = body.substring(0, body.indexOf("\r\n"));
assertResponseContains("206 Partial", response);
assertResponseContains("Content-Type: multipart/byteranges; boundary=", response);
assertResponseContains("Content-Range: bytes 0-9/80", response);
assertResponseContains("Content-Range: bytes 20-29/80", response);
assertResponseContains("Content-Length: " + body.length(), response);
assertTrue(body.endsWith(boundary + "--\r\n"));
response = connector.getResponses("GET /context/nofilesuffix HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n"+
"Range: bytes=0-9,20-29,40-49,60-60,70-79\r\n" +
"\r\n");
start = response.indexOf("--jetty");
body = response.substring(start);
boundary = body.substring(0, body.indexOf("\r\n"));
assertResponseContains("206 Partial", response);
assertResponseContains("Content-Type: multipart/byteranges; boundary=", response);
assertResponseContains("Content-Range: bytes 0-9/80", response);
assertResponseContains("Content-Range: bytes 20-29/80", response);
assertResponseContains("Content-Range: bytes 60-60/80", response);
assertResponseContains("Content-Range: bytes 70-79/80", response);
assertResponseContains("Content-Length: " + body.length(), response);
assertTrue(body.endsWith(boundary + "--\r\n"));
}
@Test @Test
public void testFiltered() throws Exception public void testFiltered() throws Exception
{ {

View File

@ -96,6 +96,7 @@ public class MultiPartOutputStream extends FilterOutputStream
out.write(__DASHDASH); out.write(__DASHDASH);
out.write(boundaryBytes); out.write(boundaryBytes);
out.write(__CRLF); out.write(__CRLF);
if (contentType != null)
out.write(("Content-Type: "+contentType).getBytes(StringUtil.__ISO_8859_1)); out.write(("Content-Type: "+contentType).getBytes(StringUtil.__ISO_8859_1));
out.write(__CRLF); out.write(__CRLF);
out.write(__CRLF); out.write(__CRLF);
@ -113,6 +114,7 @@ public class MultiPartOutputStream extends FilterOutputStream
out.write(__DASHDASH); out.write(__DASHDASH);
out.write(boundaryBytes); out.write(boundaryBytes);
out.write(__CRLF); out.write(__CRLF);
if (contentType != null)
out.write(("Content-Type: "+contentType).getBytes(StringUtil.__ISO_8859_1)); out.write(("Content-Type: "+contentType).getBytes(StringUtil.__ISO_8859_1));
out.write(__CRLF); out.write(__CRLF);
for (int i=0;headers!=null && i<headers.length;i++) for (int i=0;headers!=null && i<headers.length;i++)