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 @Override
067 public void finishResponse(boolean reapplyMetaData) throws IOException {
068
069
070
071 if (!isCommitted()) {
072
073
074
075 if ((_servletOutputStream == null) ||
076 ((_servletOutputStream != null) &&
077 (_unsyncByteArrayOutputStream != null) &&
078 (_unsyncByteArrayOutputStream.size() == 0))) {
079
080
081
082 _response.reset();
083
084
085
086 super.finishResponse(reapplyMetaData);
087 }
088 }
089
090 try {
091 if (_printWriter != null) {
092 _printWriter.close();
093 }
094 else if (_servletOutputStream != null) {
095 _servletOutputStream.close();
096 }
097 }
098 catch (IOException ioe) {
099 }
100
101 if (_unsyncByteArrayOutputStream != null) {
102 _response.setContentLength(_unsyncByteArrayOutputStream.size());
103
104 _unsyncByteArrayOutputStream.writeTo(_response.getOutputStream());
105 }
106 }
107
108 @Override
109 public void flushBuffer() throws IOException {
110 if (_servletOutputStream != null) {
111 _servletOutputStream.flush();
112 }
113 }
114
115 @Override
116 public ServletOutputStream getOutputStream() throws IOException {
117 if (_printWriter != null) {
118 throw new IllegalStateException();
119 }
120
121 if (_servletOutputStream == null) {
122 if (_isGZipContentType()) {
123 _servletOutputStream = _response.getOutputStream();
124 }
125 else {
126 if (_firefox && RSSThreadLocal.isExportRSS()) {
127 _unsyncByteArrayOutputStream =
128 new UnsyncByteArrayOutputStream();
129
130 _servletOutputStream = _createGZipServletOutputStream(
131 _unsyncByteArrayOutputStream);
132 }
133 else {
134 _servletOutputStream = _createGZipServletOutputStream(
135 _response.getOutputStream());
136 }
137 }
138 }
139
140 return _servletOutputStream;
141 }
142
143 @Override
144 public PrintWriter getWriter() throws IOException {
145 if (_printWriter != null) {
146 return _printWriter;
147 }
148
149 if (_servletOutputStream != null) {
150 throw new IllegalStateException();
151 }
152
153 if (_log.isWarnEnabled()) {
154 _log.warn("Use getOutputStream for optimum performance");
155 }
156
157 _servletOutputStream = getOutputStream();
158
159 _printWriter = UnsyncPrintWriterPool.borrow(
160 _servletOutputStream, getCharacterEncoding());
161
162 return _printWriter;
163 }
164
165 @Override
166 public void setContentLength(int contentLength) {
167 }
168
169 @Override
170 public void setHeader(String name, String value) {
171 if (HttpHeaders.CONTENT_LENGTH.equals(name)) {
172 return;
173 }
174
175 super.setHeader(name, value);
176 }
177
178 private ServletOutputStream _createGZipServletOutputStream(
179 OutputStream outputStream)
180 throws IOException {
181
182 GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream) {
183
184 {
185 def.setLevel(PropsValues.GZIP_COMPRESSION_LEVEL);
186 }
187
188 };
189
190 return new ServletOutputStreamAdapter(gzipOutputStream);
191 }
192
193 private boolean _isGZipContentType() {
194 String contentType = getContentType();
195
196 if (contentType != null) {
197 if (contentType.equals(ContentTypes.APPLICATION_GZIP) ||
198 contentType.equals(ContentTypes.APPLICATION_X_GZIP)) {
199
200 return true;
201 }
202 }
203
204 return false;
205 }
206
207 private static final String _GZIP = "gzip";
208
209 private static final Log _log = LogFactoryUtil.getLog(GZipResponse.class);
210
211 private final boolean _firefox;
212 private PrintWriter _printWriter;
213 private final HttpServletResponse _response;
214 private ServletOutputStream _servletOutputStream;
215 private UnsyncByteArrayOutputStream _unsyncByteArrayOutputStream;
216
217 }