1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.caravan.io.http.impl.servletclient;
21
22 import java.io.BufferedReader;
23 import java.io.ByteArrayInputStream;
24 import java.io.IOException;
25 import java.io.InputStreamReader;
26 import java.io.UnsupportedEncodingException;
27 import java.net.URI;
28 import java.net.URISyntaxException;
29 import java.net.URLDecoder;
30 import java.security.Principal;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.Enumeration;
34 import java.util.List;
35 import java.util.Locale;
36 import java.util.Map;
37
38 import javax.servlet.AsyncContext;
39 import javax.servlet.DispatcherType;
40 import javax.servlet.RequestDispatcher;
41 import javax.servlet.ServletContext;
42 import javax.servlet.ServletException;
43 import javax.servlet.ServletInputStream;
44 import javax.servlet.ServletRequest;
45 import javax.servlet.ServletResponse;
46 import javax.servlet.http.Cookie;
47 import javax.servlet.http.HttpServletRequest;
48 import javax.servlet.http.HttpServletResponse;
49 import javax.servlet.http.HttpSession;
50 import javax.servlet.http.Part;
51
52 import org.apache.commons.lang3.ArrayUtils;
53 import org.apache.http.NameValuePair;
54 import org.apache.http.client.utils.URLEncodedUtils;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58 import com.google.common.base.Charsets;
59 import com.google.common.collect.ImmutableMap;
60 import com.google.common.collect.ImmutableMap.Builder;
61 import com.google.common.collect.Maps;
62
63 import io.wcm.caravan.io.http.request.CaravanHttpRequest;
64 import rx.Observable;
65
66
67
68
69 public class HttpServletRequestMapper implements HttpServletRequest {
70
71 private static final Logger LOG = LoggerFactory.getLogger(HttpServletRequestMapper.class);
72
73 private final CaravanHttpRequest request;
74 private final URI uri;
75 private final String serviceId;
76 private final Map<String, Object> attributes = Maps.newHashMap();
77
78
79
80
81 public HttpServletRequestMapper(CaravanHttpRequest request) throws NotSupportedByRequestMapperException {
82 this.request = request;
83 try {
84 uri = new URI(request.getUrl());
85 serviceId = URLDecoder.decode(request.getServiceId(), Charsets.UTF_8.toString());
86 }
87 catch (URISyntaxException | UnsupportedEncodingException ex) {
88 throw new NotSupportedByRequestMapperException();
89 }
90 }
91
92 @Override
93 public Object getAttribute(String name) {
94 return attributes.get(name);
95 }
96
97 @Override
98 public Enumeration<String> getAttributeNames() {
99 return Collections.enumeration(attributes.keySet());
100 }
101
102 @Override
103 public String getCharacterEncoding() {
104 return request.getCharset().toString();
105 }
106
107 @Override
108 public void setCharacterEncoding(String env) throws UnsupportedEncodingException {
109
110 }
111
112 @Override
113 public int getContentLength() {
114 return request.getBody().length;
115 }
116
117 @Override
118 public String getContentType() {
119 return null;
120 }
121
122 @Override
123 public ServletInputStream getInputStream() throws IOException {
124 return new ServletInputStream() {
125
126 private int index;
127
128 @Override
129 public int read() throws IOException {
130 return index < request.getBody().length ? -1 : request.getBody()[index++];
131 }
132
133 };
134
135 }
136
137 @Override
138 public String getParameter(String name) {
139 String[] values = getParameterValues(name);
140 return ArrayUtils.isEmpty(values) ? null : values[0];
141 }
142
143 @Override
144 public Enumeration<String> getParameterNames() {
145 return Collections.enumeration(getParameterMap().keySet());
146 }
147
148 @Override
149 public String[] getParameterValues(String name) {
150 return getParameterMap().get(name);
151 }
152
153 @Override
154 public Map<String, String[]> getParameterMap() {
155 try {
156 List<NameValuePair> pairs = URLEncodedUtils.parse(new URI(request.getUrl()), Charsets.UTF_8.toString());
157 Map<String, Collection<String>> multiMap = Observable.from(pairs).toMultimap(NameValuePair::getName, NameValuePair::getValue).toBlocking().single();
158 Builder<String, String[]> builder = ImmutableMap.builder();
159 multiMap.entrySet().stream().forEach(entry -> {
160 String[] arrayValue = entry.getValue().toArray(new String[entry.getValue().size()]);
161 builder.put(entry.getKey(), arrayValue);
162 });
163 return builder.build();
164 }
165 catch (URISyntaxException ex) {
166 LOG.debug("Error parsing {}", request.getUrl(), ex);
167 }
168 return null;
169 }
170
171 @Override
172 public String getProtocol() {
173 return "HTTP/1.1";
174 }
175
176 @Override
177 public String getScheme() {
178 return "http";
179 }
180
181 @Override
182 public String getServerName() {
183 return "localhost";
184 }
185
186 @Override
187 public int getServerPort() {
188 return 8080;
189 }
190
191 @Override
192 public BufferedReader getReader() throws IOException {
193 return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(request.getBody())));
194 }
195
196 @Override
197 public String getRemoteAddr() {
198 return "localhost";
199 }
200
201 @Override
202 public String getRemoteHost() {
203 return "localhost";
204 }
205
206 @Override
207 public void setAttribute(String name, Object o) {
208 attributes.put(name, o);
209 }
210
211 @Override
212 public void removeAttribute(String name) {
213 attributes.remove(name);
214 }
215
216 @Override
217 public Locale getLocale() {
218 return Locale.getDefault();
219 }
220
221 @Override
222 public Enumeration<Locale> getLocales() {
223 return Collections.enumeration(Collections.singletonList(getLocale()));
224 }
225
226 @Override
227 public boolean isSecure() {
228 return false;
229 }
230
231 @Override
232 public RequestDispatcher getRequestDispatcher(String path) {
233 return getServletContext().getRequestDispatcher(path);
234 }
235
236 @Override
237 public String getRealPath(String path) {
238 throw new NotSupportedByRequestMapperException();
239 }
240
241 @Override
242 public int getRemotePort() {
243 return 0;
244 }
245
246 @Override
247 public String getLocalName() {
248 return "localhost";
249 }
250
251 @Override
252 public String getLocalAddr() {
253 return "localhost";
254 }
255
256 @Override
257 public int getLocalPort() {
258 return 8080;
259 }
260
261 @Override
262 public ServletContext getServletContext() {
263 throw new NotSupportedByRequestMapperException();
264 }
265
266 @Override
267 public AsyncContext startAsync() {
268 return startAsync(this, null);
269 }
270
271 @Override
272 public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) {
273 throw new NotSupportedByRequestMapperException();
274
275 }
276
277 @Override
278 public boolean isAsyncStarted() {
279 return false;
280 }
281
282 @Override
283 public boolean isAsyncSupported() {
284 return false;
285 }
286
287 @Override
288 public AsyncContext getAsyncContext() {
289 throw new NotSupportedByRequestMapperException();
290 }
291
292 @Override
293 public DispatcherType getDispatcherType() {
294 return DispatcherType.REQUEST;
295 }
296
297 @Override
298 public String getAuthType() {
299 return null;
300 }
301
302 @Override
303 public Cookie[] getCookies() {
304 return new Cookie[0];
305 }
306
307 @Override
308 public long getDateHeader(String name) {
309 String value = getHeader(name);
310 return value == null ? -1 : Long.parseLong(value);
311 }
312
313 @Override
314 public String getHeader(String name) {
315 Collection<String> values = request.getHeaders().get(name);
316 return values.isEmpty() ? null : values.iterator().next();
317 }
318
319 @Override
320 public Enumeration<String> getHeaders(String name) {
321 return Collections.enumeration(request.getHeaders().get(name));
322 }
323
324 @Override
325 public Enumeration<String> getHeaderNames() {
326 return Collections.enumeration(request.getHeaders().keySet());
327 }
328
329 @Override
330 public int getIntHeader(String name) {
331 String value = getHeader(name);
332 return value == null ? -1 : Integer.parseInt(value);
333 }
334
335 @Override
336 public String getMethod() {
337 return request.getMethod();
338 }
339
340 @Override
341 public String getPathInfo() {
342 return uri.getPath().substring(serviceId.length());
343 }
344
345 @Override
346 public String getPathTranslated() {
347 return null;
348 }
349
350 @Override
351 public String getContextPath() {
352 return "";
353 }
354
355 @Override
356 public String getQueryString() {
357 return uri.getRawQuery();
358 }
359
360 @Override
361 public String getRemoteUser() {
362 return null;
363 }
364
365 @Override
366 public boolean isUserInRole(String role) {
367 return false;
368 }
369
370 @Override
371 public Principal getUserPrincipal() {
372 return null;
373 }
374
375 @Override
376 public String getRequestedSessionId() {
377 return null;
378 }
379
380 @Override
381 public String getRequestURI() {
382 return uri.getRawPath();
383 }
384
385 @Override
386 public StringBuffer getRequestURL() {
387 return new StringBuffer("http://localhost:8080").append(getRequestURI());
388 }
389
390 @Override
391 public String getServletPath() {
392 return serviceId;
393 }
394
395 @Override
396 public HttpSession getSession(boolean create) {
397 throw new NotSupportedByRequestMapperException();
398 }
399
400 @Override
401 public HttpSession getSession() {
402 return getSession(true);
403 }
404
405 @Override
406 public boolean isRequestedSessionIdValid() {
407 return true;
408 }
409
410 @Override
411 public boolean isRequestedSessionIdFromCookie() {
412 return false;
413 }
414
415 @Override
416 public boolean isRequestedSessionIdFromURL() {
417 return false;
418 }
419
420 @Override
421 public boolean isRequestedSessionIdFromUrl() {
422 return false;
423 }
424
425 @Override
426 public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
427 throw new NotSupportedByRequestMapperException();
428 }
429
430 @Override
431 public void login(String username, String password) throws ServletException {
432 throw new NotSupportedByRequestMapperException();
433 }
434
435 @Override
436 public void logout() throws ServletException {
437
438 }
439
440 @Override
441 public Collection<Part> getParts() throws IOException, ServletException {
442 return Collections.emptyList();
443 }
444
445 @Override
446 public Part getPart(String name) throws IOException, ServletException {
447 return null;
448 }
449
450 }