From c33c0952731f69bb77cc7b895a62e074b936ec39 Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Fri, 20 Feb 2015 10:56:01 +0100 Subject: [PATCH] OO-1446: set expiration date for versioned static file ( and transparent.gif ), refactor Workbook media resource to work without temporary files, add flag to media resources to accept or not ranges, add patch for Tomcat 8 ( thanks D. Haag ) --- .../servlets/StaticsLegacyDispatcher.java | 5 + .../modules/bc/commands/CmdDownloadZip.java | 5 + .../gui/media/ClasspathMediaResource.java | 4 + ...CleanupAfterDeliveryFileMediaResource.java | 5 + .../core/gui/media/DefaultMediaResource.java | 22 ++- .../core/gui/media/ExcelMediaResource.java | 22 +-- .../core/gui/media/FileMediaResource.java | 15 +- .../gui/media/ForbiddenMediaResource.java | 1 + .../gui/media/HttpRequestMediaResource.java | 5 + .../core/gui/media/JSONMediaResource.java | 6 - .../olat/core/gui/media/MediaResource.java | 2 + .../core/gui/media/MediaResourceFactory.java | 134 ------------------ .../gui/media/MimedFileMediaResource.java | 61 -------- .../core/gui/media/NotFoundMediaResource.java | 2 +- .../media/NothingChangedMediaResource.java | 1 + .../core/gui/media/RedirectMediaResource.java | 5 + .../org/olat/core/gui/media/ServletUtil.java | 2 +- .../core/gui/media/StreamedMediaResource.java | 5 + .../core/gui/media/StringMediaResource.java | 6 + .../core/gui/media/WorkbookMediaResource.java | 61 +++++--- .../org/olat/core/servlets/StaticServlet.java | 113 ++++++++++----- .../java/org/olat/core/util/FileUtils.java | 17 ++- .../java/org/olat/core/util/WebappHelper.java | 2 +- .../olat/core/util/vfs/VFSMediaResource.java | 5 + .../util/vfs/VFSRevisionMediaResource.java | 5 + .../olat/course/archiver/ArchiveResource.java | 5 + .../ui/CertificateMediaResource.java | 5 + .../ui/CertificatesOptionsController.java | 5 + .../olat/course/db/CourseDBMediaResource.java | 5 + .../course/nodes/cl/ui/CheckboxPDFExport.java | 5 + .../course/nodes/cl/ui/CheckedPDFExport.java | 13 +- .../ZippedDirectoryMediaResource.java | 5 + .../olat/ims/qti/export/QTIWordExport.java | 5 + .../olat/ims/qti/qpool/QTIPoolWordExport.java | 5 + .../qti/statistics/QTIStatisticsResource.java | 5 + .../org/olat/login/oauth/OAuthResource.java | 5 + .../manager/AbstractExportTestResource.java | 5 + .../qpool/manager/ExportQItemResource.java | 5 + .../manager/ExportQItemsZipResource.java | 5 + .../webFeed/SyndFeedMediaResource.java | 5 + .../olat/modules/wiki/WikiToCPResource.java | 5 + 41 files changed, 297 insertions(+), 302 deletions(-) delete mode 100644 src/main/java/org/olat/core/gui/media/MediaResourceFactory.java delete mode 100644 src/main/java/org/olat/core/gui/media/MimedFileMediaResource.java diff --git a/src/main/java/org/olat/commons/servlets/StaticsLegacyDispatcher.java b/src/main/java/org/olat/commons/servlets/StaticsLegacyDispatcher.java index cbabe7b68fd..04130222005 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 56a5ff86109..9f5f1a8576b 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 0d623906e9f..fd54f5bf3d6 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 184a5bf5bda..ba9ed00f483 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 2dbfa35ecf9..10c608f25c6 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 13283389d6b..f7c2d6aa707 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 4ffb9fc521e..894b5007c07 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 f4b033b62c4..6a7be0dca0f 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 d3d78805767..dbe8dc1d061 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 37b8a02f4fc..f25be8144bc 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 f1fa323c66a..1b265b7fdc0 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 1d6b477b35b..00000000000 --- 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 60cbfd49022..00000000000 --- 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 93ace1f98d8..340bd49a6c0 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 c1acaf4f666..a57ccb3eb6f 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 79c642414c2..35850b02a3b 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 3aea7ffdbb9..68fbf52b684 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 174e07eedd7..d2df2f1aef3 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 9b7e1fcc8ae..67f6f3eab5d 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 c64f43a806f..9a48e9ae5cc 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 4b72e70d8e2..8e10dacbe4a 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 29f827cdfd1..ddb64864964 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 f6bdb2e0395..5845c5d1592 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 57af586c426..c75c0f46022 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 b34b382ecab..d16a67ce50d 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 5f024910033..997e84792e2 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 aaddfea803e..662ba44c8f5 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 40ab3bd9673..5cc859a3316 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 45e0c3fbda5..695224cac7e 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 5d53b19a7a3..14720c95d5d 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 0a758ee64c0..7d52525dbf5 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 d0c2d9ed17b..a53762462dd 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 b99e7acdfde..521cbd1c149 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 fdc91bb8ee2..3f42674097a 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 3b084fabe53..97fd6b2fa3e 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 84c788bed72..4797d2da987 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 e3a2c1d011c..f85475edfde 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 7df84f6c762..6244b09f88d 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 df8c1cbc668..6edd61b94e3 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 8b6947eeab1..08d9000d6c1 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 f832bf7652d..ce5293f67e1 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() { -- GitLab