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