1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.util.servlet;
24  
25  import com.liferay.portal.kernel.servlet.HttpHeaders;
26  import com.liferay.portal.kernel.util.FileUtil;
27  import com.liferay.portal.kernel.util.GetterUtil;
28  import com.liferay.portal.kernel.util.ServerDetector;
29  import com.liferay.portal.kernel.util.StringPool;
30  import com.liferay.portal.kernel.util.StringUtil;
31  import com.liferay.portal.kernel.util.Validator;
32  
33  import java.io.BufferedOutputStream;
34  import java.io.IOException;
35  import java.io.InputStream;
36  import java.io.OutputStream;
37  
38  import java.net.SocketException;
39  
40  import javax.servlet.http.HttpServletResponse;
41  
42  import org.apache.commons.codec.net.URLCodec;
43  import org.apache.commons.lang.CharUtils;
44  import org.apache.commons.logging.Log;
45  import org.apache.commons.logging.LogFactory;
46  
47  /**
48   * <a href="ServletResponseUtil.java.html"><b><i>View Source</i></b></a>
49   *
50   * @author Brian Wing Shun Chan
51   *
52   */
53  public class ServletResponseUtil {
54  
55      public static void cleanUp(InputStream is) {
56          try {
57              if (is != null) {
58                  is.close();
59              }
60          }
61          catch (Exception e) {
62              if (_log.isWarnEnabled()) {
63                  _log.warn(e);
64              }
65          }
66      }
67  
68      public static void cleanUp(OutputStream os) {
69          try {
70              if (os != null) {
71                  os.flush();
72              }
73          }
74          catch (Exception e) {
75              if (_log.isWarnEnabled()) {
76                  _log.warn(e);
77              }
78          }
79  
80          try {
81              if (os != null) {
82                  os.close();
83              }
84          }
85          catch (Exception e) {
86              if (_log.isWarnEnabled()) {
87                  _log.warn(e);
88              }
89          }
90      }
91  
92      public static void cleanUp(OutputStream os, InputStream is) {
93          cleanUp(os);
94          cleanUp(is);
95      }
96  
97      public static void sendFile(
98              HttpServletResponse response, String fileName, byte[] bytes)
99          throws IOException {
100 
101         sendFile(response, fileName, bytes, null);
102     }
103 
104     public static void sendFile(
105             HttpServletResponse response, String fileName, byte[] bytes,
106             String contentType)
107         throws IOException {
108 
109         setHeaders(response, fileName, contentType);
110 
111         write(response, bytes);
112     }
113 
114     public static void sendFile(
115             HttpServletResponse response, String fileName, InputStream is)
116         throws IOException {
117 
118         sendFile(response, fileName, is, null);
119     }
120 
121     public static void sendFile(
122             HttpServletResponse response, String fileName, InputStream is,
123             String contentType)
124         throws IOException {
125 
126         setHeaders(response, fileName, contentType);
127 
128         write(response, is);
129     }
130 
131     public static void write(HttpServletResponse response, String s)
132         throws IOException {
133 
134         write(response, s.getBytes(StringPool.UTF8));
135     }
136 
137     public static void write(HttpServletResponse response, byte[] bytes)
138         throws IOException {
139 
140         write(response, bytes, 0);
141     }
142 
143     public static void write(
144             HttpServletResponse response, byte[] bytes, int contentLength)
145         throws IOException {
146 
147         OutputStream os = null;
148 
149         try {
150 
151             // LEP-3122
152 
153             if (!response.isCommitted() || ServerDetector.isPramati()) {
154 
155                 // LEP-536
156 
157                 if (contentLength == 0) {
158                     contentLength = bytes.length;
159                 }
160 
161                 response.setContentLength(contentLength);
162 
163                 os = new BufferedOutputStream(response.getOutputStream());
164 
165                 os.write(bytes, 0, contentLength);
166             }
167         }
168         catch (IOException ioe) {
169             if (ioe instanceof SocketException ||
170                 ioe.getClass().getName().equals(_CLIENT_ABORT_EXCEPTION)) {
171 
172                 if (_log.isWarnEnabled()) {
173                     _log.warn(ioe);
174                 }
175             }
176             else {
177                 throw ioe;
178             }
179         }
180         finally {
181             cleanUp(os);
182         }
183     }
184 
185     public static void write(HttpServletResponse response, InputStream is)
186         throws IOException {
187 
188         OutputStream os = null;
189 
190         try {
191             if (!response.isCommitted()) {
192                 os = new BufferedOutputStream(response.getOutputStream());
193 
194                 int c = is.read();
195 
196                 while (c != -1) {
197                     os.write(c);
198 
199                     c = is.read();
200                 }
201             }
202         }
203         finally {
204             cleanUp(os, is);
205         }
206     }
207 
208     protected static void setHeaders(
209         HttpServletResponse response, String fileName, String contentType) {
210 
211         if (_log.isDebugEnabled()) {
212             _log.debug("Sending file of type " + contentType);
213         }
214 
215         // LEP-2201
216 
217         if (Validator.isNotNull(contentType)) {
218             response.setContentType(contentType);
219         }
220 
221         response.setHeader(HttpHeaders.CACHE_CONTROL, HttpHeaders.PUBLIC);
222         response.setHeader(HttpHeaders.PRAGMA, HttpHeaders.PUBLIC);
223 
224         if (Validator.isNotNull(fileName)) {
225             String contentDisposition =
226                 "attachment; filename=\"" + fileName + "\"";
227 
228             // If necessary for non-ASCII characters, encode based on RFC 2184.
229             // However, not all browsers support RFC 2184. See LEP-3127.
230 
231             boolean ascii = true;
232 
233             for (int i = 0; i < fileName.length(); i++) {
234                 if (!CharUtils.isAscii(fileName.charAt(i))) {
235                     ascii = false;
236 
237                     break;
238                 }
239             }
240 
241             try {
242                 if (!ascii) {
243                     URLCodec codec = new URLCodec(StringPool.UTF8);
244 
245                     String encodedFileName =
246                         StringUtil.replace(codec.encode(fileName), "+", "%20");
247 
248                     contentDisposition =
249                         "attachment; filename*=UTF-8''" + encodedFileName;
250                 }
251             }
252             catch (Exception e) {
253                 if (_log.isWarnEnabled()) {
254                     _log.warn(e);
255                 }
256             }
257 
258             String extension = GetterUtil.getString(
259                 FileUtil.getExtension(fileName));
260 
261             if (extension.equals("pdf")) {
262                 contentDisposition = StringUtil.replace(
263                     contentDisposition, "attachment; ", "inline; ");
264             }
265 
266             response.setHeader(
267                 HttpHeaders.CONTENT_DISPOSITION, contentDisposition);
268         }
269     }
270 
271     private static final String _CLIENT_ABORT_EXCEPTION =
272         "org.apache.catalina.connector.ClientAbortException";
273 
274     private static Log _log = LogFactory.getLog(ServletResponseUtil.class);
275 
276 }