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.PropsUtil;
026 import com.liferay.portal.kernel.util.StreamUtil;
027 import com.liferay.portal.kernel.util.StringBundler;
028 import com.liferay.portal.kernel.util.StringPool;
029 import com.liferay.portal.kernel.util.StringUtil;
030 import com.liferay.portal.kernel.util.Validator;
031 import com.liferay.portal.util.PortalUtil;
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
056 @Deprecated
057 public static void sendFile(
058 MimeResponse mimeResponse, String fileName, byte[] bytes)
059 throws IOException {
060
061 sendFile(null, mimeResponse, fileName, bytes);
062 }
063
064
067 @Deprecated
068 public static void sendFile(
069 MimeResponse mimeResponse, String fileName, byte[] bytes,
070 String contentType)
071 throws IOException {
072
073 sendFile(null, mimeResponse, fileName, bytes, contentType);
074 }
075
076
079 @Deprecated
080 public static void sendFile(
081 MimeResponse mimeResponse, String fileName, InputStream inputStream)
082 throws IOException {
083
084 sendFile(null, mimeResponse, fileName, inputStream);
085 }
086
087
090 @Deprecated
091 public static void sendFile(
092 MimeResponse mimeResponse, String fileName, InputStream inputStream,
093 int contentLength, String contentType)
094 throws IOException {
095
096 sendFile(
097 null, mimeResponse, fileName, inputStream, contentLength,
098 contentType);
099 }
100
101
104 @Deprecated
105 public static void sendFile(
106 MimeResponse mimeResponse, String fileName, InputStream inputStream,
107 String contentType)
108 throws IOException {
109
110 sendFile(null, mimeResponse, fileName, inputStream, contentType);
111 }
112
113 public static void sendFile(
114 PortletRequest portletRequest, MimeResponse mimeResponse,
115 String fileName, byte[] bytes)
116 throws IOException {
117
118 sendFile(portletRequest, mimeResponse, fileName, bytes, null);
119 }
120
121 public static void sendFile(
122 PortletRequest portletRequest, MimeResponse mimeResponse,
123 String fileName, byte[] bytes, String contentType)
124 throws IOException {
125
126 sendFile(
127 portletRequest, mimeResponse, fileName, bytes, contentType, null);
128 }
129
130 public static void sendFile(
131 PortletRequest portletRequest, MimeResponse mimeResponse,
132 String fileName, byte[] bytes, String contentType,
133 String contentDispositionType)
134 throws IOException {
135
136 setHeaders(
137 portletRequest, mimeResponse, fileName, contentType,
138 contentDispositionType);
139
140 write(mimeResponse, bytes);
141 }
142
143 public static void sendFile(
144 PortletRequest portletRequest, MimeResponse mimeResponse,
145 String fileName, InputStream inputStream)
146 throws IOException {
147
148 sendFile(portletRequest, mimeResponse, fileName, inputStream, null);
149 }
150
151 public static void sendFile(
152 PortletRequest portletRequest, MimeResponse mimeResponse,
153 String fileName, InputStream inputStream, int contentLength,
154 String contentType)
155 throws IOException {
156
157 sendFile(
158 portletRequest, mimeResponse, fileName, inputStream, contentLength,
159 contentType, null);
160 }
161
162 public static void sendFile(
163 PortletRequest portletRequest, MimeResponse mimeResponse,
164 String fileName, InputStream inputStream, int contentLength,
165 String contentType, String contentDispositionType)
166 throws IOException {
167
168 setHeaders(
169 portletRequest, mimeResponse, fileName, contentType,
170 contentDispositionType);
171
172 write(mimeResponse, inputStream, contentLength);
173 }
174
175 public static void sendFile(
176 PortletRequest portletRequest, MimeResponse mimeResponse,
177 String fileName, InputStream inputStream, String contentType)
178 throws IOException {
179
180 sendFile(
181 portletRequest, mimeResponse, fileName, inputStream, 0,
182 contentType);
183 }
184
185 public static void write(MimeResponse mimeResponse, byte[] bytes)
186 throws IOException {
187
188 write(mimeResponse, bytes, 0, 0);
189 }
190
191 public static void write(
192 MimeResponse mimeResponse, byte[] bytes, int offset,
193 int contentLength)
194 throws IOException {
195
196
197
198 if (!mimeResponse.isCommitted()) {
199
200
201
202 if (contentLength == 0) {
203 contentLength = bytes.length;
204 }
205
206 if (mimeResponse instanceof ResourceResponse) {
207 ResourceResponse resourceResponse =
208 (ResourceResponse)mimeResponse;
209
210 resourceResponse.setContentLength(contentLength);
211 }
212
213 OutputStream outputStream = mimeResponse.getPortletOutputStream();
214
215 outputStream.write(bytes, offset, contentLength);
216 }
217 }
218
219 public static void write(MimeResponse mimeResponse, byte[][] bytesArray)
220 throws IOException {
221
222
223
224 if (mimeResponse.isCommitted()) {
225 return;
226 }
227
228
229
230 long contentLength = 0;
231
232 for (byte[] bytes : bytesArray) {
233 contentLength += bytes.length;
234 }
235
236 if (mimeResponse instanceof ResourceResponse) {
237 ResourceResponse resourceResponse = (ResourceResponse)mimeResponse;
238
239 setContentLength(resourceResponse, contentLength);
240 }
241
242 OutputStream outputStream = mimeResponse.getPortletOutputStream();
243
244 for (byte[] bytes : bytesArray) {
245 outputStream.write(bytes);
246 }
247 }
248
249 public static void write(MimeResponse mimeResponse, File file)
250 throws IOException {
251
252 FileInputStream fileInputStream = new FileInputStream(file);
253
254 try (FileChannel fileChannel = fileInputStream.getChannel()) {
255 long contentLength = fileChannel.size();
256
257 if (mimeResponse instanceof ResourceResponse) {
258 ResourceResponse resourceResponse =
259 (ResourceResponse)mimeResponse;
260
261 setContentLength(resourceResponse, contentLength);
262 }
263
264 fileChannel.transferTo(
265 0, contentLength,
266 Channels.newChannel(mimeResponse.getPortletOutputStream()));
267 }
268 }
269
270 public static void write(MimeResponse mimeResponse, InputStream inputStream)
271 throws IOException {
272
273 write(mimeResponse, inputStream, 0);
274 }
275
276 public static void write(
277 MimeResponse mimeResponse, InputStream inputStream,
278 int contentLength)
279 throws IOException {
280
281 if (mimeResponse.isCommitted()) {
282 StreamUtil.cleanUp(inputStream);
283
284 return;
285 }
286
287 if (contentLength > 0) {
288 if (mimeResponse instanceof ResourceResponse) {
289 ResourceResponse resourceResponse =
290 (ResourceResponse)mimeResponse;
291
292 resourceResponse.setContentLength(contentLength);
293 }
294 }
295
296 StreamUtil.transfer(inputStream, mimeResponse.getPortletOutputStream());
297 }
298
299 public static void write(MimeResponse mimeResponse, String s)
300 throws IOException {
301
302 write(mimeResponse, s.getBytes(StringPool.UTF8));
303 }
304
305 protected static void setContentLength(
306 ResourceResponse response, long contentLength) {
307
308 response.setProperty(
309 HttpHeaders.CONTENT_LENGTH, String.valueOf(contentLength));
310 }
311
312 protected static void setHeaders(
313 PortletRequest portletRequest, MimeResponse mimeResponse,
314 String fileName, String contentType, String contentDispositionType) {
315
316 if (_log.isDebugEnabled()) {
317 _log.debug("Sending file of type " + contentType);
318 }
319
320
321
322 if (Validator.isNotNull(contentType)) {
323 mimeResponse.setContentType(contentType);
324 }
325
326 mimeResponse.setProperty(
327 HttpHeaders.CACHE_CONTROL, HttpHeaders.CACHE_CONTROL_PRIVATE_VALUE);
328
329 if (Validator.isNull(fileName)) {
330 return;
331 }
332
333 String contentDispositionFileName = "filename=\"" + fileName + "\"";
334
335
336
337
338 boolean ascii = true;
339
340 for (int i = 0; i < fileName.length(); i++) {
341 if (!Validator.isAscii(fileName.charAt(i))) {
342 ascii = false;
343
344 break;
345 }
346 }
347
348 try {
349 if (!ascii) {
350 String encodedFileName = HttpUtil.encodeURL(fileName, true);
351
352 HttpServletRequest request = PortalUtil.getHttpServletRequest(
353 portletRequest);
354
355 if (BrowserSnifferUtil.isIe(request)) {
356 contentDispositionFileName =
357 "filename=\"" + encodedFileName + "\"";
358 }
359 else {
360 contentDispositionFileName =
361 "filename*=UTF-8''" + encodedFileName;
362 }
363 }
364 }
365 catch (Exception e) {
366 if (_log.isWarnEnabled()) {
367 _log.warn(e);
368 }
369 }
370
371 if (Validator.isNull(contentDispositionType)) {
372 String extension = GetterUtil.getString(
373 FileUtil.getExtension(fileName));
374
375 extension = StringUtil.toLowerCase(extension);
376
377 String[] mimeTypesContentDispositionInline = null;
378
379 try {
380 mimeTypesContentDispositionInline = PropsUtil.getArray(
381 "mime.types.content.disposition.inline");
382 }
383 catch (Exception e) {
384 mimeTypesContentDispositionInline = new String[0];
385 }
386
387 if (ArrayUtil.contains(
388 mimeTypesContentDispositionInline, extension)) {
389
390 contentDispositionType = HttpHeaders.CONTENT_DISPOSITION_INLINE;
391 }
392 else {
393 contentDispositionType =
394 HttpHeaders.CONTENT_DISPOSITION_ATTACHMENT;
395 }
396 }
397
398 StringBundler sb = new StringBundler(4);
399
400 sb.append(contentDispositionType);
401 sb.append(StringPool.SEMICOLON);
402 sb.append(StringPool.SPACE);
403 sb.append(contentDispositionFileName);
404
405 mimeResponse.setProperty(
406 HttpHeaders.CONTENT_DISPOSITION, sb.toString());
407 }
408
409 private static final Log _log = LogFactoryUtil.getLog(
410 PortletResponseUtil.class);
411
412 }