001
014
015 package com.liferay.portal.kernel.servlet;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.nio.charset.CharsetEncoderUtil;
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.ServerDetector;
027 import com.liferay.portal.kernel.util.StreamUtil;
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
032 import java.io.File;
033 import java.io.FileInputStream;
034 import java.io.IOException;
035 import java.io.InputStream;
036
037 import java.net.SocketException;
038
039 import java.nio.ByteBuffer;
040 import java.nio.channels.Channels;
041 import java.nio.channels.FileChannel;
042
043 import javax.servlet.ServletOutputStream;
044 import javax.servlet.http.HttpServletRequest;
045 import javax.servlet.http.HttpServletResponse;
046
047
051 public class ServletResponseUtil {
052
053 public static void sendFile(
054 HttpServletRequest request, HttpServletResponse response,
055 String fileName, byte[] bytes)
056 throws IOException {
057
058 sendFile(request, response, fileName, bytes, null);
059 }
060
061 public static void sendFile(
062 HttpServletRequest request, HttpServletResponse response,
063 String fileName, byte[] bytes, String contentType)
064 throws IOException {
065
066 setHeaders(request, response, fileName, contentType);
067
068 write(response, bytes);
069 }
070
071 public static void sendFile(
072 HttpServletRequest request, HttpServletResponse response,
073 String fileName, InputStream is)
074 throws IOException {
075
076 sendFile(request, response, fileName, is, null);
077 }
078
079 public static void sendFile(
080 HttpServletRequest request, HttpServletResponse response,
081 String fileName, InputStream is, long contentLength,
082 String contentType)
083 throws IOException {
084
085 setHeaders(request, response, fileName, contentType);
086
087 write(response, is, contentLength);
088 }
089
090 public static void sendFile(
091 HttpServletRequest request, HttpServletResponse response,
092 String fileName, InputStream is, String contentType)
093 throws IOException {
094
095 sendFile(request, response, fileName, is, 0, contentType);
096 }
097
098
101 public static void sendFile(
102 HttpServletResponse response, String fileName, byte[] bytes)
103 throws IOException {
104
105 sendFile(null, response, fileName, bytes);
106 }
107
108
111 public static void sendFile(
112 HttpServletResponse response, String fileName, byte[] bytes,
113 String contentType)
114 throws IOException {
115
116 sendFile(null, response, fileName, bytes, contentType);
117 }
118
119
122 public static void sendFile(
123 HttpServletResponse response, String fileName, InputStream is)
124 throws IOException {
125
126 sendFile(null, response, fileName, is);
127 }
128
129
132 public static void sendFile(
133 HttpServletResponse response, String fileName, InputStream is,
134 int contentLength, String contentType)
135 throws IOException {
136
137 sendFile(null, response, fileName, is, contentLength, contentType);
138 }
139
140
143 public static void sendFile(
144 HttpServletResponse response, String fileName, InputStream is,
145 String contentType)
146 throws IOException {
147
148 sendFile(null, response, fileName, is, contentType);
149 }
150
151 public static void write(HttpServletResponse response, byte[] bytes)
152 throws IOException {
153
154 write(response, bytes, 0, 0);
155 }
156
157 public static void write(
158 HttpServletResponse response, byte[] bytes, int offset,
159 int contentLength)
160 throws IOException {
161
162 try {
163
164
165
166 if (!response.isCommitted()) {
167
168
169
170 if (contentLength == 0) {
171 contentLength = bytes.length;
172 }
173
174 response.setContentLength(contentLength);
175
176 response.flushBuffer();
177
178 if (response instanceof ByteBufferServletResponse) {
179 ByteBufferServletResponse byteBufferResponse =
180 (ByteBufferServletResponse)response;
181
182 byteBufferResponse.setByteBuffer(
183 ByteBuffer.wrap(bytes, offset, contentLength));
184 }
185 else {
186 ServletOutputStream servletOutputStream =
187 response.getOutputStream();
188
189 if ((contentLength == 0) && ServerDetector.isJetty()) {
190 }
191 else {
192 servletOutputStream.write(bytes, offset, contentLength);
193 }
194 }
195 }
196 }
197 catch (IOException ioe) {
198 if (ioe instanceof SocketException ||
199 ioe.getClass().getName().equals(_CLIENT_ABORT_EXCEPTION)) {
200
201 if (_log.isWarnEnabled()) {
202 _log.warn(ioe);
203 }
204 }
205 else {
206 throw ioe;
207 }
208 }
209 }
210
211 public static void write(HttpServletResponse response, byte[][] bytesArray)
212 throws IOException {
213
214 try {
215
216
217
218 if (!response.isCommitted()) {
219 int contentLength = 0;
220
221 for (byte[] bytes : bytesArray) {
222 contentLength += bytes.length;
223 }
224
225 response.setContentLength(contentLength);
226
227 response.flushBuffer();
228
229 ServletOutputStream servletOutputStream =
230 response.getOutputStream();
231
232 for (byte[] bytes : bytesArray) {
233 servletOutputStream.write(bytes);
234 }
235 }
236 }
237 catch (IOException ioe) {
238 if (ioe instanceof SocketException ||
239 ioe.getClass().getName().equals(_CLIENT_ABORT_EXCEPTION)) {
240
241 if (_log.isWarnEnabled()) {
242 _log.warn(ioe);
243 }
244 }
245 else {
246 throw ioe;
247 }
248 }
249 }
250
251 public static void write(
252 HttpServletResponse response, ByteBuffer byteBuffer)
253 throws IOException {
254
255 if (response instanceof ByteBufferServletResponse) {
256 ByteBufferServletResponse byteBufferResponse =
257 (ByteBufferServletResponse)response;
258
259 byteBufferResponse.setByteBuffer(byteBuffer);
260 }
261 else {
262 write(
263 response, byteBuffer.array(), byteBuffer.position(),
264 byteBuffer.limit());
265 }
266 }
267
268 public static void write(HttpServletResponse response, File file)
269 throws IOException {
270
271 if (response instanceof ByteBufferServletResponse) {
272 ByteBufferServletResponse byteBufferResponse =
273 (ByteBufferServletResponse)response;
274
275 ByteBuffer byteBuffer = ByteBuffer.wrap(FileUtil.getBytes(file));
276
277 byteBufferResponse.setByteBuffer(byteBuffer);
278 }
279 else if (response instanceof StringServletResponse) {
280 StringServletResponse stringResponse =
281 (StringServletResponse)response;
282
283 String s = FileUtil.read(file);
284
285 stringResponse.setString(s);
286 }
287 else {
288 FileInputStream fileInputStream = new FileInputStream(file);
289
290 FileChannel fileChannel = fileInputStream.getChannel();
291
292 try {
293 int contentLength = (int)fileChannel.size();
294
295 response.setContentLength(contentLength);
296
297 response.flushBuffer();
298
299 fileChannel.transferTo(
300 0, contentLength,
301 Channels.newChannel(response.getOutputStream()));
302 }
303 finally {
304 fileChannel.close();
305 }
306 }
307 }
308
309 public static void write(HttpServletResponse response, InputStream is)
310 throws IOException {
311
312 write(response, is, 0);
313 }
314
315 public static void write(
316 HttpServletResponse response, InputStream is, long contentLength)
317 throws IOException {
318
319 if (response.isCommitted()) {
320 return;
321 }
322
323 if (contentLength > 0) {
324 response.setHeader(
325 HttpHeaders.CONTENT_LENGTH, String.valueOf(contentLength));
326 }
327
328 response.flushBuffer();
329
330 StreamUtil.transfer(is, response.getOutputStream());
331 }
332
333 public static void write(HttpServletResponse response, String s)
334 throws IOException {
335
336 if (response instanceof StringServletResponse) {
337 StringServletResponse stringResponse =
338 (StringServletResponse)response;
339
340 stringResponse.setString(s);
341 }
342 else {
343 ByteBuffer byteBuffer = CharsetEncoderUtil.encode(
344 StringPool.UTF8, s);
345
346 write(response, byteBuffer);
347 }
348 }
349
350 public static void write(
351 HttpServletResponse response, StringServletResponse stringResponse)
352 throws IOException {
353
354 if (stringResponse.isCalledGetOutputStream()) {
355 UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
356 stringResponse.getUnsyncByteArrayOutputStream();
357
358 ByteBuffer byteBuffer =
359 unsyncByteArrayOutputStream.unsafeGetByteBuffer();
360
361 write(response, byteBuffer);
362 }
363 else {
364 write(response, stringResponse.getString());
365 }
366 }
367
368 protected static void setHeaders(
369 HttpServletRequest request, HttpServletResponse response,
370 String fileName, String contentType) {
371
372 if (_log.isDebugEnabled()) {
373 _log.debug("Sending file of type " + contentType);
374 }
375
376
377
378 if (Validator.isNotNull(contentType)) {
379 response.setContentType(contentType);
380 }
381
382 response.setHeader(
383 HttpHeaders.CACHE_CONTROL, HttpHeaders.CACHE_CONTROL_PUBLIC_VALUE);
384 response.setHeader(HttpHeaders.PRAGMA, HttpHeaders.PRAGMA_PUBLIC_VALUE);
385
386 if (Validator.isNotNull(fileName)) {
387 String contentDisposition =
388 "attachment; filename=\"" + fileName + "\"";
389
390
391
392
393 boolean ascii = true;
394
395 for (int i = 0; i < fileName.length(); i++) {
396 if (!Validator.isAscii(fileName.charAt(i))) {
397 ascii = false;
398
399 break;
400 }
401 }
402
403 try {
404 if (!ascii) {
405 String encodedFileName = HttpUtil.encodeURL(fileName, true);
406
407 if (BrowserSnifferUtil.isIe(request)) {
408 contentDisposition =
409 "attachment; filename=\"" + encodedFileName + "\"";
410 }
411 else {
412 contentDisposition =
413 "attachment; filename*=UTF-8''" + encodedFileName;
414 }
415 }
416 }
417 catch (Exception e) {
418 if (_log.isWarnEnabled()) {
419 _log.warn(e);
420 }
421 }
422
423 String extension = GetterUtil.getString(
424 FileUtil.getExtension(fileName)).toLowerCase();
425
426 String[] mimeTypesContentDispositionInline = null;
427
428 try {
429 mimeTypesContentDispositionInline = PropsUtil.getArray(
430 "mime.types.content.disposition.inline");
431 }
432 catch (Exception e) {
433 mimeTypesContentDispositionInline = new String[0];
434 }
435
436 if (ArrayUtil.contains(
437 mimeTypesContentDispositionInline, extension)) {
438
439 contentDisposition = StringUtil.replace(
440 contentDisposition, "attachment; ", "inline; ");
441 }
442
443 response.setHeader(
444 HttpHeaders.CONTENT_DISPOSITION, contentDisposition);
445 }
446 }
447
448 private static final String _CLIENT_ABORT_EXCEPTION =
449 "org.apache.catalina.connector.ClientAbortException";
450
451 private static Log _log = LogFactoryUtil.getLog(ServletResponseUtil.class);
452
453 }