diff --git a/src/main/java/org/olat/commons/servlets/StaticsLegacyDispatcher.java b/src/main/java/org/olat/commons/servlets/StaticsLegacyDispatcher.java
index cbabe7b68fd404bcb6068a0319a53167aa688585..04130222005e05e63e3ccce9214a1b2d0e0d6c0a 100644
--- a/src/main/java/org/olat/commons/servlets/StaticsLegacyDispatcher.java
+++ b/src/main/java/org/olat/commons/servlets/StaticsLegacyDispatcher.java
@@ -232,6 +232,11 @@ public class StaticsLegacyDispatcher implements Dispatcher {
     		this.inStream = inStream;
     		this.rd = rd;
     	}
+    	
+    	@Override
+    	public boolean acceptRanges() {
+    		return false;
+    	}
 
 		@Override
 		public String getContentType() {
diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdDownloadZip.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdDownloadZip.java
index 56a5ff86109e9237d3be1f4ce2c85351d2fd8042..9f5f1a8576b58e244a6b0028feafccab8e4dbf74 100644
--- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdDownloadZip.java
+++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdDownloadZip.java
@@ -101,6 +101,11 @@ public class CmdDownloadZip implements FolderCommand {
 			this.selection = selection;
 			this.currentContainer = currentContainer;
 		}
+		
+		@Override
+		public boolean acceptRanges() {
+			return false;
+		}
 
 		@Override
 		public String getContentType() {
diff --git a/src/main/java/org/olat/core/gui/media/ClasspathMediaResource.java b/src/main/java/org/olat/core/gui/media/ClasspathMediaResource.java
index 0d623906e9f571d74fe442d8e174395f550b6392..fd54f5bf3d672e3b30daa2e8ee6ffc5de9d0a76d 100644
--- a/src/main/java/org/olat/core/gui/media/ClasspathMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/ClasspathMediaResource.java
@@ -158,6 +158,10 @@ public class ClasspathMediaResource extends LogDelegator implements MediaResourc
 		}
 	}
 	
+	@Override
+	public boolean acceptRanges() {
+		return true;
+	}
 
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#getContentType()
diff --git a/src/main/java/org/olat/core/gui/media/CleanupAfterDeliveryFileMediaResource.java b/src/main/java/org/olat/core/gui/media/CleanupAfterDeliveryFileMediaResource.java
index 184a5bf5bda1f81a41f0d3395b60ca132ccc3fc3..ba9ed00f483d06f57d89f74a6d2be144badc252d 100644
--- a/src/main/java/org/olat/core/gui/media/CleanupAfterDeliveryFileMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/CleanupAfterDeliveryFileMediaResource.java
@@ -45,6 +45,11 @@ public class CleanupAfterDeliveryFileMediaResource extends FileMediaResource {
 	public CleanupAfterDeliveryFileMediaResource(File file) {
 		super(file, true);
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#release()
diff --git a/src/main/java/org/olat/core/gui/media/DefaultMediaResource.java b/src/main/java/org/olat/core/gui/media/DefaultMediaResource.java
index 2dbfa35ecf9dfcbbebf8c06332df7ea5ccc37521..10c608f25c6cbae0d908466ae41108fe8f23711a 100644
--- a/src/main/java/org/olat/core/gui/media/DefaultMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/DefaultMediaResource.java
@@ -35,10 +35,14 @@ import javax.servlet.http.HttpServletResponse;
  */
 public class DefaultMediaResource implements MediaResource {
 
-	private String contentType;
 	private Long size;
-	private InputStream inputStream;
 	private Long lastModified;
+	private String contentType;
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#getContentType()
@@ -51,7 +55,7 @@ public class DefaultMediaResource implements MediaResource {
 	 * @see org.olat.core.gui.media.MediaResource#getInputStream()
 	 */
 	public InputStream getInputStream() {
-		return inputStream;
+		return null;
 	}
 
 	/**
@@ -75,13 +79,6 @@ public class DefaultMediaResource implements MediaResource {
 		this.contentType = contentType;
 	}
 
-	/**
-	 * @param inputStream
-	 */
-	public void setInputStream(InputStream inputStream) {
-		this.inputStream = inputStream;
-	}
-
 	/**
 	 * @param lastModified
 	 */
@@ -100,14 +97,13 @@ public class DefaultMediaResource implements MediaResource {
 	 * @see org.olat.core.gui.media.MediaResource#prepare(javax.servlet.http.HttpServletResponse)
 	 */
 	public void prepare(HttpServletResponse hres) {
-	//
+		//
 	}
 
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#release()
 	 */
 	public void release() {
-	//
+		//
 	}
-
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/core/gui/media/ExcelMediaResource.java b/src/main/java/org/olat/core/gui/media/ExcelMediaResource.java
index 13283389d6bd36f01834e34d4df923ac9d9170a6..f7c2d6aa7073d99ce205f3503aa3ae506a631e2f 100644
--- a/src/main/java/org/olat/core/gui/media/ExcelMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/ExcelMediaResource.java
@@ -52,8 +52,8 @@ public class ExcelMediaResource extends StringMediaResource {
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#prepare(javax.servlet.http.HttpServletResponse)
 	 */
+	@Override
 	public void prepare(HttpServletResponse hres) {
-
 		// anything
 		hres.setCharacterEncoding("utf-8");
 		
@@ -65,21 +65,7 @@ public class ExcelMediaResource extends StringMediaResource {
 		else {
 			name = optionalFilename;
 		}
-		
-		
-		/*try {
-		 //String test = "aüa\u0395\u0159a\u0641bcd\u0395a\u03BA\u03C4\u03B5a\u0410\u0432\u0442b\u0159c";
-		 String output = null;
-			byte[] b = test.getBytes("utf-8");
-			output = new String(b, "iso-8859-1");
-			String res = sb.toString();
-			//output = res;
-		} catch (UnsupportedEncodingException e) {
-		}
-		*/
-		//boolean isIE = false; // ie and konqueror and safari: true, only iso-8859-1
-		
-		//hres.setHeader("Content-Disposition", "attachment; filename=" + (isIE?test:output) + ".xls");
+
 		hres.setHeader("Content-Disposition", "attachment; filename=" + name + ".xls");
 		hres.setHeader("Content-Description", "OLAT Generated data");
 	}
@@ -93,10 +79,6 @@ public class ExcelMediaResource extends StringMediaResource {
 		if (!p.matcher(fileName).matches())	{
 			throw new AssertException(fileName + " is not a valid filename");
 		}
-		
-		//TODO: check for no file extension and only valid characters
-//		StringHelper.check4SafeFileName(fileName);
 		this.optionalFilename = fileName;
 	}
-
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/core/gui/media/FileMediaResource.java b/src/main/java/org/olat/core/gui/media/FileMediaResource.java
index 4ffb9fc521edaf98771dbd75e5639ffb5e17dc9c..894b5007c07ed662d8f914e11720c2a48ae348fa 100644
--- a/src/main/java/org/olat/core/gui/media/FileMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/FileMediaResource.java
@@ -89,9 +89,15 @@ public class FileMediaResource implements MediaResource {
 		this.filesInfoMBean = (FilesInfoMBean) CoreSpringFactory.getBean(FilesInfoMBean.class.getCanonicalName());
 	}
 	
+	@Override
+	public boolean acceptRanges() {
+		return true;
+	}
+	
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#getContentType()
 	 */
+	@Override
 	public String getContentType() {
 		String fileName = file.getName();
 		String mimeType = WebappHelper.getMimeType(fileName);
@@ -102,6 +108,7 @@ public class FileMediaResource implements MediaResource {
 	/**
 	 * @return @see org.olat.core.gui.media.MediaRequest#getSize()
 	 */
+	@Override
 	public Long getSize() {
 		return new Long(file.length());
 	}
@@ -109,6 +116,7 @@ public class FileMediaResource implements MediaResource {
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#getInputStream()
 	 */
+	@Override
 	public InputStream getInputStream() {
 		BufferedInputStream bis = null;
 		try {
@@ -123,6 +131,7 @@ public class FileMediaResource implements MediaResource {
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#getLastModified()
 	 */
+	@Override
 	public Long getLastModified() {
 		return new Long(file.lastModified());
 	}
@@ -130,6 +139,7 @@ public class FileMediaResource implements MediaResource {
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#release()
 	 */
+	@Override
 	public void release() {
 	// void
 	}
@@ -137,6 +147,7 @@ public class FileMediaResource implements MediaResource {
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#prepare(javax.servlet.http.HttpServletResponse)
 	 */
+	@Override
 	public void prepare(HttpServletResponse hres) {
 		if (deliverAsAttachment) {
 			// encode filename in ISO8859-1; does not really help but prevents from filename not being displayed at all
@@ -147,9 +158,9 @@ public class FileMediaResource implements MediaResource {
 			hres.setHeader("Content-Disposition", "inline");
 		}
 	}
-	
+
+	@Override
 	public String toString() {
 		return "FileMediaResource:"+file.getAbsolutePath();
 	}
-
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/core/gui/media/ForbiddenMediaResource.java b/src/main/java/org/olat/core/gui/media/ForbiddenMediaResource.java
index f4b033b62c4dbd7d52c8f6d6fce0bad9bdfd2f97..6a7be0dca0f7e9a83ba4b84a7b10bc354378912f 100644
--- a/src/main/java/org/olat/core/gui/media/ForbiddenMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/ForbiddenMediaResource.java
@@ -46,6 +46,7 @@ public class ForbiddenMediaResource extends DefaultMediaResource {
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#prepare(javax.servlet.http.HttpServletResponse)
 	 */
+	@Override
 	public void prepare(HttpServletResponse hres) {
 		try {
 			hres.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden: " + forbiddenFoundURI);
diff --git a/src/main/java/org/olat/core/gui/media/HttpRequestMediaResource.java b/src/main/java/org/olat/core/gui/media/HttpRequestMediaResource.java
index d3d7880576773b50aa4a7eb2a28b083c1ae1d927..dbe8dc1d061d86257ad526e10d13a212497bcfcc 100644
--- a/src/main/java/org/olat/core/gui/media/HttpRequestMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/HttpRequestMediaResource.java
@@ -56,6 +56,11 @@ public class HttpRequestMediaResource implements MediaResource {
 	public HttpRequestMediaResource(HttpResponse response) {
 		this.response = response;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#getContentType()
diff --git a/src/main/java/org/olat/core/gui/media/JSONMediaResource.java b/src/main/java/org/olat/core/gui/media/JSONMediaResource.java
index 37b8a02f4fc8a259128d8b41872f11e38f56556b..f25be8144bc3123a20744eb9221bdbcec148b894 100644
--- a/src/main/java/org/olat/core/gui/media/JSONMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/JSONMediaResource.java
@@ -20,7 +20,6 @@
 package org.olat.core.gui.media;
 
 import java.io.IOException;
-import java.io.InputStream;
 
 import javax.servlet.http.HttpServletResponse;
 
@@ -79,9 +78,4 @@ public class JSONMediaResource extends DefaultMediaResource {
 			log.error("", e);
 		}
 	}
-
-	@Override
-	public InputStream getInputStream() {
-		return null;
-	}
 }
diff --git a/src/main/java/org/olat/core/gui/media/MediaResource.java b/src/main/java/org/olat/core/gui/media/MediaResource.java
index f1fa323c66af295fa60ed8e3e135a6e3b1a71a26..1b265b7fdc047567fdeaa381d48cc53d2b6b5d4b 100644
--- a/src/main/java/org/olat/core/gui/media/MediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/MediaResource.java
@@ -35,6 +35,8 @@ import javax.servlet.http.HttpServletResponse;
  * @author Felix Jost
  */
 public interface MediaResource {
+	
+	public boolean acceptRanges();
 
 	/**
 	 * @return
diff --git a/src/main/java/org/olat/core/gui/media/MediaResourceFactory.java b/src/main/java/org/olat/core/gui/media/MediaResourceFactory.java
deleted file mode 100644
index 1d6b477b35b6010c64d61a3a671e0e82ba4e0153..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/core/gui/media/MediaResourceFactory.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
-* OLAT - Online Learning and Training<br>
-* http://www.olat.org
-* <p>
-* Licensed under the Apache License, Version 2.0 (the "License"); <br>
-* you may not use this file except in compliance with the License.<br>
-* You may obtain a copy of the License at
-* <p>
-* http://www.apache.org/licenses/LICENSE-2.0
-* <p>
-* Unless required by applicable law or agreed to in writing,<br>
-* software distributed under the License is distributed on an "AS IS" BASIS, <br>
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
-* See the License for the specific language governing permissions and <br>
-* limitations under the License.
-* <p>
-* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
-* University of Zurich, Switzerland.
-* <hr>
-* <a href="http://www.openolat.org">
-* OpenOLAT - Online Learning and Training</a><br>
-* This file has been modified by the OpenOLAT community. Changes are licensed
-* under the Apache 2.0 license as the original file.  
-* <p>
-*/ 
-package org.olat.core.gui.media;
-
-import java.io.InputStream;
-
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * Description:<br>
- * Factory for different common types of MediaResources
- * <P>
- * Initial Date: 09.01.2007 <br>
- * 
- * @author Felix Jost, http://www.goodsolutions.ch
- */
-public class MediaResourceFactory {
-
-	/**
-	 * Allow private browser caching of <seconds> seconds hours. After that period
-	 * the browser <br>
-	 * must revalidate the resource using a If-Modified-Since request header.<br>
-	 * Usually the answer will be a Not-Modified, but it gives us the chance<br>
-	 * to update CSS and Javascript files ant at least the next day users<br>
-	 * will be up to date as well. <br>
-	 * Add proxy max ager in case a proxy ignored the private cache settings.<br>
-	 * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9<br>
-	 * <br>
-	 * the bevaviour of this method is that it simply overwrites or sets a new
-	 * http-response-header:<br>
-	 * response.setHeader("Cache-Control", "private, max-age=21600,
-	 * s-maxage=21600");<br>
-	 * <br>
-	 * 
-	 * @param originalMediaResource the mediaResource to be cache-enabled
-	 * @param seconds determines how many seconds a browser may cache this
-	 *          mediaresource before revalidating it
-	 * @return the resulting cachable mediaresource
-	 */
-	// thanks to Florian Gnägi.
-	public static MediaResource createCachableMediaResource(MediaResource originalMediaResource, int seconds) {
-		return new CachableMediaResource(originalMediaResource, seconds);
-	}
-}
-
-class CachableMediaResource implements MediaResource {
-	private final MediaResource original;
-	private final int seconds;
-
-	public CachableMediaResource(MediaResource original, int seconds) {
-		this.original = original;
-		this.seconds = seconds;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.olat.core.gui.media.MediaResource#getContentType()
-	 */
-	public String getContentType() {
-		return original.getContentType();
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.olat.core.gui.media.MediaResource#getInputStream()
-	 */
-	public InputStream getInputStream() {
-		return original.getInputStream();
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.olat.core.gui.media.MediaResource#getLastModified()
-	 */
-	public Long getLastModified() {
-		return original.getLastModified();
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.olat.core.gui.media.MediaResource#getSize()
-	 */
-	public Long getSize() {
-		return original.getSize();
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.olat.core.gui.media.MediaResource#prepare(javax.servlet.http.HttpServletResponse)
-	 */
-	public void prepare(HttpServletResponse hres) {
-		original.prepare(hres);
-		// add or set additional header
-		hres.setHeader("Cache-Control", "private, max-age=" + seconds + ", s-maxage=" + seconds);
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.olat.core.gui.media.MediaResource#release()
-	 */
-	public void release() {
-		original.release();
-	}
-
-}
diff --git a/src/main/java/org/olat/core/gui/media/MimedFileMediaResource.java b/src/main/java/org/olat/core/gui/media/MimedFileMediaResource.java
deleted file mode 100644
index 60cbfd490221fe09ef734dce64fdf45f790d032e..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/core/gui/media/MimedFileMediaResource.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
-* OLAT - Online Learning and Training<br>
-* http://www.olat.org
-* <p>
-* Licensed under the Apache License, Version 2.0 (the "License"); <br>
-* you may not use this file except in compliance with the License.<br>
-* You may obtain a copy of the License at
-* <p>
-* http://www.apache.org/licenses/LICENSE-2.0
-* <p>
-* Unless required by applicable law or agreed to in writing,<br>
-* software distributed under the License is distributed on an "AS IS" BASIS, <br>
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
-* See the License for the specific language governing permissions and <br>
-* limitations under the License.
-* <p>
-* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
-* University of Zurich, Switzerland.
-* <hr>
-* <a href="http://www.openolat.org">
-* OpenOLAT - Online Learning and Training</a><br>
-* This file has been modified by the OpenOLAT community. Changes are licensed
-* under the Apache 2.0 license as the original file.  
-* <p>
-*/ 
-
-package org.olat.core.gui.media;
-
-import java.io.File;
-
-/**
- * Description:<BR/>
- * <p>
- * The mimed file media resource explicitly uses the given mime type instead of
- * the mime type compiled from the file name.
- * <p>
- * Initial Date: Mar 7, 2005
- * 
- * @author Felix Jost
- */
-public class MimedFileMediaResource extends FileMediaResource {
-
-	private final String mimeType;
-
-	/**
-	 * @param file
-	 * @param mimeType
-	 * @param deliverAsAttachment true: deliver as attachment; false: deliver inline
-	 */
-	public MimedFileMediaResource(File file, String mimeType, boolean deliverAsAttachment) {
-		super(file, deliverAsAttachment);
-		this.mimeType = mimeType;	
-	}
-
-	/**
-	 * @see org.olat.core.gui.media.MediaResource#getContentType()
-	 */
-	public String getContentType() {
-		return mimeType;
-	}
-}
diff --git a/src/main/java/org/olat/core/gui/media/NotFoundMediaResource.java b/src/main/java/org/olat/core/gui/media/NotFoundMediaResource.java
index 93ace1f98d822e154ce748c4ba26d2abb4ef70e7..340bd49a6c0bf13c5c035d1891a03f756ba12278 100644
--- a/src/main/java/org/olat/core/gui/media/NotFoundMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/NotFoundMediaResource.java
@@ -48,6 +48,7 @@ public class NotFoundMediaResource extends DefaultMediaResource {
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#prepare(javax.servlet.http.HttpServletResponse)
 	 */
+	@Override
 	public void prepare(HttpServletResponse hres) {
 		try {
 			hres.sendError(HttpServletResponse.SC_NOT_FOUND, "Not found: " + notFoundURI);
@@ -55,5 +56,4 @@ public class NotFoundMediaResource extends DefaultMediaResource {
 			// we can do nothing better
 		}
 	}
-
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/core/gui/media/NothingChangedMediaResource.java b/src/main/java/org/olat/core/gui/media/NothingChangedMediaResource.java
index c1acaf4f6662e9d333aff25b6f751455b44757ee..a57ccb3eb6fe79685ff0dfe508e0cbdf00394d90 100644
--- a/src/main/java/org/olat/core/gui/media/NothingChangedMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/NothingChangedMediaResource.java
@@ -39,6 +39,7 @@ public class NothingChangedMediaResource extends DefaultMediaResource {
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#prepare(javax.servlet.http.HttpServletResponse)
 	 */
+	@Override
 	public void prepare(HttpServletResponse hres) {
 		hres.setStatus(HttpServletResponse.SC_OK);
 	}
diff --git a/src/main/java/org/olat/core/gui/media/RedirectMediaResource.java b/src/main/java/org/olat/core/gui/media/RedirectMediaResource.java
index 79c642414c2ae9a4b0f601da3162752ff5cc78b9..35850b02a3bc9d7dfb9b041c1f64c9e0d290f2cb 100644
--- a/src/main/java/org/olat/core/gui/media/RedirectMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/RedirectMediaResource.java
@@ -49,6 +49,11 @@ public class RedirectMediaResource implements MediaResource {
 	public RedirectMediaResource(String redirectURL) {
 		this.redirectURL = redirectURL;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#getContentType()
diff --git a/src/main/java/org/olat/core/gui/media/ServletUtil.java b/src/main/java/org/olat/core/gui/media/ServletUtil.java
index 3aea7ffdbb920e663f6fe88868aab0c896c5bc26..68fbf52b6848a3837de013274e57139827b2cc24 100644
--- a/src/main/java/org/olat/core/gui/media/ServletUtil.java
+++ b/src/main/java/org/olat/core/gui/media/ServletUtil.java
@@ -157,7 +157,7 @@ public class ServletUtil {
 
 			//fxdiff FXOLAT-118: accept range to deliver videos for iPad (implementation based on Tomcat)
 			List<Range> ranges = parseRange(httpReq, httpResp, (lastModified == null ? -1 : lastModified.longValue()), (size == null ? 0 : size.longValue()));
-			if(ranges != null) {
+			if(ranges != null && mr.acceptRanges()) {
 				httpResp.setHeader("Accept-Ranges", "bytes");
 			}
 			// maybe some more preparations
diff --git a/src/main/java/org/olat/core/gui/media/StreamedMediaResource.java b/src/main/java/org/olat/core/gui/media/StreamedMediaResource.java
index 174e07eedd70eb8dc0f5c88be0fb09547bb5d90b..d2df2f1aef3f12d2b6073f804b3d9399eacc7d94 100644
--- a/src/main/java/org/olat/core/gui/media/StreamedMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/StreamedMediaResource.java
@@ -57,6 +57,11 @@ public class StreamedMediaResource implements MediaResource {
 		this.lastModified = lastModified;
 		this.contentType = contentType;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	@Override
 	public String getContentType() {
diff --git a/src/main/java/org/olat/core/gui/media/StringMediaResource.java b/src/main/java/org/olat/core/gui/media/StringMediaResource.java
index 9b7e1fcc8ae8f434631679c8ff98e61a67d0be04..67f6f3eab5dae3106e236834f4c889ccdee44e95 100644
--- a/src/main/java/org/olat/core/gui/media/StringMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/StringMediaResource.java
@@ -30,6 +30,7 @@ import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
+
 import javax.servlet.http.HttpServletResponse;
 
 import org.olat.core.logging.AssertException;
@@ -42,6 +43,11 @@ public class StringMediaResource extends DefaultMediaResource {
 	//default - if no encoding is specified we assume iso latin
 	private String encoding = "iso-8859-1";
 	private String data;
+	
+	@Override
+	public boolean acceptRanges() {
+		return true;
+	}
 
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#getInputStream()
diff --git a/src/main/java/org/olat/core/gui/media/WorkbookMediaResource.java b/src/main/java/org/olat/core/gui/media/WorkbookMediaResource.java
index c64f43a806f8da63caa69b0a6688730367a56aad..9a48e9ae5cc0427290eb0763e5dbdb8b39df17d8 100644
--- a/src/main/java/org/olat/core/gui/media/WorkbookMediaResource.java
+++ b/src/main/java/org/olat/core/gui/media/WorkbookMediaResource.java
@@ -19,13 +19,12 @@
  */
 package org.olat.core.gui.media;
 
-import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.poi.ss.usermodel.Workbook;
-import org.olat.core.commons.modules.bc.FolderConfig;
 import org.olat.core.logging.AssertException;
 import org.olat.core.util.CodeHelper;
 
@@ -36,30 +35,58 @@ import org.olat.core.util.CodeHelper;
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  *
  */
-public class WorkbookMediaResource extends FileMediaResource {
+public class WorkbookMediaResource implements MediaResource {
 
+	private final Workbook wb;
+	
 	public WorkbookMediaResource(Workbook wb) {
-		super(null, true);
-		
-		FileOutputStream fos = null;
+		this.wb = wb;
+	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
+
+	@Override
+	public String getContentType() {
+		return "application/vnd.ms-excel; charset=utf-8";
+	}
+
+	@Override
+	public Long getSize() {
+		return null;
+	}
+
+	@Override
+	public InputStream getInputStream() {
+		return null;
+	}
+
+	@Override
+	public Long getLastModified() {
+		return null;
+	}
+
+	@Override
+	public void prepare(HttpServletResponse hres) {
+		hres.setCharacterEncoding("utf-8");
+		String name = "TableExport" + CodeHelper.getRAMUniqueID();
+		hres.setHeader("Content-Disposition", "attachment; filename=" + name + ".xls");
+		hres.setHeader("Content-Description", "OpenOLAT Generated data");
 		try {
-			File f = new File(FolderConfig.getCanonicalTmpDir(), "TableExport" + CodeHelper.getRAMUniqueID() + ".xls");
-			fos = new FileOutputStream(f);
-			wb.write(fos);
-			fos.close();
-			this.file = f;
+			wb.write(hres.getOutputStream());
 		} catch (IOException e) {
 			throw new AssertException("error preparing media resource for XLS Table Export", e);
-		} finally {
-			IOUtils.closeQuietly(fos);
 		}
 	}
-	
+
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#release()
 	 */
+	@Override
 	public void release() {
-		file.delete();
+		//
 	}
 
 
diff --git a/src/main/java/org/olat/core/servlets/StaticServlet.java b/src/main/java/org/olat/core/servlets/StaticServlet.java
index 4b72e70d8e2ecc2a6d395bd4fb2f06b4d4e65a22..8e10dacbe4a260e16ab63faef462c8b8be524cd5 100644
--- a/src/main/java/org/olat/core/servlets/StaticServlet.java
+++ b/src/main/java/org/olat/core/servlets/StaticServlet.java
@@ -20,7 +20,9 @@
 package org.olat.core.servlets;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -35,6 +37,7 @@ import org.olat.core.gui.media.ServletUtil;
 import org.olat.core.helpers.Settings;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
+import org.olat.core.util.FileUtils;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.WebappHelper;
 
@@ -49,6 +52,8 @@ public class StaticServlet extends HttpServlet {
 
 	private static final long serialVersionUID = -2430002903299685192L;
 	private static final OLog log = Tracing.createLoggerFor(StaticServlet.class);
+	private final int CACHE_DURATION_IN_SECOND = 60 * 60 * 24 * 8; // 8 days
+	private final long CACHE_DURATION_IN_MS = CACHE_DURATION_IN_SECOND  * 1000;
 
 	public static String STATIC_DIR_NAME = "/static";
 	public static String NOVERSION = "_noversion_";
@@ -63,28 +68,35 @@ public class StaticServlet extends HttpServlet {
 		} else {
 			super.service(req, resp);
 		}
+		
+		if("head".equalsIgnoreCase(req.getMethod())) {
+			System.out.println("HEAD");
+			System.out.println("HEAD");
+			System.out.println("HEAD");
+			System.out.println("HEAD");
+		}
 	}
 
 	@Override
 	protected void doGet(HttpServletRequest request, HttpServletResponse response)
 	throws ServletException, IOException {
-		final boolean debug = log.isDebug();
 		final String pathInfo = request.getPathInfo();
 		if (pathInfo == null) {
 			// huh? What's this, send not found, don't know what to do here
-			if (debug) {
-				log.debug("PathInfo is null for static request URI::" + request.getRequestURI(), null);
-			}
 			response.sendError(HttpServletResponse.SC_NOT_FOUND);
-			return;
-		}
-		// remove uri prefix and version from request if available
-		String staticRelPath;
-		if (pathInfo.indexOf(NOVERSION) != -1) {
+		} else if (pathInfo.indexOf(NOVERSION) != -1) {
 			// no version provided - only remove mapper
-			staticRelPath = pathInfo.substring(NOVERSION.length() + 1, pathInfo.length());
+			String staticRelPath = pathInfo.substring(NOVERSION.length() + 1, pathInfo.length());
+			String normalizedRelPath = ServletUtil.normalizePath(staticRelPath);
+			if (normalizedRelPath == null) {
+				response.sendError(HttpServletResponse.SC_NOT_FOUND);
+			} else if(normalizedRelPath.endsWith("transparent.gif")){
+				deliverStatic(request, response, pathInfo, normalizedRelPath, true);
+			} else {
+				deliverStatic(request, response, pathInfo, normalizedRelPath, false);
+			}
 		} else if (pathInfo.startsWith(STATIC_DIR_NAME)) {
-			staticRelPath = pathInfo.substring(STATIC_DIR_NAME.length() + 1, pathInfo.length());
+			String staticRelPath = pathInfo.substring(STATIC_DIR_NAME.length() + 1, pathInfo.length());
 			//customizing 
 			CustomStaticFolderManager folderManager = CoreSpringFactory.getImpl(CustomStaticFolderManager.class);
 			File file = new File(folderManager.getRootFile(), staticRelPath);
@@ -94,7 +106,6 @@ public class StaticServlet extends HttpServlet {
 			} else {
 				response.sendError(HttpServletResponse.SC_NOT_FOUND);
 			}
-			return;
 		} else {
 			// version provided - remove it
 			String version;
@@ -105,31 +116,37 @@ public class StaticServlet extends HttpServlet {
 			}	
 			int start = version.length() + 1;
 			int end = pathInfo.length();
+			
 			if(start <= end) {
-				staticRelPath = pathInfo.substring(start, end);
+				String staticRelPath = pathInfo.substring(start, end);
+				String normalizedRelPath = ServletUtil.normalizePath(staticRelPath);
+				if (normalizedRelPath == null) {
+					response.sendError(HttpServletResponse.SC_NOT_FOUND);
+				} else {
+					boolean expiration = !Settings.isDebuging();
+					deliverStatic(request, response, pathInfo, normalizedRelPath, expiration);
+				}
 			} else {
 				response.sendError(HttpServletResponse.SC_NOT_FOUND);
-				return;
-			}
-		}
-		
-		// remove any .. in the path
-		String normalizedRelPath = ServletUtil.normalizePath(staticRelPath);
-		if (normalizedRelPath == null) {
-			if (debug) {
-				log.debug("Path is null after noralizing for static request URI::" + request.getRequestURI(), null);
 			}
-			response.sendError(HttpServletResponse.SC_NOT_FOUND);
-			return;
-		}
+		}	
+	}
+	
+	private void deliverStatic(HttpServletRequest request, HttpServletResponse response,
+		String pathInfo, String normalizedRelPath, boolean expiration)
+	throws IOException {
+
+		boolean notFound = false;
 		// create the file from the path
 		String staticAbsPath;
 		if(Settings.isDebuging() && WebappHelper.getWebappSourcePath() != null) {
 			staticAbsPath = WebappHelper.getWebappSourcePath() + STATIC_DIR_NAME;
+			expiration &= false;
 		} else {
 			staticAbsPath = WebappHelper.getContextRealPath(STATIC_DIR_NAME);
+			expiration &= true;
 		}
-		
+
 		File staticFile = new File(staticAbsPath, normalizedRelPath);
 		if (!staticFile.exists()) {
 			// try loading themes from custom themes folder if configured 
@@ -138,13 +155,11 @@ public class StaticServlet extends HttpServlet {
 				String path = staticFile.getAbsolutePath();
 				path = path.substring(path.indexOf("/static/themes/") + 15);
 				staticFile = new File(customThemesDir, path);
+				expiration &= false;//themes can be update any time
 			}
 			
 			// only serve if file exists
 			if (!staticFile.exists()) {
-				if (debug) {
-					log.debug("File does not exist for URI::" + request.getRequestURI(), null);
-				}
 				// try fallback without version ID
 				String fallbackPath = pathInfo.substring(1, pathInfo.length());
 				fallbackPath = ServletUtil.normalizePath(fallbackPath);
@@ -155,8 +170,7 @@ public class StaticServlet extends HttpServlet {
 						String realPath = request.getServletContext().getRealPath("/static" + normalizedRelPath);
 						staticFile = new File(realPath);
 						if(!staticFile.exists()) {
-							response.sendError(HttpServletResponse.SC_NOT_FOUND);
-							return;
+							notFound = true;
 						}
 					}
 				}
@@ -164,12 +178,37 @@ public class StaticServlet extends HttpServlet {
 				log.warn("File exists but not mapped using version - use StaticMediaDispatch methods to create URL of static files! invalid URI::" + request.getRequestURI(), null);			
 			}
 		}
-
-		if (debug) {
-			log.debug("Serving resource URI::" + request.getRequestURI(), null);
-		}
 		
-    	MediaResource resource = new FileMediaResource(staticFile);
-    	ServletUtil.serveResource(request, response, resource);
+		if(notFound) {
+			response.sendError(HttpServletResponse.SC_NOT_FOUND);
+		} else {
+			deliverFile(request, response, staticFile, expiration);
+		}
+	}
+	
+	private void deliverFile(HttpServletRequest request, HttpServletResponse response, File file, boolean expiration) {
+		long lastModified = file.lastModified();
+		long ifModifiedSince = request.getDateHeader("If-Modified-Since");
+		if (ifModifiedSince >= (lastModified / 1000L) * 1000L) {
+			response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+		} else {
+			response.setDateHeader("Last-Modified", lastModified);
+			if(expiration) {
+				long now = System.currentTimeMillis();
+				//res being the HttpServletResponse of the request
+				response.addHeader("Cache-Control", "max-age=" + CACHE_DURATION_IN_SECOND);
+				response.setDateHeader("Expires", now + CACHE_DURATION_IN_MS);
+			}
+			
+			String mimeType = WebappHelper.getMimeType(file.getName());
+			response.setContentType(mimeType);
+			response.setContentLength((int)file.length());
+
+			try(InputStream in = new FileInputStream(file)) {
+				FileUtils.cpio(in, response.getOutputStream(), "static");
+			} catch(Exception ex) {
+				log.error("", ex);
+			}
+		}	
 	}
 }
diff --git a/src/main/java/org/olat/core/util/FileUtils.java b/src/main/java/org/olat/core/util/FileUtils.java
index 29f827cdfd1b1a0160a1b002c165991d04b47995..ddb6486496429f5e37c62baf158667ec1fc81411 100644
--- a/src/main/java/org/olat/core/util/FileUtils.java
+++ b/src/main/java/org/olat/core/util/FileUtils.java
@@ -940,16 +940,23 @@ public class FileUtils {
 
 		int c;
 		long tot = 0;
-		long s = System.nanoTime();
+		long s = 0;
+		boolean debug = log.isDebug();
+		if(debug) {
+			s = System.nanoTime();
+		}
+		
 		while ((c = in.read(buffer, 0, buffer.length)) != -1) {
     		out.write(buffer, 0, c);
     		tot += c;
 		}
 		
-		long tim = System.nanoTime() - s;
-		double dtim = tim == 0 ? 0.5 : tim; // avg of those less than 1 nanoseconds is taken as 0.5 nanoseconds
-		double bps = tot*1000*1000/dtim;
-		log.debug(String.format("cpio %,13d bytes %6.2f ms avg %6.1f Mbps %s%n", tot, dtim/1000/1000, bps/1024, wt));
+		if(debug) {
+			long tim = System.nanoTime() - s;
+			double dtim = tim == 0 ? 0.5 : tim; // avg of those less than 1 nanoseconds is taken as 0.5 nanoseconds
+			double bps = tot*1000*1000/dtim;
+			log.debug(String.format("cpio %,13d bytes %6.2f ms avg %6.1f Mbps %s%n", tot, dtim/1000/1000, bps/1024, wt));
+		}
 		return tot;
 	}
 	
diff --git a/src/main/java/org/olat/core/util/WebappHelper.java b/src/main/java/org/olat/core/util/WebappHelper.java
index f6bdb2e0395b3d67fecca0dda5b54966c3ddac83..5845c5d1592428050ebc848e46f8cad67ed5ee2a 100644
--- a/src/main/java/org/olat/core/util/WebappHelper.java
+++ b/src/main/java/org/olat/core/util/WebappHelper.java
@@ -114,7 +114,7 @@ public class WebappHelper implements Initializable, Destroyable, ServletContextA
 		servletContextPath = servletContext.getContextPath();
 		
 		try {
-			InputStream meta = servletContext.getResourceAsStream("META-INF/MANIFEST.MF");
+			InputStream meta = servletContext.getResourceAsStream("/META-INF/MANIFEST.MF");
 			if(meta != null) {
 				try {
 					Properties props = new Properties();
diff --git a/src/main/java/org/olat/core/util/vfs/VFSMediaResource.java b/src/main/java/org/olat/core/util/vfs/VFSMediaResource.java
index 57af586c4266ac1ed22a0567324fb5779b03dac5..c75c0f46022fb70d00afb25e1f4f46625e214176 100644
--- a/src/main/java/org/olat/core/util/vfs/VFSMediaResource.java
+++ b/src/main/java/org/olat/core/util/vfs/VFSMediaResource.java
@@ -51,6 +51,11 @@ public class VFSMediaResource implements MediaResource {
 		this.vfsLeaf = vfsLeaf;
 		this.filesInfoMBean = (FilesInfoMBean) CoreSpringFactory.getBean(FilesInfoMBean.class.getCanonicalName());
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return true;
+	}
 
 	public String getContentType() {
 		String mimeType;
diff --git a/src/main/java/org/olat/core/util/vfs/VFSRevisionMediaResource.java b/src/main/java/org/olat/core/util/vfs/VFSRevisionMediaResource.java
index b34b382ecab58e727f923670da27026348ae08c4..d16a67ce50dfe22727769ef2e6c12fc7635d8594 100644
--- a/src/main/java/org/olat/core/util/vfs/VFSRevisionMediaResource.java
+++ b/src/main/java/org/olat/core/util/vfs/VFSRevisionMediaResource.java
@@ -45,6 +45,11 @@ public class VFSRevisionMediaResource implements MediaResource {
 		this.revision = revision;
 		this.forceDownload = forceDownload;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return true;
+	}
 
 	public String getContentType() {
 		String mimeType = WebappHelper.getMimeType(revision.getName());
diff --git a/src/main/java/org/olat/course/archiver/ArchiveResource.java b/src/main/java/org/olat/course/archiver/ArchiveResource.java
index 5f0249100335ade32b3fab363fca3f6da20f92e7..997e84792e2405f0600954c2cd847c928929468b 100644
--- a/src/main/java/org/olat/course/archiver/ArchiveResource.java
+++ b/src/main/java/org/olat/course/archiver/ArchiveResource.java
@@ -60,6 +60,11 @@ public class ArchiveResource implements MediaResource {
 		this.courseNode = courseNode;
 		this.courseOres = courseOres;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	@Override
 	public String getContentType() {
diff --git a/src/main/java/org/olat/course/certificate/ui/CertificateMediaResource.java b/src/main/java/org/olat/course/certificate/ui/CertificateMediaResource.java
index aaddfea803efcfac2cef98c8fee9bec9f1435cc1..662ba44c8f50f54486ba2de2486b1fe9809a8964 100644
--- a/src/main/java/org/olat/course/certificate/ui/CertificateMediaResource.java
+++ b/src/main/java/org/olat/course/certificate/ui/CertificateMediaResource.java
@@ -42,6 +42,11 @@ public class CertificateMediaResource implements MediaResource {
 		this.filename = filename;
 	}
 	
+	@Override
+	public boolean acceptRanges() {
+		return true;
+	}
+	
 	@Override
 	public String getContentType() {
 		return "application/pdf";
diff --git a/src/main/java/org/olat/course/certificate/ui/CertificatesOptionsController.java b/src/main/java/org/olat/course/certificate/ui/CertificatesOptionsController.java
index 40ab3bd96737baee907762fe2a5b44cbbb55decb..5cc859a33161dca11cbdac051abf9919564d6398 100644
--- a/src/main/java/org/olat/course/certificate/ui/CertificatesOptionsController.java
+++ b/src/main/java/org/olat/course/certificate/ui/CertificatesOptionsController.java
@@ -438,6 +438,11 @@ public class CertificatesOptionsController extends FormBasicController {
 			this.preview = preview;
 		}
 		
+		@Override
+		public boolean acceptRanges() {
+			return true;
+		}
+		
 		@Override
 		public String getContentType() {
 			return "application/type";
diff --git a/src/main/java/org/olat/course/db/CourseDBMediaResource.java b/src/main/java/org/olat/course/db/CourseDBMediaResource.java
index 45e0c3fbda52841098de521bd91f56bd157fd9c1..695224cac7e4c12bbed1e971dba08b17564df826 100644
--- a/src/main/java/org/olat/course/db/CourseDBMediaResource.java
+++ b/src/main/java/org/olat/course/db/CourseDBMediaResource.java
@@ -47,6 +47,11 @@ public class CourseDBMediaResource implements MediaResource {
 		this.fileName = fileName;
 		this.content = content;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	@Override
 	public String getContentType() {
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxPDFExport.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxPDFExport.java
index 5d53b19a7a3c3fa111dc5240b70de180a66fbf2a..14720c95d5de1454642e3381481c05fe2150b954 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxPDFExport.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxPDFExport.java
@@ -115,6 +115,11 @@ public class CheckboxPDFExport extends PdfDocument implements MediaResource {
 	public void setAuthor(String author) {
 		this.author = author;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	@Override
 	public String getContentType() {
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckedPDFExport.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckedPDFExport.java
index 0a758ee64c041af3a24110b3d80b024af6dc8a87..7d52525dbf586b3cb2c82c2b8b9f550bb4edd7b8 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckedPDFExport.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckedPDFExport.java
@@ -79,10 +79,10 @@ public class CheckedPDFExport extends PdfDocument implements MediaResource {
 		institutionalUserIdentifierIndex = findPropertyIndex(UserConstants.INSTITUTIONALUSERIDENTIFIER, userPropertyHandlers);
 	}
 	
-	private int findPropertyIndex(String propertyName, List<UserPropertyHandler> userPropertyHandlers) {
+	private int findPropertyIndex(String propertyName, List<UserPropertyHandler> userPropHandlers) {
 		int i=0;
 		int index = -1;
-		for(UserPropertyHandler userPropertyHandler:userPropertyHandlers) {
+		for(UserPropertyHandler userPropertyHandler:userPropHandlers) {
 			if(propertyName.equals(userPropertyHandler.getName())) {
 				index = i;
 				numOfCols++;
@@ -92,9 +92,9 @@ public class CheckedPDFExport extends PdfDocument implements MediaResource {
 		return index;
 	}
 	
-	private String findHeader(String propertyName, List<UserPropertyHandler> userPropertyHandlers) {
+	private String findHeader(String propertyName, List<UserPropertyHandler> userPropHandlers) {
 		String header = null;
-		for(UserPropertyHandler userPropertyHandler:userPropertyHandlers) {
+		for(UserPropertyHandler userPropertyHandler:userPropHandlers) {
 			if(propertyName.equals(userPropertyHandler.getName())) {
 				header = translator.translate(userPropertyHandler.i18nColumnDescriptorLabelKey());
 			}
@@ -125,6 +125,11 @@ public class CheckedPDFExport extends PdfDocument implements MediaResource {
 	public void setAuthor(String author) {
 		this.author = author;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	@Override
 	public String getContentType() {
diff --git a/src/main/java/org/olat/fileresource/ZippedDirectoryMediaResource.java b/src/main/java/org/olat/fileresource/ZippedDirectoryMediaResource.java
index d0c2d9ed17beb2e91f89536303b128e034fc61bd..a53762462dd5ce20ad8e3bda7bc02411998b0d72 100644
--- a/src/main/java/org/olat/fileresource/ZippedDirectoryMediaResource.java
+++ b/src/main/java/org/olat/fileresource/ZippedDirectoryMediaResource.java
@@ -56,6 +56,11 @@ public class ZippedDirectoryMediaResource implements MediaResource {
 		this.unzipDir = unzipDir;
 	}
 
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
+
 	@Override
 	public String getContentType() {
 		return "application/zip";
diff --git a/src/main/java/org/olat/ims/qti/export/QTIWordExport.java b/src/main/java/org/olat/ims/qti/export/QTIWordExport.java
index b99e7acdfde9001280f3b59a25fbb23d6b3ad34f..521cbd1c149963fcb570f024e19b2b6ed389bcb8 100644
--- a/src/main/java/org/olat/ims/qti/export/QTIWordExport.java
+++ b/src/main/java/org/olat/ims/qti/export/QTIWordExport.java
@@ -83,6 +83,11 @@ public class QTIWordExport implements MediaResource {
 		this.mediaContainer = mediaContainer;
 	}
 	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
+	
 	@Override
 	public String getContentType() {
 		return "application/zip";
diff --git a/src/main/java/org/olat/ims/qti/qpool/QTIPoolWordExport.java b/src/main/java/org/olat/ims/qti/qpool/QTIPoolWordExport.java
index fdc91bb8ee24cd5c1c720c8a7b8f419933978b61..3f42674097ab12e8bb70e1828f2090550f85ed0a 100644
--- a/src/main/java/org/olat/ims/qti/qpool/QTIPoolWordExport.java
+++ b/src/main/java/org/olat/ims/qti/qpool/QTIPoolWordExport.java
@@ -76,6 +76,11 @@ class QTIPoolWordExport implements MediaResource {
 		this.qpoolFileStorage = qpoolFileStorage;
 	}
 	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
+	
 	@Override
 	public String getContentType() {
 		return "application/zip";
diff --git a/src/main/java/org/olat/ims/qti/statistics/QTIStatisticsResource.java b/src/main/java/org/olat/ims/qti/statistics/QTIStatisticsResource.java
index 3b084fabe53900416688d963caa9a4fdd127c3b7..97fd6b2fa3ee6b50e2074e8347258ec50217b906 100644
--- a/src/main/java/org/olat/ims/qti/statistics/QTIStatisticsResource.java
+++ b/src/main/java/org/olat/ims/qti/statistics/QTIStatisticsResource.java
@@ -73,6 +73,11 @@ public class QTIStatisticsResource implements MediaResource {
 		this.resourceResult = resourceResult;
 		this.locale = locale;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	@Override
 	public String getContentType() {
diff --git a/src/main/java/org/olat/login/oauth/OAuthResource.java b/src/main/java/org/olat/login/oauth/OAuthResource.java
index 84c788bed7210c05addcfac97e9abd597a9520a9..4797d2da987251c5b726493b5f8011b09a381e93 100644
--- a/src/main/java/org/olat/login/oauth/OAuthResource.java
+++ b/src/main/java/org/olat/login/oauth/OAuthResource.java
@@ -49,6 +49,11 @@ public class OAuthResource implements MediaResource {
 		this.provider = provider;
 		this.session = session;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	@Override
 	public String getContentType() {
diff --git a/src/main/java/org/olat/modules/qpool/manager/AbstractExportTestResource.java b/src/main/java/org/olat/modules/qpool/manager/AbstractExportTestResource.java
index e3a2c1d011c5936dd671decaab258ecd7b1378a3..f85475edfde70ea8a1f6d2e210f098f03ab6ccf9 100644
--- a/src/main/java/org/olat/modules/qpool/manager/AbstractExportTestResource.java
+++ b/src/main/java/org/olat/modules/qpool/manager/AbstractExportTestResource.java
@@ -50,6 +50,11 @@ public abstract class AbstractExportTestResource implements MediaResource {
 		this.encoding = encoding;
 		this.items = items;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	@Override
 	public String getContentType() {
diff --git a/src/main/java/org/olat/modules/qpool/manager/ExportQItemResource.java b/src/main/java/org/olat/modules/qpool/manager/ExportQItemResource.java
index 7df84f6c762f9f7c84883e25fca1650ed1bc414e..6244b09f88db4b53d065433c316dc3e252093b16 100644
--- a/src/main/java/org/olat/modules/qpool/manager/ExportQItemResource.java
+++ b/src/main/java/org/olat/modules/qpool/manager/ExportQItemResource.java
@@ -53,6 +53,11 @@ public class ExportQItemResource implements MediaResource {
 		this.encoding = encoding;
 		this.item = item;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	@Override
 	public String getContentType() {
diff --git a/src/main/java/org/olat/modules/qpool/manager/ExportQItemsZipResource.java b/src/main/java/org/olat/modules/qpool/manager/ExportQItemsZipResource.java
index df8c1cbc668ae6495f6ebebc3926841ec290edc1..6edd61b94e3f5473451ce829d2bb7f24f129fcd8 100644
--- a/src/main/java/org/olat/modules/qpool/manager/ExportQItemsZipResource.java
+++ b/src/main/java/org/olat/modules/qpool/manager/ExportQItemsZipResource.java
@@ -54,6 +54,11 @@ public class ExportQItemsZipResource implements MediaResource {
 		this.encoding = encoding;
 		this.items = items;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	@Override
 	public String getContentType() {
diff --git a/src/main/java/org/olat/modules/webFeed/SyndFeedMediaResource.java b/src/main/java/org/olat/modules/webFeed/SyndFeedMediaResource.java
index 8b6947eeab1b69f7941939884e21ebef415af4f6..08d9000d6c13b28cf16f5e7c30d662385302567b 100644
--- a/src/main/java/org/olat/modules/webFeed/SyndFeedMediaResource.java
+++ b/src/main/java/org/olat/modules/webFeed/SyndFeedMediaResource.java
@@ -58,6 +58,11 @@ public class SyndFeedMediaResource implements MediaResource {
 			// cannot convert feed to string or something
 		}
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return true;
+	}
 
 	/**
 	 * @see org.olat.core.gui.media.MediaResource#getContentType()
diff --git a/src/main/java/org/olat/modules/wiki/WikiToCPResource.java b/src/main/java/org/olat/modules/wiki/WikiToCPResource.java
index f832bf7652d63a8054971611a619004b224c959b..ce5293f67e13438648ce8ea7aab6eeda830f6f84 100644
--- a/src/main/java/org/olat/modules/wiki/WikiToCPResource.java
+++ b/src/main/java/org/olat/modules/wiki/WikiToCPResource.java
@@ -61,6 +61,11 @@ public class WikiToCPResource implements MediaResource {
 		this.translator = translator;
 		this.ores = ores;
 	}
+	
+	@Override
+	public boolean acceptRanges() {
+		return false;
+	}
 
 	@Override
 	public String getContentType() {