Content download merging of byte range requests for MSIE user-agent.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@19728 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2010-04-01 11:55:59 +00:00
parent 16e70c676f
commit 2bf2fc4d91

View File

@@ -23,6 +23,7 @@ import java.io.InputStream;
import java.net.SocketException; import java.net.SocketException;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@@ -87,6 +88,7 @@ public abstract class BaseDownloadContentServlet extends BaseServlet
private static final String HEADER_ETAG = "ETag"; private static final String HEADER_ETAG = "ETag";
private static final String HEADER_CACHE_CONTROL = "Cache-Control"; private static final String HEADER_CACHE_CONTROL = "Cache-Control";
private static final String HEADER_LAST_MODIFIED = "Last-Modified"; private static final String HEADER_LAST_MODIFIED = "Last-Modified";
private static final String HEADER_USER_AGENT = "User-Agent";
private static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition"; private static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
/** size of a multi-part byte range output buffer */ /** size of a multi-part byte range output buffer */
@@ -341,7 +343,9 @@ public abstract class BaseDownloadContentServlet extends BaseServlet
// ensure the range header is starts with "bytes=" and process the range(s) // ensure the range header is starts with "bytes=" and process the range(s)
if (range.length() > 6) if (range.length() > 6)
{ {
processedRange = processRange(res, reader, range.substring(6), nodeRef, propertyQName, mimetype); processedRange = processRange(
res, reader, range.substring(6), nodeRef, propertyQName,
mimetype, req.getHeader(HEADER_USER_AGENT));
} }
} }
if (processedRange == false) if (processedRange == false)
@@ -399,7 +403,7 @@ public abstract class BaseDownloadContentServlet extends BaseServlet
* Process a range header - handles single and multiple range requests. * Process a range header - handles single and multiple range requests.
*/ */
private boolean processRange(HttpServletResponse res, ContentReader reader, String range, private boolean processRange(HttpServletResponse res, ContentReader reader, String range,
NodeRef ref, QName property, String mimetype) NodeRef ref, QName property, String mimetype, String userAgent)
throws IOException throws IOException
{ {
// test for multiple byte ranges present in header // test for multiple byte ranges present in header
@@ -409,7 +413,7 @@ public abstract class BaseDownloadContentServlet extends BaseServlet
} }
else else
{ {
return processMultiRange(res, range, ref, property, mimetype); return processMultiRange(res, range, ref, property, mimetype, userAgent);
} }
} }
@@ -499,10 +503,12 @@ public abstract class BaseDownloadContentServlet extends BaseServlet
* @param ref NodeRef to the content for streaming * @param ref NodeRef to the content for streaming
* @param property Content Property for the content * @param property Content Property for the content
* @param mimetype Mimetype of the content * @param mimetype Mimetype of the content
* @param userAgent User Agent of the caller
* *
* @return true if processed range, false otherwise * @return true if processed range, false otherwise
*/ */
private boolean processMultiRange(HttpServletResponse res, String range, NodeRef ref, QName property, String mimetype) private boolean processMultiRange(
HttpServletResponse res, String range, NodeRef ref, QName property, String mimetype, String userAgent)
throws IOException throws IOException
{ {
final Log logger = getLogger(); final Log logger = getLogger();
@@ -552,27 +558,34 @@ public abstract class BaseDownloadContentServlet extends BaseServlet
if (ranges.size() != 0) if (ranges.size() != 0)
{ {
// merge byte ranges if possible // merge byte ranges if possible - IE handles this well, FireFox not so much
/*if (ranges.size() > 1) if (userAgent == null || userAgent.indexOf("MSIE ") != -1)
{ {
Collections.sort(ranges);
for (int i=0; i<ranges.size() - 1; i++) for (int i=0; i<ranges.size() - 1; i++)
{ {
Range first = ranges.get(i); Range first = ranges.get(i);
Range second = ranges.get(i + 1); Range second = ranges.get(i + 1);
if (first.end + 1 == second.start) if (first.end + 1 >= second.start)
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Merging byte range: " + first + " with " + second); logger.debug("Merging byte range: " + first + " with " + second);
// merge second range into first if (first.end < second.end)
first.end = second.end; {
// merge second range into first
first.end = second.end;
}
// else we simply discard the second range - it is contained within the first
// delete second range // delete second range
ranges.remove(i + 1); ranges.remove(i + 1);
// reset loop index // reset loop index
i--; i--;
} }
} }
}*/ }
// calculate response content length // calculate response content length
long length = MULTIPART_BYTERANGES_BOUNDRY_END.length() + 2; long length = MULTIPART_BYTERANGES_BOUNDRY_END.length() + 2;
@@ -815,7 +828,7 @@ public abstract class BaseDownloadContentServlet extends BaseServlet
*/ */
public int compareTo(Range o) public int compareTo(Range o)
{ {
return this.start < o.start ? 1 : -1; return this.start > o.start ? 1 : -1;
} }
} }