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