JETTY-983 send content-length with ranges
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1006 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
4edf7c7039
commit
75c80264c2
|
@ -10,6 +10,7 @@ jetty-7.0.1-SNAPSHOT
|
|||
+ 291543 make bin/*.sh scripts executable in distribution
|
||||
+ 291589 Update jetty-rewrite demo
|
||||
+ JETTY-937 More JVM bug work arounds. Insert pause if all else fails
|
||||
+ JETTY-983 Send content-length with multipart ranges
|
||||
+ JETTY-1114 unsynchronised WebAppClassloader.getResource(String)
|
||||
+ JETTY-1121 Merge Multipart query parameters
|
||||
+ JETTY-1122 Handle multi-byte utf that causes buffer overflow
|
||||
|
|
|
@ -836,12 +836,28 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
|
|||
InputStream in=resource.getInputStream();
|
||||
long pos=0;
|
||||
|
||||
// calculate the content-length
|
||||
int length=0;
|
||||
String[] header = new String[ranges.size()];
|
||||
for (int i=0;i<ranges.size();i++)
|
||||
{
|
||||
InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
|
||||
String header=HttpHeaders.CONTENT_RANGE+": "+
|
||||
ibr.toHeaderRangeString(content_length);
|
||||
multi.startPart(mimetype,new String[]{header});
|
||||
header[i]=ibr.toHeaderRangeString(content_length);
|
||||
length+=
|
||||
((i>0)?2:0)+
|
||||
2+multi.getBoundary().length()+2+
|
||||
HttpHeaders.CONTENT_TYPE.length()+2+mimetype.length()+2+
|
||||
HttpHeaders.CONTENT_RANGE.length()+2+header[i].length()+2+
|
||||
2+
|
||||
(ibr.getLast(content_length)-ibr.getFirst(content_length))+1;
|
||||
}
|
||||
length+=2+2+multi.getBoundary().length()+2+2;
|
||||
response.setContentLength(length);
|
||||
|
||||
for (int i=0;i<ranges.size();i++)
|
||||
{
|
||||
InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
|
||||
multi.startPart(mimetype,new String[]{HttpHeaders.CONTENT_RANGE+": "+header[i]});
|
||||
|
||||
long start=ibr.getFirst(content_length);
|
||||
long size=ibr.getSize(content_length);
|
||||
|
|
|
@ -9,6 +9,7 @@ import junit.framework.TestCase;
|
|||
import org.eclipse.jetty.server.LocalConnector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
public class DefaultServletTest extends TestCase
|
||||
{
|
||||
|
@ -418,13 +419,99 @@ public class DefaultServletTest extends TestCase
|
|||
assertResponseContains("JSP support not configured",response);
|
||||
|
||||
}
|
||||
|
||||
public void testRangeRequests() throws Exception
|
||||
{
|
||||
File testDir = new File("target/tests/" + getName());
|
||||
prepareEmptyTestDir(testDir);
|
||||
File resBase = new File(testDir, "docroot");
|
||||
resBase.mkdirs();
|
||||
File data = new File(resBase, "data.txt");
|
||||
createFile(data,"01234567890123456789012345678901234567890123456789012345678901234567890123456789");
|
||||
String resBasePath = resBase.getAbsolutePath();
|
||||
|
||||
|
||||
|
||||
ServletHolder defholder = context.addServlet(DefaultServlet.class,"/");
|
||||
defholder.setInitParameter("acceptRanges","true");
|
||||
defholder.setInitParameter("resourceBase",resBasePath);
|
||||
|
||||
String response;
|
||||
|
||||
response= connector.getResponses(
|
||||
"GET /context/data.txt HTTP/1.1\r\n"+
|
||||
"Host: localhost\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"+
|
||||
"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"+
|
||||
"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"+
|
||||
"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"+
|
||||
"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"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void createFile(File file, String str) throws IOException
|
||||
{
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream(file);
|
||||
out.write(str.getBytes());
|
||||
out.write(str.getBytes(StringUtil.__UTF8));
|
||||
out.flush();
|
||||
} finally {
|
||||
IO.close(out);
|
||||
|
@ -495,7 +582,7 @@ public class DefaultServletTest extends TestCase
|
|||
}
|
||||
}
|
||||
|
||||
private void assertResponseContains(String expected, String response)
|
||||
private int assertResponseContains(String expected, String response)
|
||||
{
|
||||
int idx = response.indexOf(expected);
|
||||
if (idx == (-1))
|
||||
|
@ -508,5 +595,6 @@ public class DefaultServletTest extends TestCase
|
|||
System.err.println(err);
|
||||
throw new AssertionFailedError(err.toString());
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue