001
014
015 package com.liferay.portal.kernel.portlet;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
020 import com.liferay.portal.kernel.servlet.HttpHeaders;
021 import com.liferay.portal.kernel.util.ArrayUtil;
022 import com.liferay.portal.kernel.util.FileUtil;
023 import com.liferay.portal.kernel.util.GetterUtil;
024 import com.liferay.portal.kernel.util.HttpUtil;
025 import com.liferay.portal.kernel.util.PortalUtil;
026 import com.liferay.portal.kernel.util.PropsUtil;
027 import com.liferay.portal.kernel.util.StreamUtil;
028 import com.liferay.portal.kernel.util.StringBundler;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.kernel.util.StringUtil;
031 import com.liferay.portal.kernel.util.Validator;
032
033 import java.io.File;
034 import java.io.FileInputStream;
035 import java.io.IOException;
036 import java.io.InputStream;
037 import java.io.OutputStream;
038
039 import java.nio.channels.Channels;
040 import java.nio.channels.FileChannel;
041
042 import javax.portlet.MimeResponse;
043 import javax.portlet.PortletRequest;
044 import javax.portlet.ResourceResponse;
045
046 import javax.servlet.http.HttpServletRequest;
047
048
051 public class PortletResponseUtil {
052
053 public static void sendFile(
054 PortletRequest portletRequest, MimeResponse mimeResponse,
055 String fileName, byte[] bytes)
056 throws IOException {
057
058 sendFile(portletRequest, mimeResponse, fileName, bytes, null);
059 }
060
061 public static void sendFile(
062 PortletRequest portletRequest, MimeResponse mimeResponse,
063 String fileName, byte[] bytes, String contentType)
064 throws IOException {
065
066 sendFile(
067 portletRequest, mimeResponse, fileName, bytes, contentType, null);
068 }
069
070 public static void sendFile(
071 PortletRequest portletRequest, MimeResponse mimeResponse,
072 String fileName, byte[] bytes, String contentType,
073 String contentDispositionType)
074 throws IOException {
075
076 setHeaders(
077 portletRequest, mimeResponse, fileName, contentType,
078 contentDispositionType);
079
080 write(mimeResponse, bytes);
081 }
082
083 public static void sendFile(
084 PortletRequest portletRequest, MimeResponse mimeResponse,
085 String fileName, InputStream inputStream)
086 throws IOException {
087
088 sendFile(portletRequest, mimeResponse, fileName, inputStream, null);
089 }
090
091 public static void sendFile(
092 PortletRequest portletRequest, MimeResponse mimeResponse,
093 String fileName, InputStream inputStream, int contentLength,
094 String contentType)
095 throws IOException {
096
097 sendFile(
098 portletRequest, mimeResponse, fileName, inputStream, contentLength,
099 contentType, null);
100 }
101
102 public static void sendFile(
103 PortletRequest portletRequest, MimeResponse mimeResponse,
104 String fileName, InputStream inputStream, int contentLength,
105 String contentType, String contentDispositionType)
106 throws IOException {
107
108 setHeaders(
109 portletRequest, mimeResponse, fileName, contentType,
110 contentDispositionType);
111
112 write(mimeResponse, inputStream, contentLength);
113 }
114
115 public static void sendFile(
116 PortletRequest portletRequest, MimeResponse mimeResponse,
117 String fileName, InputStream inputStream, String contentType)
118 throws IOException {
119
120 sendFile(
121 portletRequest, mimeResponse, fileName, inputStream, 0,
122 contentType);
123 }
124
125 public static void write(MimeResponse mimeResponse, byte[] bytes)
126 throws IOException {
127
128 write(mimeResponse, bytes, 0, 0);
129 }
130
131 public static void write(
132 MimeResponse mimeResponse, byte[] bytes, int offset,
133 int contentLength)
134 throws IOException {
135
136
137
138 if (!mimeResponse.isCommitted()) {
139
140
141
142 if (contentLength == 0) {
143 contentLength = bytes.length;
144 }
145
146 if (mimeResponse instanceof ResourceResponse) {
147 ResourceResponse resourceResponse =
148 (ResourceResponse)mimeResponse;
149
150 resourceResponse.setContentLength(contentLength);
151 }
152
153 OutputStream outputStream = mimeResponse.getPortletOutputStream();
154
155 outputStream.write(bytes, offset, contentLength);
156 }
157 }
158
159 public static void write(MimeResponse mimeResponse, byte[][] bytesArray)
160 throws IOException {
161
162
163
164 if (mimeResponse.isCommitted()) {
165 return;
166 }
167
168
169
170 long contentLength = 0;
171
172 for (byte[] bytes : bytesArray) {
173 contentLength += bytes.length;
174 }
175
176 if (mimeResponse instanceof ResourceResponse) {
177 ResourceResponse resourceResponse = (ResourceResponse)mimeResponse;
178
179 setContentLength(resourceResponse, contentLength);
180 }
181
182 OutputStream outputStream = mimeResponse.getPortletOutputStream();
183
184 for (byte[] bytes : bytesArray) {
185 outputStream.write(bytes);
186 }
187 }
188
189 public static void write(MimeResponse mimeResponse, File file)
190 throws IOException {
191
192 FileInputStream fileInputStream = new FileInputStream(file);
193
194 try (FileChannel fileChannel = fileInputStream.getChannel()) {
195 long contentLength = fileChannel.size();
196
197 if (mimeResponse instanceof ResourceResponse) {
198 ResourceResponse resourceResponse =
199 (ResourceResponse)mimeResponse;
200
201 setContentLength(resourceResponse, contentLength);
202 }
203
204 fileChannel.transferTo(
205 0, contentLength,
206 Channels.newChannel(mimeResponse.getPortletOutputStream()));
207 }
208 }
209
210 public static void write(MimeResponse mimeResponse, InputStream inputStream)
211 throws IOException {
212
213 write(mimeResponse, inputStream, 0);
214 }
215
216 public static void write(
217 MimeResponse mimeResponse, InputStream inputStream,
218 int contentLength)
219 throws IOException {
220
221 if (mimeResponse.isCommitted()) {
222 StreamUtil.cleanUp(inputStream);
223
224 return;
225 }
226
227 if (contentLength > 0) {
228 if (mimeResponse instanceof ResourceResponse) {
229 ResourceResponse resourceResponse =
230 (ResourceResponse)mimeResponse;
231
232 resourceResponse.setContentLength(contentLength);
233 }
234 }
235
236 StreamUtil.transfer(inputStream, mimeResponse.getPortletOutputStream());
237 }
238
239 public static void write(MimeResponse mimeResponse, String s)
240 throws IOException {
241
242 write(mimeResponse, s.getBytes(StringPool.UTF8));
243 }
244
245 protected static void setContentLength(
246 ResourceResponse response, long contentLength) {
247
248 response.setProperty(
249 HttpHeaders.CONTENT_LENGTH, String.valueOf(contentLength));
250 }
251
252 protected static void setHeaders(
253 PortletRequest portletRequest, MimeResponse mimeResponse,
254 String fileName, String contentType, String contentDispositionType) {
255
256 if (_log.isDebugEnabled()) {
257 _log.debug("Sending file of type " + contentType);
258 }
259
260
261
262 if (Validator.isNotNull(contentType)) {
263 mimeResponse.setContentType(contentType);
264 }
265
266 mimeResponse.setProperty(
267 HttpHeaders.CACHE_CONTROL, HttpHeaders.CACHE_CONTROL_PRIVATE_VALUE);
268
269 if (Validator.isNull(fileName)) {
270 return;
271 }
272
273 String contentDispositionFileName = "filename=\"" + fileName + "\"";
274
275
276
277
278 boolean ascii = true;
279
280 for (int i = 0; i < fileName.length(); i++) {
281 if (!Validator.isAscii(fileName.charAt(i))) {
282 ascii = false;
283
284 break;
285 }
286 }
287
288 try {
289 if (!ascii) {
290 String encodedFileName = HttpUtil.encodeURL(fileName, true);
291
292 HttpServletRequest request = PortalUtil.getHttpServletRequest(
293 portletRequest);
294
295 if (BrowserSnifferUtil.isIe(request)) {
296 contentDispositionFileName =
297 "filename=\"" + encodedFileName + "\"";
298 }
299 else {
300 contentDispositionFileName =
301 "filename*=UTF-8''" + encodedFileName;
302 }
303 }
304 }
305 catch (Exception e) {
306 if (_log.isWarnEnabled()) {
307 _log.warn(e);
308 }
309 }
310
311 if (Validator.isNull(contentDispositionType)) {
312 String extension = GetterUtil.getString(
313 FileUtil.getExtension(fileName));
314
315 extension = StringUtil.toLowerCase(extension);
316
317 String[] mimeTypesContentDispositionInline = null;
318
319 try {
320 mimeTypesContentDispositionInline = PropsUtil.getArray(
321 "mime.types.content.disposition.inline");
322 }
323 catch (Exception e) {
324 mimeTypesContentDispositionInline = new String[0];
325 }
326
327 if (ArrayUtil.contains(
328 mimeTypesContentDispositionInline, extension)) {
329
330 contentDispositionType = HttpHeaders.CONTENT_DISPOSITION_INLINE;
331 }
332 else {
333 contentDispositionType =
334 HttpHeaders.CONTENT_DISPOSITION_ATTACHMENT;
335 }
336 }
337
338 StringBundler sb = new StringBundler(4);
339
340 sb.append(contentDispositionType);
341 sb.append(StringPool.SEMICOLON);
342 sb.append(StringPool.SPACE);
343 sb.append(contentDispositionFileName);
344
345 mimeResponse.setProperty(
346 HttpHeaders.CONTENT_DISPOSITION, sb.toString());
347 }
348
349 private static final Log _log = LogFactoryUtil.getLog(
350 PortletResponseUtil.class);
351
352 }