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