1
2
3
4
5
6 package org.tailormap.api.geotools;
7
8 import java.io.ByteArrayOutputStream;
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.net.URL;
12 import java.util.Collections;
13 import java.util.HashMap;
14 import java.util.Map;
15 import java.util.Set;
16 import java.util.function.BiConsumer;
17 import org.geotools.http.HTTPClient;
18 import org.geotools.http.HTTPResponse;
19
20
21
22
23
24
25
26
27
28 public class ResponseTeeingHTTPClient implements HTTPClient {
29
30 public class TeeHTTPResponseWrapper implements HTTPResponse {
31 private final HTTPResponse wrapped;
32
33 private boolean disposed = false;
34 private final ByteArrayOutputStream copy = new ByteArrayOutputStream();
35
36 private String contentType;
37 private final Map<String, String> cachedResponseHeaders = new HashMap<>();
38
39 public TeeHTTPResponseWrapper(HTTPResponse wrapped) {
40 this.wrapped = wrapped;
41 }
42
43 public byte[] getCopy() {
44 return copy.toByteArray();
45 }
46
47
48 @Override
49 public void dispose() {
50 disposed = true;
51 wrapped.dispose();
52 }
53
54 public boolean isDisposed() {
55 return disposed;
56 }
57
58 @Override
59 public String getContentType() {
60 if (contentType == null) {
61 contentType = wrapped.getContentType();
62 }
63 return contentType;
64 }
65
66 @Override
67 public String getResponseHeader(String header) {
68 if (cachedResponseHeaders.containsKey(header)) {
69 return cachedResponseHeaders.get(header);
70 }
71
72
73 if (isDisposed()) {
74 return null;
75 }
76 return wrapped.getResponseHeader(header);
77 }
78
79 @Override
80 public InputStream getResponseStream() throws IOException {
81
82 for (String header : responseHeadersToCache) {
83 cachedResponseHeaders.put(header, wrapped.getResponseHeader(header));
84 }
85 return new org.apache.commons.io.input.TeeInputStream(wrapped.getResponseStream(), copy);
86 }
87
88 @Override
89 public String getResponseCharset() {
90 return wrapped.getResponseCharset();
91 }
92
93 }
94
95 private TeeHTTPResponseWrapper responseWrapper;
96
97 private final HTTPClient wrapped;
98
99 private final BiConsumer<URL, TeeHTTPResponseWrapper> requestConsumer;
100
101 private final Set<String> responseHeadersToCache;
102
103
104
105
106
107
108
109
110
111 public ResponseTeeingHTTPClient(HTTPClient wrapped) {
112 this(wrapped, null, null);
113 }
114
115
116
117
118
119
120
121
122
123
124
125
126
127 public ResponseTeeingHTTPClient(
128 HTTPClient wrapped,
129 BiConsumer<URL, TeeHTTPResponseWrapper> requestConsumer,
130 Set<String> responseHeadersToCache) {
131 this.wrapped = wrapped;
132 this.requestConsumer = requestConsumer == null ? (url, response) -> {} : requestConsumer;
133 this.responseHeadersToCache =
134 responseHeadersToCache == null ? Collections.emptySet() : responseHeadersToCache;
135 }
136
137 @Override
138 public HTTPResponse get(URL url, Map<String, String> headers) throws IOException {
139 this.responseWrapper = new TeeHTTPResponseWrapper(wrapped.get(url, headers));
140 requestConsumer.accept(url, this.responseWrapper);
141 return responseWrapper;
142 }
143
144 @Override
145 public HTTPResponse post(URL url, InputStream inputStream, String s) throws IOException {
146 this.responseWrapper = new TeeHTTPResponseWrapper(wrapped.post(url, inputStream, s));
147 requestConsumer.accept(url, this.responseWrapper);
148 return responseWrapper;
149 }
150
151 @Override
152 public HTTPResponse get(URL url) throws IOException {
153 this.responseWrapper = new TeeHTTPResponseWrapper(wrapped.get(url));
154 requestConsumer.accept(url, this.responseWrapper);
155 return responseWrapper;
156 }
157
158 public HTTPResponse getLatestResponse() {
159 return responseWrapper;
160 }
161
162 public byte[] getLatestResponseCopy() {
163 return responseWrapper == null ? null : responseWrapper.getCopy();
164 }
165
166
167 @Override
168 public String getUser() {
169 return wrapped.getUser();
170 }
171
172 @Override
173 public void setUser(String user) {
174 wrapped.setUser(user);
175 }
176
177 @Override
178 public String getPassword() {
179 return wrapped.getPassword();
180 }
181
182 @Override
183 public void setPassword(String password) {
184 wrapped.setPassword(password);
185 }
186
187 @Override
188 public Map<String, String> getExtraParams() {
189 return wrapped.getExtraParams();
190 }
191
192 @Override
193 public void setExtraParams(Map<String, String> extraParams) {
194 wrapped.setExtraParams(extraParams);
195 }
196
197 @Override
198 public int getConnectTimeout() {
199 return wrapped.getConnectTimeout();
200 }
201
202 @Override
203 public void setConnectTimeout(int connectTimeout) {
204 wrapped.setConnectTimeout(connectTimeout);
205 }
206
207 @Override
208 public int getReadTimeout() {
209 return wrapped.getReadTimeout();
210 }
211
212 @Override
213 public void setReadTimeout(int readTimeout) {
214 wrapped.setReadTimeout(readTimeout);
215 }
216
217 @Override
218 public void setTryGzip(boolean tryGZIP) {
219 wrapped.setTryGzip(tryGZIP);
220 }
221
222 @Override
223 public boolean isTryGzip() {
224 return wrapped.isTryGzip();
225 }
226
227 }