// if there is only a single valid range (must be satisfiable
// since were here now), send that range with a 216 response
if ( ranges.size()== 1)
{
InclusiveByteRange singleSatisfiableRange =
(InclusiveByteRange)ranges.get(0);
long singleLength = singleSatisfiableRange.getSize(content_length);
writeHeaders(response,content,singleLength );
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
response.setHeader(HttpHeaders.CONTENT_RANGE,
singleSatisfiableRange.toHeaderRangeString(content_length));
resource.writeTo(out,singleSatisfiableRange.getFirst(content_length),singleLength);
return;
}
// multiple non-overlapping valid ranges cause a multipart
// 216 response which does not require an overall
// content-length header
//
writeHeaders(response,content,-1);
String mimetype=content.getContentType().toString();
MultiPartOutputStream multi = new MultiPartOutputStream(out);
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
// If the request has a "Request-Range" header then we need to
// send an old style multipart/x-byteranges Content-Type. This
// keeps Netscape and acrobat happy. This is what Apache does.
String ctp;
if (request.getHeader(HttpHeaders.REQUEST_RANGE)!=null)
ctp = "multipart/x-byteranges; boundary=";
else
ctp = "multipart/byteranges; boundary=";
response.setContentType(ctp+multi.getBoundary());
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);
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);
if (in!=null)
{
// Handle non cached resource
if (start<pos)
{