1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.esigate.http;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.OutputStream;
21 import java.io.UnsupportedEncodingException;
22 import java.nio.charset.Charset;
23 import java.nio.charset.UnsupportedCharsetException;
24 import java.util.List;
25
26 import org.apache.http.Header;
27 import org.apache.http.HttpEntity;
28 import org.apache.http.HttpResponse;
29 import org.apache.http.HttpStatus;
30 import org.apache.http.client.entity.DeflateDecompressingEntity;
31 import org.apache.http.client.entity.GzipDecompressingEntity;
32 import org.apache.http.client.methods.CloseableHttpResponse;
33 import org.apache.http.cookie.Cookie;
34 import org.apache.http.cookie.CookieOrigin;
35 import org.apache.http.cookie.CookieSpec;
36 import org.apache.http.cookie.MalformedCookieException;
37 import org.apache.http.entity.ContentType;
38 import org.apache.http.impl.cookie.DefaultCookieSpec;
39 import org.apache.http.protocol.HTTP;
40 import org.apache.http.util.Args;
41 import org.apache.http.util.EntityUtils;
42 import org.esigate.HttpErrorPage;
43 import org.esigate.events.EventManager;
44 import org.esigate.events.impl.ReadEntityEvent;
45 import org.esigate.util.UriUtils;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49
50
51
52
53
54
55
56 public final class HttpResponseUtils {
57 private static final Logger LOG = LoggerFactory.getLogger(HttpResponseUtils.class);
58 private static final int OUTPUT_BUFFER_SIZE = 4096;
59
60 private HttpResponseUtils() {
61
62 }
63
64
65
66
67
68
69
70
71 public static boolean isError(HttpResponse httpResponse) {
72 return httpResponse.getStatusLine().getStatusCode() >= HttpStatus.SC_BAD_REQUEST;
73 }
74
75
76
77
78
79
80
81
82 public static String getFirstHeader(String headerName, HttpResponse httpResponse) {
83 Header header = httpResponse.getFirstHeader(headerName);
84 if (header != null) {
85 return header.getValue();
86 }
87 return null;
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 public static String removeSessionId(String uri, HttpResponse httpResponse) {
109 CookieSpec cookieSpec = new DefaultCookieSpec();
110
111
112 CookieOrigin cookieOrigin = new CookieOrigin("dummy", Http.DEFAULT_HTTP_PORT, "/", false);
113 Header[] responseHeaders = httpResponse.getHeaders("Set-cookie");
114 String jsessionid = null;
115 for (Header header : responseHeaders) {
116 try {
117 List<Cookie> cookies = cookieSpec.parse(header, cookieOrigin);
118 for (Cookie cookie : cookies) {
119 if ("JSESSIONID".equalsIgnoreCase(cookie.getName())) {
120 jsessionid = cookie.getValue();
121 }
122 break;
123 }
124 } catch (MalformedCookieException ex) {
125 LOG.warn("Malformed header: " + header.getName() + ": " + header.getValue());
126 }
127 if (jsessionid != null) {
128 break;
129 }
130 }
131 if (jsessionid == null) {
132 return uri;
133 }
134
135 return UriUtils.removeSessionId(jsessionid, uri);
136
137 }
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155 public static String toString(HttpResponse httpResponse, EventManager eventManager) throws HttpErrorPage {
156 HttpEntity httpEntity = httpResponse.getEntity();
157 String result;
158 if (httpEntity == null) {
159 result = httpResponse.getStatusLine().getReasonPhrase();
160 } else {
161
162 Header contentEncoding = httpEntity.getContentEncoding();
163 if (contentEncoding != null) {
164 String contentEncodingValue = contentEncoding.getValue();
165 if ("gzip".equalsIgnoreCase(contentEncodingValue) || "x-gzip".equalsIgnoreCase(contentEncodingValue)) {
166 httpEntity = new GzipDecompressingEntity(httpEntity);
167 } else if ("deflate".equalsIgnoreCase(contentEncodingValue)) {
168 httpEntity = new DeflateDecompressingEntity(httpEntity);
169 } else {
170 throw new UnsupportedContentEncodingException("Content-encoding \"" + contentEncoding
171 + "\" is not supported");
172 }
173 }
174
175 try {
176 byte[] rawEntityContent = EntityUtils.toByteArray(httpEntity);
177 ContentType contentType;
178 Charset charset;
179 String mimeType;
180 try {
181 contentType = ContentType.getOrDefault(httpEntity);
182 mimeType = contentType.getMimeType();
183 charset = contentType.getCharset();
184 } catch (UnsupportedCharsetException ex) {
185 throw new UnsupportedEncodingException(ex.getMessage());
186 }
187
188
189
190 if (charset == null) {
191 charset = HTTP.DEF_CONTENT_CHARSET;
192 }
193
194 ReadEntityEvent event = new ReadEntityEvent(mimeType, charset, rawEntityContent);
195
196
197 event.setEntityContent(new String(rawEntityContent, charset));
198
199
200 if (eventManager != null) {
201 eventManager.fire(EventManager.EVENT_READ_ENTITY, event);
202 }
203
204 return event.getEntityContent();
205
206 } catch (IOException e) {
207 throw new HttpErrorPage(HttpErrorPage.generateHttpResponse(e));
208 }
209 }
210
211 return removeSessionId(result, httpResponse);
212 }
213
214 public static ContentType getContentType(CloseableHttpResponse response) {
215 HttpEntity entity = response.getEntity();
216 if (entity == null) {
217 return null;
218 }
219 return ContentType.get(entity);
220 }
221
222 public static String toString(CloseableHttpResponse response) throws HttpErrorPage {
223 return toString(response, null);
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237 public static void writeTo(final HttpEntity httpEntity, final OutputStream outstream) throws IOException {
238 Args.notNull(outstream, "Output stream");
239 try (InputStream instream = httpEntity.getContent()) {
240 final byte[] buffer = new byte[OUTPUT_BUFFER_SIZE];
241 int l;
242 if (httpEntity.getContentLength() < 0) {
243
244 while ((l = instream.read(buffer)) != -1) {
245 outstream.write(buffer, 0, l);
246 outstream.flush();
247 LOG.debug("Flushed {} bytes of data");
248 }
249 } else {
250
251 long remaining = httpEntity.getContentLength();
252 while (remaining > 0) {
253 l = instream.read(buffer, 0, (int) Math.min(OUTPUT_BUFFER_SIZE, remaining));
254 if (l == -1) {
255 break;
256 }
257 outstream.write(buffer, 0, l);
258 outstream.flush();
259 LOG.debug("Flushed {} bytes of data");
260 remaining -= l;
261 }
262 }
263 }
264 }
265
266 }