001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Florent Guillaume
016 */
017package org.nuxeo.ecm.core.io.download;
018
019import java.io.IOException;
020import java.io.OutputStream;
021import java.io.Serializable;
022import java.util.Map;
023import java.util.function.Consumer;
024import java.util.function.Supplier;
025
026import javax.servlet.http.HttpServletRequest;
027import javax.servlet.http.HttpServletResponse;
028
029import org.nuxeo.ecm.core.api.Blob;
030import org.nuxeo.ecm.core.api.DocumentModel;
031
032/**
033 * This service allows the download of blobs to a HTTP response.
034 *
035 * @since 7.3
036 */
037public interface DownloadService {
038
039    String EVENT_NAME = "download";
040
041    String NXFILE = "nxfile";
042
043    String NXDOWNLOADINFO = "nxdownloadinfo";
044
045    String NXBIGBLOB = "nxbigblob";
046
047    String NXBIGZIPFILE = "nxbigzipfile";
048
049    String BLOBHOLDER_PREFIX = "blobholder:";
050
051    String BLOBHOLDER_0 = "blobholder:0";
052
053    public static class ByteRange {
054
055        private final long start;
056
057        private final long end;
058
059        public ByteRange(long start, long end) {
060            this.start = start;
061            this.end = end;
062        }
063
064        public long getStart() {
065            return start;
066        }
067
068        public long getEnd() {
069            return end;
070        }
071
072        public long getLength() {
073            return end - start + 1;
074        }
075    }
076
077    /**
078     * Gets the URL to use to download the blob at the given xpath in the given document.
079     * <p>
080     * The URL is relative to the Nuxeo Web Application context.
081     * <p>
082     * Returns something like {@code nxbigfile/reponame/docuuid/blobholder:0/foo.jpg}
083     *
084     * @param doc the document
085     * @param xpath the blob's xpath or blobholder index, or {@code null} for default
086     * @param filename the blob's filename, or {@code null} for default
087     * @return the download URL
088     */
089    String getDownloadUrl(DocumentModel doc, String xpath, String filename);
090
091    /**
092     * Gets the URL to use to download the blob at the given xpath in the given document.
093     * <p>
094     * The URL is relative to the Nuxeo Web Application context.
095     * <p>
096     * Returns something like {@code nxbigfile/reponame/docuuid/blobholder:0/foo.jpg}
097     *
098     * @param repositoryName the document repository
099     * @param docId the document id
100     * @param xpath the blob's xpath or blobholder index, or {@code null} for default
101     * @param filename the blob's filename, or {@code null} for default
102     * @return the download URL
103     */
104    String getDownloadUrl(String repositoryName, String docId, String xpath, String filename);
105
106    /**
107     * Triggers a blob download.
108     *
109     * @param doc the document, if available
110     * @param xpath the blob's xpath or blobholder index, if available
111     * @param blob the blob, if already fetched
112     * @param filename the filename to use
113     * @param reason the download reason
114     */
115    void downloadBlob(HttpServletRequest request, HttpServletResponse response, DocumentModel doc, String xpath,
116            Blob blob, String filename, String reason) throws IOException;
117
118    /**
119     * Triggers a blob download.
120     *
121     * @param doc the document, if available
122     * @param xpath the blob's xpath or blobholder index, if available
123     * @param blob the blob, if already fetched
124     * @param filename the filename to use
125     * @param reason the download reason
126     * @param extendedInfos an optional map of extended informations to log
127     */
128    void downloadBlob(HttpServletRequest request, HttpServletResponse response, DocumentModel doc, String xpath,
129            Blob blob, String filename, String reason, Map<String, Serializable> extendedInfos) throws IOException;
130
131    /**
132     * Triggers a blob download. The actual byte transfer is done through a {@link DownloadExecutor}.
133     *
134     * @param doc the document, if available
135     * @param xpath the blob's xpath or blobholder index, if available
136     * @param blob the blob, if already fetched
137     * @param filename the filename to use
138     * @param reason the download reason
139     * @param extendedInfos an optional map of extended informations to log
140     * @param inline if not null, force the inline flag for content-disposition
141     * @param blobTransferer the transferer of the actual blob
142     * @since 7.10
143     */
144    void downloadBlob(HttpServletRequest request, HttpServletResponse response, DocumentModel doc, String xpath,
145            Blob blob, String filename, String reason, Map<String, Serializable> extendedInfos, Boolean inline,
146            Consumer<ByteRange> blobTransferer) throws IOException;
147
148    /**
149     * Copies the blob stream at the given byte range into the supplied {@link OutputStream}.
150     *
151     * @param blob the blob
152     * @param byteRange the byte range
153     * @param outputStreamSupplier the {@link OutputStream} supplier
154     * @since 7.10
155     */
156    void transferBlobWithByteRange(Blob blob, ByteRange byteRange, Supplier<OutputStream> outputStreamSupplier);
157
158    /**
159     * Logs a download.
160     *
161     * @param doc the doc for which this download occurs, if available
162     * @param blobXPath the blob's xpath or blobholder index, if available
163     * @param filename the filename
164     * @param reason the download reason
165     * @param extendedInfos an optional map of extended informations to log
166     */
167    void logDownload(DocumentModel doc, String blobXPath, String filename, String reason,
168            Map<String, Serializable> extendedInfos);
169
170    /**
171     * Finds a document's blob given an xpath or blobholder index
172     *
173     * @param doc the document
174     * @param xpath the xpath or blobholder index
175     * @return the blob, or {@code null} if not found
176     */
177    Blob resolveBlob(DocumentModel doc, String xpath);
178
179    /**
180     * Checks whether the download of the blob is allowed.
181     *
182     * @param doc the doc for which this download occurs, if available
183     * @param blobXPath the blob's xpath or blobholder index, if available
184     * @param blob the blob
185     * @param reason the download reason
186     * @param extendedInfos an optional map of extended informations to log
187     * @return {@code true} if download is allowed
188     * @since 7.10
189     */
190    boolean checkPermission(DocumentModel doc, String xpath, Blob blob, String reason,
191            Map<String, Serializable> extendedInfos);
192
193}