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