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 private ServletOutputStream _createGZipServletOutputStream(
170 OutputStream outputStream)
171 throws IOException {
172
173 GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream) {
174
175 {
176 def.setLevel(PropsValues.GZIP_COMPRESSION_LEVEL);
177 }
178
179 };
180
181 return new ServletOutputStreamAdapter(gzipOutputStream);
182 }
183
184 private boolean _isGZipContentType() {
185 String contentType = getContentType();
186
187 if (contentType != null) {
188 if (contentType.equals(ContentTypes.APPLICATION_GZIP) ||
189 contentType.equals(ContentTypes.APPLICATION_X_GZIP)) {
190
191 return true;
192 }
193 }
194
195 return false;
196 }
197
198 private static final String _GZIP = "gzip";
199
200 private static final Log _log = LogFactoryUtil.getLog(GZipResponse.class);
201
202 private final boolean _firefox;
203 private PrintWriter _printWriter;
204 private final HttpServletResponse _response;
205 private ServletOutputStream _servletOutputStream;
206 private UnsyncByteArrayOutputStream _unsyncByteArrayOutputStream;
207
208 }