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.GetterUtil;
27  import com.liferay.portal.kernel.util.ServerDetector;
28  import com.liferay.portal.kernel.util.StringPool;
29  import com.liferay.portal.kernel.util.StringUtil;
30  import com.liferay.portal.kernel.util.Validator;
31  import com.liferay.util.FileUtil;
32  
33  import java.io.BufferedOutputStream;
34  import java.io.IOException;
35  import java.io.InputStream;
36  import java.io.OutputStream;
37  
38  import javax.servlet.http.HttpServletResponse;
39  
40  import org.apache.commons.codec.net.URLCodec;
41  import org.apache.commons.lang.CharUtils;
42  import org.apache.commons.logging.Log;
43  import org.apache.commons.logging.LogFactory;
44  
45  /**
46   * <a href="ServletResponseUtil.java.html"><b><i>View Source</i></b></a>
47   *
48   * @author Brian Wing Shun Chan
49   *
50   */
51  public class ServletResponseUtil {
52  
53      public static final String DEFAULT_CONTENT_TYPE =
54          "application/octet-stream";
55  
56      public static void cleanUp(InputStream is) {
57          try {
58              if (is != null) {
59                  is.close();
60              }
61          }
62          catch (Exception e) {
63              if (_log.isWarnEnabled()) {
64                  _log.warn(e);
65              }
66          }
67      }
68  
69      public static void cleanUp(OutputStream os) {
70          try {
71              if (os != null) {
72                  os.flush();
73              }
74          }
75          catch (Exception e) {
76              if (_log.isWarnEnabled()) {
77                  _log.warn(e);
78              }
79          }
80  
81          try {
82              if (os != null) {
83                  os.close();
84              }
85          }
86          catch (Exception e) {
87              if (_log.isWarnEnabled()) {
88                  _log.warn(e);
89              }
90          }
91      }
92  
93      public static void cleanUp(OutputStream os, InputStream is) {
94          cleanUp(os);
95          cleanUp(is);
96      }
97  
98      public static void sendFile(
99              HttpServletResponse res, String fileName, byte[] byteArray)
100         throws IOException {
101 
102         sendFile(res, fileName, byteArray, null);
103     }
104 
105     public static void sendFile(
106             HttpServletResponse res, String fileName, byte[] byteArray,
107             String contentType)
108         throws IOException {
109 
110         setHeaders(res, fileName, contentType);
111 
112         write(res, byteArray);
113     }
114 
115     public static void sendFile(
116             HttpServletResponse res, String fileName, InputStream is)
117         throws IOException {
118 
119         sendFile(res, fileName, is, null);
120     }
121 
122     public static void sendFile(
123             HttpServletResponse res, String fileName, InputStream is,
124             String contentType)
125         throws IOException {
126 
127         setHeaders(res, fileName, contentType);
128 
129         write(res, is);
130     }
131 
132     public static void write(HttpServletResponse res, String s)
133         throws IOException {
134 
135         write(res, s.getBytes(StringPool.UTF8));
136     }
137 
138     public static void write(HttpServletResponse res, byte[] byteArray)
139         throws IOException {
140 
141         write(res, byteArray, 0);
142     }
143 
144     public static void write(
145             HttpServletResponse res, byte[] byteArray, int contentLength)
146         throws IOException {
147 
148         OutputStream os = null;
149 
150         try {
151 
152             // LEP-3122
153 
154             if (!res.isCommitted() || ServerDetector.isPramati()) {
155 
156                 // LEP-536
157 
158                 if (contentLength == 0) {
159                     contentLength = byteArray.length;
160                 }
161 
162                 res.setContentLength(contentLength);
163 
164                 os = new BufferedOutputStream(res.getOutputStream());
165 
166                 os.write(byteArray, 0, contentLength);
167             }
168         }
169         finally {
170             cleanUp(os);
171         }
172     }
173 
174     public static void write(HttpServletResponse res, InputStream is)
175         throws IOException {
176 
177         OutputStream os = null;
178 
179         try {
180             if (!res.isCommitted()) {
181                 os = new BufferedOutputStream(res.getOutputStream());
182 
183                 int c = is.read();
184 
185                 while (c != -1) {
186                     os.write(c);
187 
188                     c = is.read();
189                 }
190             }
191         }
192         finally {
193             cleanUp(os, is);
194         }
195     }
196 
197     protected static void setHeaders(
198             HttpServletResponse res, String fileName, String contentType)
199         throws IOException {
200 
201         if (_log.isDebugEnabled()) {
202             _log.debug("Sending file of type " + contentType);
203         }
204 
205         // LEP-2201
206 
207         if (Validator.isNotNull(contentType)) {
208             res.setContentType(contentType);
209         }
210 
211         res.setHeader(HttpHeaders.CACHE_CONTROL, HttpHeaders.PUBLIC);
212         res.setHeader(HttpHeaders.PRAGMA, HttpHeaders.PUBLIC);
213 
214         if (Validator.isNotNull(fileName)) {
215             String contentDisposition =
216                 "attachment; filename=\"" + fileName + "\"";
217 
218             // If necessary for non-ASCII characters, encode based on RFC 2184.
219             // However, not all browsers support RFC 2184. See LEP-3127.
220 
221             boolean ascii = true;
222 
223             for (int i = 0; i < fileName.length(); i++) {
224                 if (!CharUtils.isAscii(fileName.charAt(i))) {
225                     ascii = false;
226 
227                     break;
228                 }
229             }
230 
231             try {
232                 if (!ascii) {
233                     URLCodec codec = new URLCodec(StringPool.UTF8);
234 
235                     String encodedFileName =
236                         StringUtil.replace(codec.encode(fileName), "+", "%20");
237 
238                     contentDisposition =
239                         "attachment; filename*=UTF-8''" + encodedFileName;
240                 }
241             }
242             catch (Exception e) {
243                 if (_log.isWarnEnabled()) {
244                     _log.warn(e);
245                 }
246             }
247 
248             String extension = GetterUtil.getString(
249                 FileUtil.getExtension(fileName));
250 
251             if (extension.equals("pdf")) {
252                 contentDisposition = StringUtil.replace(
253                     contentDisposition, "attachment; ", "inline; ");
254             }
255 
256             res.setHeader(HttpHeaders.CONTENT_DISPOSITION, contentDisposition);
257         }
258     }
259 
260     private static Log _log = LogFactory.getLog(ServletResponseUtil.class);
261 
262 }