Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFalko Schumann2017-09-08 14:57:29 +0000
committerRaymond Auge2018-01-22 15:55:42 +0000
commit2dc516548adf468508419079662995742a3457aa (patch)
treeaabfd261c0be595119ceefb533ad8db6834fee9c
parent4e6efcf250b2ce6dbde81d8c5f4c46382bbf086f (diff)
downloadrt.equinox.bundles-2dc516548adf468508419079662995742a3457aa.tar.gz
rt.equinox.bundles-2dc516548adf468508419079662995742a3457aa.tar.xz
rt.equinox.bundles-2dc516548adf468508419079662995742a3457aa.zip
Bug 519955 - ResourceServlet should handle range request
Support Range Requests (RFC7233) for requesting large files such as videos. Change-Id: I2965f3b534457a1a6f3cd41c73af5654331fd641 Signed-off-by: Falko Schumann <falko.schumann@bitctrl.de>
-rw-r--r--bundles/org.eclipse.equinox.http.servlet.tests/.classpath1
-rw-r--r--bundles/org.eclipse.equinox.http.servlet.tests/build.properties6
-rw-r--r--bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/META-INF/MANIFEST.MF19
-rw-r--r--bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/OSGI-INF/testResource1_component.xml10
-rw-r--r--bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/org/eclipse/equinox/http/servlet/tests/tb2/TestResource1.java18
-rw-r--r--bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/org/eclipse/equinox/http/servlet/tests/tb2/rangerequest.mp4255
-rw-r--r--bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java1
-rw-r--r--bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java103
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/RangeAwareServletContextHelper.java49
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResourceServlet.java166
10 files changed, 614 insertions, 14 deletions
diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/.classpath b/bundles/org.eclipse.equinox.http.servlet.tests/.classpath
index a7328b45b..980d19693 100644
--- a/bundles/org.eclipse.equinox.http.servlet.tests/.classpath
+++ b/bundles/org.eclipse.equinox.http.servlet.tests/.classpath
@@ -4,5 +4,6 @@
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" output="bundles_bin/tb1" path="bundles_src/tb1"/>
+ <classpathentry kind="src" output="bundles_bin/tb2" path="bundles_src/tb2"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/build.properties b/bundles/org.eclipse.equinox.http.servlet.tests/build.properties
index a5548edfa..5a5e20026 100644
--- a/bundles/org.eclipse.equinox.http.servlet.tests/build.properties
+++ b/bundles/org.eclipse.equinox.http.servlet.tests/build.properties
@@ -12,13 +12,17 @@ source.. = src/
bin.includes = .,\
META-INF/,\
bundles_bin/tb1.jar,\
+ bundles_bin/tb2.jar,\
about.html,\
http.context.test/,\
test.xml
jars.compile.order = .,\
- bundles_bin/tb1.jar
+ bundles_bin/tb1.jar,\
+ bundles_bin/tb2.jar
source.bundles_bin/tb1.jar = bundles_src/tb1/
+source.bundles_bin/tb2.jar = bundles_src/tb2/
manifest.bundles_bin/tb1.jar = META-INF/MANIFEST.MF
+manifest.bundles_bin/tb2.jar = META-INF/MANIFEST.MF
src.includes = test.xml,\
about.html
diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..0638e8cf9
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ActivationPolicy: lazy
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.equinox.http.servlet.tests.tb2
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-SymbolicName: org.eclipse.equinox.http.servlet.tests.tb2
+Bundle-Vendor: IBM
+Bundle-Version: 1.0.0.qualifier
+Service-Component: OSGI-INF/*_component.xml
+Import-Package: javax.servlet,
+ javax.servlet.http,
+ org.eclipse.equinox.http.servlet;version="1.1.0",
+ org.osgi.framework,
+ org.osgi.service.component,
+ org.osgi.service.http;version="1.2.1",
+ org.osgi.service.http.context;version="1.0.0",
+ org.osgi.service.http.runtime;version="1.0.0",
+ org.osgi.service.http.runtime.dto;version="1.0.0",
+ org.osgi.service.http.whiteboard;version="1.0.0"
diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/OSGI-INF/testResource1_component.xml b/bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/OSGI-INF/testResource1_component.xml
new file mode 100644
index 000000000..b11365160
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/OSGI-INF/testResource1_component.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true">
+ <implementation class="org.eclipse.equinox.http.servlet.tests.tb2.TestResource1"/>
+ <service>
+ <provide interface="org.eclipse.equinox.http.servlet.tests.tb2.TestResource1"/>
+ </service>
+ <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=foo)"/>
+ <property name="osgi.http.whiteboard.resource.pattern" type="String" value="/TestResource1/*"/>
+ <property name="osgi.http.whiteboard.resource.prefix" type="String" value="/org/eclipse/equinox/http/servlet/tests/tb2"/>
+</scr:component>
diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/org/eclipse/equinox/http/servlet/tests/tb2/TestResource1.java b/bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/org/eclipse/equinox/http/servlet/tests/tb2/TestResource1.java
new file mode 100644
index 000000000..3c550ea12
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/org/eclipse/equinox/http/servlet/tests/tb2/TestResource1.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Raymond Augé and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Raymond Augé <raymond.auge@liferay.com> - Bug 519955
+ ******************************************************************************/
+
+package org.eclipse.equinox.http.servlet.tests.tb2;
+
+/**
+ * @author Raymond Augé
+ */
+public class TestResource1 {
+}
diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/org/eclipse/equinox/http/servlet/tests/tb2/rangerequest.mp4 b/bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/org/eclipse/equinox/http/servlet/tests/tb2/rangerequest.mp4
new file mode 100644
index 000000000..800356f07
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet.tests/bundles_src/tb2/org/eclipse/equinox/http/servlet/tests/tb2/rangerequest.mp4
@@ -0,0 +1,255 @@
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java
index 1bc3f8037..9aaabd18c 100644
--- a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java
+++ b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java
@@ -195,6 +195,7 @@ public class BaseTest {
protected static final String STATUS_OK = "OK";
protected static final String TEST_BUNDLES_BINARY_DIRECTORY = "/bundles_bin/";
protected static final String TEST_BUNDLE_1 = "tb1";
+ protected static final String TEST_BUNDLE_2 = "tb2";
protected static final String[] BUNDLES = new String[] {
EQUINOX_DS_BUNDLE
diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java
index 2a422b046..3f5e679f4 100644
--- a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java
+++ b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java
@@ -75,6 +75,7 @@ import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.eclipse.equinox.http.servlet.RangeAwareServletContextHelper;
import org.eclipse.equinox.http.servlet.ExtendedHttpService;
import org.eclipse.equinox.http.servlet.context.ContextPathCustomizer;
import org.eclipse.equinox.http.servlet.session.HttpSessionInvalidator;
@@ -1775,6 +1776,108 @@ public class ServletTest extends BaseTest {
}
@Test
+ public void test_ResourceRangeRequest_Complete() throws Exception {
+ Bundle bundle = installBundle(TEST_BUNDLE_2);
+ ServletContextHelper customSCH = new ServletContextHelper(bundle) {
+ @Override
+ public String getMimeType(String filename) {
+ if (filename.endsWith(".mp4")) { //$NON-NLS-1$
+ return "video/mp4"; //$NON-NLS-1$
+ }
+ return null;
+ }
+ };
+ Dictionary<String, Object> contextProps = new Hashtable<String, Object>();
+ contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "foo");
+ contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/foo");
+ registrations.add(getBundleContext().registerService(ServletContextHelper.class, customSCH, contextProps));
+ Map<String, List<String>> actual;
+ Map<String, List<String>> requestHeader = new HashMap<>();
+ requestHeader.put("Range", Collections.singletonList("bytes=0-"));
+ try {
+ bundle.start();
+ actual = requestAdvisor.request("foo/TestResource1/rangerequest.mp4", requestHeader);
+ } finally {
+ uninstallBundle(bundle);
+ }
+ Assert.assertEquals("Response Code", Collections.singletonList("206"), actual.get("responseCode"));
+ Assert.assertEquals("Content-Length", Collections.singletonList("20655"), actual.get("Content-Length"));
+ Assert.assertEquals("Accept-Ranges", Collections.singletonList("bytes"), actual.get("Accept-Ranges"));
+ Assert.assertEquals("Content-Range", Collections.singletonList("bytes 0-20654/20655"), actual.get("Content-Range"));
+ }
+
+ @Test
+ public void test_ResourceRangeRequest_WithRange() throws Exception {
+ Map<String, List<String>> actual;
+ Bundle bundle = installBundle(TEST_BUNDLE_2);
+ ServletContextHelper customSCH = new ServletContextHelper(bundle) {
+ @Override
+ public String getMimeType(String filename) {
+ if (filename.endsWith(".mp4")) { //$NON-NLS-1$
+ return "video/mp4"; //$NON-NLS-1$
+ }
+ return null;
+ }
+ };
+ Dictionary<String, Object> contextProps = new Hashtable<String, Object>();
+ contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "foo");
+ contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/foo");
+ registrations.add(getBundleContext().registerService(ServletContextHelper.class, customSCH, contextProps));
+ Map<String, List<String>> requestHeader = new HashMap<>();
+ requestHeader.put("Range", Collections.singletonList("bytes=1000-9999"));
+ try {
+ bundle.start();
+ actual = requestAdvisor.request("foo/TestResource1/rangerequest.mp4", requestHeader);
+ } finally {
+ uninstallBundle(bundle);
+ }
+ Assert.assertEquals("Response Code", Collections.singletonList("206"), actual.get("responseCode"));
+ Assert.assertEquals("Content-Length", Collections.singletonList("9000"), actual.get("Content-Length"));
+ Assert.assertEquals("Accept-Ranges", Collections.singletonList("bytes"), actual.get("Accept-Ranges"));
+ Assert.assertEquals("Content-Range", Collections.singletonList("bytes 1000-9999/20655"), actual.get("Content-Range"));
+ Assert.assertEquals("Response Body Prefix", "901", actual.get("responseBody").get(0).substring(0, 3));
+ Assert.assertEquals("Response Body Suffix", "567", actual.get("responseBody").get(0).substring(8997, 9000));
+ }
+
+ @Test
+ public void test_ResourceRangeRequest_WithRange_customContext() throws Exception {
+ Map<String, List<String>> actual;
+ Bundle bundle = installBundle(TEST_BUNDLE_2);
+ RangeAwareServletContextHelper customSCH = new RangeAwareServletContextHelper(bundle) {
+ @Override
+ public String getMimeType(String filename) {
+ if (filename.endsWith(".mp4")) { //$NON-NLS-1$
+ return "video/mp4"; //$NON-NLS-1$
+ }
+ return null;
+ }
+ @Override
+ public boolean rangeableContentType(String contentType, String userAgent) {
+ return userAgent.contains("Foo") && contentType.startsWith("video/");
+ }
+ };
+ Dictionary<String, Object> contextProps = new Hashtable<String, Object>();
+ contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "foo");
+ contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/foo");
+ registrations.add(getBundleContext().registerService(ServletContextHelper.class, customSCH, contextProps));
+
+ Map<String, List<String>> requestHeader = new HashMap<>();
+ requestHeader.put("User-Agent", Collections.singletonList("Foo"));
+ try {
+ bundle.start();
+ actual = requestAdvisor.request("foo/TestResource1/rangerequest.mp4", requestHeader);
+ } finally {
+ uninstallBundle(bundle);
+ }
+ Assert.assertEquals("Response Code", Collections.singletonList("206"), actual.get("responseCode"));
+ Assert.assertEquals("Content-Length", Collections.singletonList("20655"), actual.get("Content-Length"));
+ Assert.assertEquals("Accept-Ranges", Collections.singletonList("bytes"), actual.get("Accept-Ranges"));
+ Assert.assertEquals("Content-Range", Collections.singletonList("bytes 0-20654/20655"), actual.get("Content-Range"));
+ Assert.assertEquals("Response Body Prefix", "123", actual.get("responseBody").get(0).substring(0, 3));
+ Assert.assertEquals("Response Body Suffix", "789", actual.get("responseBody").get(0).substring(8997, 9000));
+ }
+
+ @Test
public void test_Runtime() throws Exception {
Bundle bundle = installBundle(TEST_BUNDLE_1);
try {
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/RangeAwareServletContextHelper.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/RangeAwareServletContextHelper.java
new file mode 100644
index 000000000..7241b8418
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/RangeAwareServletContextHelper.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) Jan 20, 2018 Liferay, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Liferay, Inc. - initial API and implementation and/or initial
+ * documentation
+ ******************************************************************************/
+
+package org.eclipse.equinox.http.servlet;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.http.context.ServletContextHelper;
+
+/**
+ * A custom servlet context helper type providing support for predicting the need
+ * for ranged content responses based on the content type and the user agent.
+ *
+ * @since 1.4
+ */
+public abstract class RangeAwareServletContextHelper extends ServletContextHelper {
+
+ public RangeAwareServletContextHelper() {
+ super();
+ }
+
+ public RangeAwareServletContextHelper(Bundle bundle) {
+ super(bundle);
+ }
+
+ /**
+ * Return true if the content type should result in a ranged content response
+ * based on the user agent. The user agent value is obtained from the
+ * {@code User-Agent} request header.
+ * <p>
+ * This mechanism is only applicable if the browser didn't make a range request
+ * for a known ranged content type.
+ *
+ * @param contentType the content type of the request
+ * @param userAgent the value obtained from the "User-Agent" header
+ */
+ public boolean rangeableContentType(String contentType, String userAgent) {
+ return false;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResourceServlet.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResourceServlet.java
index e07d4aa10..2385f4f12 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResourceServlet.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResourceServlet.java
@@ -9,6 +9,7 @@
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
* Raymond Augé <raymond.auge@liferay.com> - Bug 436698
+ * Falko Schumann <falko.schumann@bitctrl.de> - Bug 519955
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal.servlet;
@@ -16,7 +17,10 @@ import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.servlet.http.*;
+import org.eclipse.equinox.http.servlet.RangeAwareServletContextHelper;
import org.eclipse.equinox.http.servlet.internal.util.Const;
import org.osgi.service.http.context.ServletContextHelper;
@@ -26,16 +30,20 @@ public class ResourceServlet extends HttpServlet {
private static final String IF_MODIFIED_SINCE = "If-Modified-Since"; //$NON-NLS-1$
private static final String IF_NONE_MATCH = "If-None-Match"; //$NON-NLS-1$
private static final String ETAG = "ETag"; //$NON-NLS-1$
+ private static final String RANGE = "Range"; //$NON-NLS-1$
+ private static final String ACCEPT_RANGES = "Accept-Ranges"; //$NON-NLS-1$
+ private static final String RANGE_UNIT_BYTES = "bytes"; //$NON-NLS-1$
+ private static final String CONTENT_RANGE = "Content-Range"; //$NON-NLS-1$
- private String internalName;
- private ServletContextHelper servletContextHelper;
- private AccessControlContext acc;
+ private final String internalName;
+ final ServletContextHelper servletContextHelper;
+ private final AccessControlContext acc;
public ResourceServlet(String internalName, ServletContextHelper servletContextHelper, AccessControlContext acc) {
- this.internalName = internalName;
if (internalName.equals(Const.SLASH)) {
- this.internalName = Const.BLANK;
+ internalName = Const.BLANK;
}
+ this.internalName = internalName;
this.servletContextHelper = servletContextHelper;
this.acc = acc;
}
@@ -86,13 +94,28 @@ public class ResourceServlet extends HttpServlet {
return Boolean.TRUE;
}
+ String rangeHeader = req.getHeader(RANGE);
+ Range range = null;
+ if (rangeHeader != null) {
+ range = Range.createFromRangeHeader(rangeHeader);
+ range.completeLength = contentLength;
+ range.updateBytePos();
+
+ if (!range.isValid()) {
+ resp.setHeader(ACCEPT_RANGES, RANGE_UNIT_BYTES);
+ resp.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
+ return Boolean.TRUE;
+ }
+ }
+
// return the full contents regularly
if (contentLength != -1)
resp.setContentLength(contentLength);
- String contentType = servletContextHelper.getMimeType(resourcePath);
+ String filename = new File(resourcePath).getName();
+ String contentType = servletContextHelper.getMimeType(filename);
if (contentType == null)
- contentType = getServletConfig().getServletContext().getMimeType(resourcePath);
+ contentType = getServletConfig().getServletContext().getMimeType(filename);
if (contentType != null)
resp.setContentType(contentType);
@@ -103,6 +126,23 @@ public class ResourceServlet extends HttpServlet {
if (etag != null)
resp.setHeader(ETAG, etag);
+ if (range == null &&
+ (servletContextHelper instanceof RangeAwareServletContextHelper) &&
+ ((RangeAwareServletContextHelper)servletContextHelper).rangeableContentType(contentType, req.getHeader("User-Agent"))) { //$NON-NLS-1$
+
+ range = new Range();
+ range.firstBytePos = 0;
+ range.completeLength = contentLength;
+ range.updateBytePos();
+ }
+
+ if (range != null) {
+ resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
+ resp.setHeader(ACCEPT_RANGES, RANGE_UNIT_BYTES);
+ resp.setContentLength(range.contentLength());
+ resp.setHeader(CONTENT_RANGE, RANGE_UNIT_BYTES + " " + range.firstBytePos + "-" + range.lastBytePos + "/" + range.completeLength); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
if (contentLength != 0) {
// open the input stream
InputStream is = null;
@@ -111,12 +151,12 @@ public class ResourceServlet extends HttpServlet {
// write the resource
try {
OutputStream os = resp.getOutputStream();
- int writtenContentLength = writeResourceToOutputStream(is, os);
+ int writtenContentLength = writeResourceToOutputStream(is, os, range);
if (contentLength == -1 || contentLength != writtenContentLength)
resp.setContentLength(writtenContentLength);
} catch (IllegalStateException e) { // can occur if the response output is already open as a Writer
Writer writer = resp.getWriter();
- writeResourceToWriter(is, writer);
+ writeResourceToWriter(is, writer, range);
// Since ContentLength is a measure of the number of bytes contained in the body
// of a message when we use a Writer we lose control of the exact byte count and
// defer the problem to the Servlet Engine's Writer implementation.
@@ -158,11 +198,22 @@ public class ResourceServlet extends HttpServlet {
}
}
- int writeResourceToOutputStream(InputStream is, OutputStream os) throws IOException {
+ int writeResourceToOutputStream(InputStream is, OutputStream os, Range range) throws IOException {
+ if (range != null) {
+ if (range.firstBytePos != Range.NOT_SET) {
+ is.skip(range.firstBytePos);
+ } else {
+ is.skip(range.completeLength - range.lastBytePos);
+ }
+ }
+
byte[] buffer = new byte[8192];
int bytesRead = is.read(buffer);
int writtenContentLength = 0;
- while (bytesRead != -1) {
+ while (bytesRead != -1 && (range == null || range.lastBytePos == Range.NOT_SET || writtenContentLength < range.lastBytePos)) {
+ if (range != null && range.lastBytePos != Range.NOT_SET && (bytesRead + writtenContentLength) > range.lastBytePos) {
+ bytesRead = range.contentLength() - writtenContentLength;
+ }
os.write(buffer, 0, bytesRead);
writtenContentLength += bytesRead;
bytesRead = is.read(buffer);
@@ -170,13 +221,26 @@ public class ResourceServlet extends HttpServlet {
return writtenContentLength;
}
- void writeResourceToWriter(InputStream is, Writer writer) throws IOException {
+ void writeResourceToWriter(InputStream is, Writer writer, Range range) throws IOException {
+ if (range != null) {
+ if (range.firstBytePos != Range.NOT_SET) {
+ is.skip(range.firstBytePos);
+ } else {
+ is.skip(range.completeLength - range.lastBytePos);
+ }
+ }
+
Reader reader = new InputStreamReader(is);
try {
char[] buffer = new char[8192];
int charsRead = reader.read(buffer);
- while (charsRead != -1) {
+ int writtenContentLength = 0;
+ while (charsRead != -1 && (range == null || range.lastBytePos == Range.NOT_SET || writtenContentLength < range.lastBytePos)) {
+ if (range != null && range.lastBytePos != Range.NOT_SET && (charsRead + writtenContentLength) > range.lastBytePos) {
+ charsRead = range.contentLength() - writtenContentLength;
+ }
writer.write(buffer, 0, charsRead);
+ writtenContentLength += charsRead;
charsRead = reader.read(buffer);
}
} finally {
@@ -185,4 +249,80 @@ public class ResourceServlet extends HttpServlet {
}
}
}
+
+ static class Range {
+
+ private static final Pattern RANGE_PATTERN = Pattern.compile("^(.+)=(\\d+)?-(\\d+)?$"); //$NON-NLS-1$
+
+ static final int NOT_SET = -1;
+
+ String rangeUnit = RANGE_UNIT_BYTES;
+ int firstBytePos = NOT_SET;
+ int lastBytePos = NOT_SET;
+ int completeLength = NOT_SET;
+
+ static Range createFromRangeHeader(String header) {
+ Range range = new Range();
+
+ Matcher matcher = RANGE_PATTERN.matcher(header);
+ if (!matcher.matches()) {
+ // use default values
+ return range;
+ }
+
+ range.rangeUnit = matcher.group(1);
+ if (matcher.group(2) != null) {
+ try {
+ range.firstBytePos = Integer.parseInt(matcher.group(2));
+ } catch (NumberFormatException ignored) {
+ // use default value
+ }
+ }
+ if (matcher.group(3) != null) {
+ try {
+ range.lastBytePos = Integer.parseInt(matcher.group(3));
+ } catch (NumberFormatException ignored) {
+ // use default value
+ }
+ }
+ return range;
+ }
+
+ void updateBytePos() {
+ if (lastBytePos == -1 || lastBytePos >= completeLength) {
+ lastBytePos = completeLength - 1;
+ }
+ if (firstBytePos == -1) {
+ firstBytePos = completeLength - lastBytePos - 1;
+ lastBytePos = completeLength - 1;
+ }
+ }
+
+ boolean isValid() {
+ // we accept bytes unit only
+ if (!RANGE_UNIT_BYTES.equals(rangeUnit)) {
+ return false;
+ }
+
+ if (firstBytePos == NOT_SET && lastBytePos == NOT_SET) {
+ return false;
+ }
+
+ if (firstBytePos >= completeLength) {
+ return false;
+ }
+
+ if (lastBytePos >= completeLength) {
+ return false;
+ }
+
+ return true;
+ }
+
+ int contentLength() {
+ return lastBytePos - firstBytePos + 1;
+ }
+
+ }
+
}

Back to the top