mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
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:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user