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