/*
* LinShare is an open source filesharing software, part of the LinPKI software
* suite, developed by Linagora.
*
* Copyright (C) 2015 LINAGORA
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version, provided you comply with the Additional Terms applicable for
* LinShare software by Linagora pursuant to Section 7 of the GNU Affero General
* Public License, subsections (b), (c), and (e), pursuant to which you must
* notably (i) retain the display of the “LinShare™” trademark/logo at the top
* of the interface window, the display of the “You are using the Open Source
* and free version of LinShare™, powered by Linagora © 2009–2015. Contribute to
* Linshare R&D by subscribing to an Enterprise offer!” infobox and in the
* e-mails sent with the Program, (ii) retain all hypertext links between
* LinShare and linshare.org, between linagora.com and Linagora, and (iii)
* refrain from infringing Linagora intellectual property rights over its
* trademarks and commercial brands. Other Additional Terms apply, see
* <http://www.linagora.com/licenses/> for more details.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License and
* its applicable Additional Terms for LinShare along with this program. If not,
* see <http://www.gnu.org/licenses/> for the GNU Affero General Public License
* version 3 and <http://www.linagora.com/licenses/> for the Additional Terms
* applicable to LinShare software.
*/
package org.linagora.linshare.webservice.utils;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.linagora.linshare.core.exception.BusinessErrorCode;
import org.linagora.linshare.core.exception.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DocumentStreamReponseBuilder {
private static Logger logger = LoggerFactory.getLogger(DocumentStreamReponseBuilder.class);
public static ResponseBuilder getDocumentResponseBuilder(InputStream inputStream, String fileName, String mimeType) {
return getDocumentResponseBuilder(inputStream, fileName, mimeType, null);
}
public static ResponseBuilder getThumbnailResponseBuilder(InputStream inputStream, String fileName, boolean base64) {
ResponseBuilder response = null;
if (base64) {
response = getDocumentResponseBuilderBase64(inputStream, fileName,
"image/png", null);
} else {
response = getDocumentResponseBuilder(inputStream, fileName,
"image/png", null);
}
return response;
}
public static ResponseBuilder getDocumentResponseBuilder(
InputStream inputStream, String fileName, String mimeType,
Long fileSize) {
ResponseBuilder response = Response.ok(inputStream);
setHeaderToResponse(response, fileName, mimeType, fileSize);
return response;
}
public static ResponseBuilder getDocumentResponseBuilderBase64(
InputStream inputStream, String fileName, String mimeType,
Long fileSize) {
ResponseBuilder response = null;
byte[] byteArray = null;
try {
byteArray = IOUtils.toByteArray(inputStream);
response = Response.ok(Base64.encodeBase64(byteArray));
} catch (IOException e) {
logger.error(e.getMessage(), e);
throw new BusinessException(
BusinessErrorCode.BASE64_INPUTSTREAM_ENCODE_ERROR,
e.getMessage());
}
setHeaderToResponse(response, fileName, mimeType, fileSize);
return response;
}
private static void setHeaderToResponse(ResponseBuilder response,
String fileName, String mimeType, Long fileSize) {
if (fileName != null)
response.header("Content-Disposition", getContentDispositionHeader(fileName));
response.header("Content-Type", mimeType);
response.header("Content-Transfer-Encoding", "binary");
if (fileSize != null)
response.header("Content-Length", fileSize);
// BUG WITH IE WHEN PRAGMA IS NO-CACHE solution is:
// The proper solution to IE cache issues is to declare the attachment
// as "Pragma: private"
// and "Cache-Control: private, must-revalidate" in the HTTP Response.
// This allows MS-IE to save the content as a temporary file in its
// local cache,
// but in not general public cache servers, before handing it off the
// plugin, e.g. Adobe Acrobat, to handle it.
// Pragma is a HTTP 1.0 directive that was retained in HTTP 1.1 for
// backward compatibility.
// no-cache prevent caching in proxy
response.header("Pragma", "private");
// cache-control: private. It instructs proxies in the path not to cache
// the page. But it permits browsers to cache the page.
// must-revalidate means the browser must revalidate the page against
// the server before serving it from cache
// post-check Defines an interval in seconds after which an entity must
// be checked for freshness.
// The check may happen after the user is shown the resource but ensures
// that on the next roundtrip
// the cached copy will be up-to-date
// pre-check Defines an interval in seconds after
// which an entity must be checked for freshness prior to showing the
// user the resource.
response.header("Cache-Control",
"private,must-revalidate, post-check=0, pre-check=0");
}
private static String getContentDispositionHeader(String fileName) {
String encodeFileName = null;
try {
URI uri = new URI(null, null, fileName, null);
encodeFileName = uri.toASCIIString();
} catch (URISyntaxException e) {
e.printStackTrace();
}
StringBuilder sb = new StringBuilder();
sb.append("attachment; ");
// Adding filename using the old way for old browser compatibility
sb.append("filename=\"" + fileName + "\"; ");
// Adding UTF-8 encoded filename. If the browser do not support this
// parameter, it will use the old way.
if (encodeFileName != null) {
sb.append("filename*= UTF-8''" + encodeFileName);
}
return sb.toString();
}
}