001
014
015 package com.liferay.portal.servlet.filters.gzip;
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.servlet.BrowserSnifferUtil;
021 import com.liferay.portal.kernel.servlet.HttpHeaders;
022 import com.liferay.portal.kernel.servlet.MetaInfoCacheServletResponse;
023 import com.liferay.portal.kernel.servlet.ServletOutputStreamAdapter;
024 import com.liferay.portal.kernel.util.ContentTypes;
025 import com.liferay.portal.kernel.util.UnsyncPrintWriterPool;
026 import com.liferay.portal.util.PropsValues;
027 import com.liferay.util.RSSThreadLocal;
028
029 import java.io.IOException;
030 import java.io.OutputStream;
031 import java.io.PrintWriter;
032
033 import java.util.zip.GZIPOutputStream;
034
035 import javax.servlet.ServletOutputStream;
036 import javax.servlet.http.HttpServletRequest;
037 import javax.servlet.http.HttpServletResponse;
038
039
044 public class GZipResponse extends MetaInfoCacheServletResponse {
045
046 public GZipResponse(
047 HttpServletRequest request, HttpServletResponse response) {
048
049 super(response);
050
051 _response = response;
052
053
054
055
056
057 _response.setContentLength(-1);
058
059
060
061 _response.addHeader(HttpHeaders.CONTENT_ENCODING, _GZIP);
062
063 _firefox = BrowserSnifferUtil.isFirefox(request);
064 }
065
066
069 @Deprecated
070 @Override
071 public void finishResponse() throws IOException {
072 finishResponse(false);
073 }
074
075 @Override
076 public void finishResponse(boolean reapplyMetaData) throws IOException {
077
078
079
080 if (!isCommitted()) {
081
082
083
084 if ((_servletOutputStream == null) ||
085 ((_servletOutputStream != null) &&
086 (_unsyncByteArrayOutputStream != null) &&
087 (_unsyncByteArrayOutputStream.size() == 0))) {
088
089
090
091 _response.reset();
092
093
094
095 super.finishResponse(reapplyMetaData);
096 }
097 }
098
099 try {
100 if (_printWriter != null) {
101 _printWriter.close();
102 }
103 else if (_servletOutputStream != null) {
104 _servletOutputStream.close();
105 }
106 }
107 catch (IOException ioe) {
108 }
109
110 if (_unsyncByteArrayOutputStream != null) {
111 _response.setContentLength(_unsyncByteArrayOutputStream.size());
112
113 _unsyncByteArrayOutputStream.writeTo(_response.getOutputStream());
114 }
115 }
116
117 @Override
118 public void flushBuffer() throws IOException {
119 if (_servletOutputStream != null) {
120 _servletOutputStream.flush();
121 }
122 }
123
124 @Override
125 public ServletOutputStream getOutputStream() throws IOException {
126 if (_printWriter != null) {
127 throw new IllegalStateException();
128 }
129
130 if (_servletOutputStream == null) {
131 if (_isGZipContentType()) {
132 _servletOutputStream = _response.getOutputStream();
133 }
134 else {
135 if (_firefox && RSSThreadLocal.isExportRSS()) {
136 _unsyncByteArrayOutputStream =
137 new UnsyncByteArrayOutputStream();
138
139 _servletOutputStream = _createGZipServletOutputStream(
140 _unsyncByteArrayOutputStream);
141 }
142 else {
143 _servletOutputStream = _createGZipServletOutputStream(
144 _response.getOutputStream());
145 }
146 }
147 }
148
149 return _servletOutputStream;
150 }
151
152 @Override
153 public PrintWriter getWriter() throws IOException {
154 if (_printWriter != null) {
155 return _printWriter;
156 }
157
158 if (_servletOutputStream != null) {
159 throw new IllegalStateException();
160 }
161
162 if (_log.isWarnEnabled()) {
163 _log.warn("Use getOutputStream for optimum performance");
164 }
165
166 _servletOutputStream = getOutputStream();
167
168 _printWriter = UnsyncPrintWriterPool.borrow(
169 _servletOutputStream, getCharacterEncoding());
170
171 return _printWriter;
172 }
173
174 @Override
175 public void setContentLength(int contentLength) {
176 }
177
178 @Override
179 public void setHeader(String name, String value) {
180 if (HttpHeaders.CONTENT_LENGTH.equals(name)) {
181 return;
182 }
183
184 _response.setHeader(name, value);
185 }
186
187 private ServletOutputStream _createGZipServletOutputStream(
188 OutputStream outputStream)
189 throws IOException {
190
191 GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream) {
192
193 {
194 def.setLevel(PropsValues.GZIP_COMPRESSION_LEVEL);
195 }
196
197 };
198
199 return new ServletOutputStreamAdapter(gzipOutputStream);
200 }
201
202 private boolean _isGZipContentType() {
203 String contentType = getContentType();
204
205 if (contentType != null) {
206 if (contentType.equals(ContentTypes.APPLICATION_GZIP) ||
207 contentType.equals(ContentTypes.APPLICATION_X_GZIP)) {
208
209 return true;
210 }
211 }
212
213 return false;
214 }
215
216 private static final String _GZIP = "gzip";
217
218 private static Log _log = LogFactoryUtil.getLog(GZipResponse.class);
219
220 private boolean _firefox;
221 private PrintWriter _printWriter;
222 private HttpServletResponse _response;
223 private ServletOutputStream _servletOutputStream;
224 private UnsyncByteArrayOutputStream _unsyncByteArrayOutputStream;
225
226 }