001/**
002 * Copyright (C) 2006-2020 Talend Inc. - www.talend.com
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.talend.sdk.component.server.front.memory;
017
018import static java.util.Collections.emptyEnumeration;
019import static java.util.Collections.emptySet;
020import static java.util.Collections.enumeration;
021import static java.util.Collections.singleton;
022
023import java.io.BufferedReader;
024import java.io.IOException;
025import java.io.InputStreamReader;
026import java.security.Principal;
027import java.text.SimpleDateFormat;
028import java.util.Collection;
029import java.util.Enumeration;
030import java.util.HashMap;
031import java.util.List;
032import java.util.Locale;
033import java.util.Map;
034import java.util.function.Supplier;
035
036import javax.servlet.AsyncContext;
037import javax.servlet.DispatcherType;
038import javax.servlet.RequestDispatcher;
039import javax.servlet.ServletContext;
040import javax.servlet.ServletInputStream;
041import javax.servlet.ServletRequest;
042import javax.servlet.ServletResponse;
043import javax.servlet.http.Cookie;
044import javax.servlet.http.HttpServletRequest;
045import javax.servlet.http.HttpServletResponse;
046import javax.servlet.http.HttpSession;
047import javax.servlet.http.HttpUpgradeHandler;
048import javax.servlet.http.Part;
049
050import org.apache.cxf.transport.servlet.ServletController;
051import org.apache.tomcat.util.http.FastHttpDateFormat;
052import org.talend.sdk.component.server.front.security.ConnectionSecurityProvider;
053
054import lombok.RequiredArgsConstructor;
055import lombok.Setter;
056
057@RequiredArgsConstructor
058public class InMemoryRequest implements HttpServletRequest {
059
060    private static final Cookie[] NO_COOKIE = new Cookie[0];
061
062    private static final SimpleDateFormat[] DATE_FORMATS =
063            { new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US),
064                    new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
065                    new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US) };
066
067    private final Map<String, Object> attributes = new HashMap<>();
068
069    private final String method;
070
071    private final Map<String, List<String>> headers;
072
073    private final String requestUri;
074
075    private final String pathInfo;
076
077    private final String servletPath;
078
079    private final String query;
080
081    private final int port;
082
083    private final ServletContext servletContext;
084
085    private final ServletInputStream inputStream;
086
087    private final Supplier<Principal> principalSupplier;
088
089    private final ServletController controller;
090
091    private String encoding;
092
093    private long length;
094
095    private String type;
096
097    private Map<String, String[]> parameters = new HashMap<>();
098
099    private Locale locale = Locale.getDefault();
100
101    private BufferedReader reader;
102
103    @Setter
104    private InMemoryResponse response;
105
106    private AsyncContext asyncContext;
107
108    @Override
109    public String getAuthType() {
110        return null;
111    }
112
113    @Override
114    public Cookie[] getCookies() {
115        return NO_COOKIE;
116    }
117
118    @Override
119    public long getDateHeader(final String name) {
120        final String value = getHeader(name);
121        if (value == null) {
122            return -1L;
123        }
124
125        final SimpleDateFormat[] formats = new SimpleDateFormat[DATE_FORMATS.length];
126        for (int i = 0; i < formats.length; i++) {
127            formats[i] = SimpleDateFormat.class.cast(DATE_FORMATS[i].clone());
128        }
129
130        final long result = FastHttpDateFormat.parseDate(value, formats);
131        if (result != -1L) {
132            return result;
133        }
134        throw new IllegalArgumentException(value);
135    }
136
137    @Override
138    public String getHeader(final String s) {
139        final List<String> strings = headers.get(s);
140        return strings == null || strings.isEmpty() ? null : strings.iterator().next();
141    }
142
143    @Override
144    public Enumeration<String> getHeaders(final String s) {
145        final List<String> strings = headers.get(s);
146        return strings == null || strings.isEmpty() ? null : enumeration(strings);
147    }
148
149    @Override
150    public Enumeration<String> getHeaderNames() {
151        return enumeration(headers.keySet());
152    }
153
154    @Override
155    public int getIntHeader(final String s) {
156        final String value = getHeader(s);
157        if (value == null) {
158            return -1;
159        }
160
161        return Integer.parseInt(value);
162    }
163
164    @Override
165    public String getMethod() {
166        return method;
167    }
168
169    @Override
170    public String getPathInfo() {
171        return pathInfo;
172    }
173
174    @Override
175    public String getPathTranslated() {
176        return pathInfo;
177    }
178
179    @Override
180    public String getContextPath() {
181        return servletContext.getContextPath();
182    }
183
184    @Override
185    public String getQueryString() {
186        return query;
187    }
188
189    @Override
190    public String getRemoteUser() {
191        final Principal principal = getUserPrincipal();
192        return principal == null ? null : principal.getName();
193    }
194
195    @Override
196    public boolean isUserInRole(final String s) {
197        return false; // if needed do it with the original request
198    }
199
200    @Override
201    public Principal getUserPrincipal() {
202        return principalSupplier.get();
203    }
204
205    @Override
206    public String getRequestedSessionId() {
207        return null;
208    }
209
210    @Override
211    public String getRequestURI() {
212        return requestUri;
213    }
214
215    @Override
216    public StringBuffer getRequestURL() {
217        return new StringBuffer(requestUri);
218    }
219
220    @Override
221    public String getServletPath() {
222        return servletPath;
223    }
224
225    @Override
226    public HttpSession getSession(final boolean b) {
227        return null;
228    }
229
230    @Override
231    public HttpSession getSession() {
232        return null;
233    }
234
235    @Override
236    public String changeSessionId() {
237        return null;
238    }
239
240    @Override
241    public boolean isRequestedSessionIdValid() {
242        return false;
243    }
244
245    @Override
246    public boolean isRequestedSessionIdFromCookie() {
247        return false;
248    }
249
250    @Override
251    public boolean isRequestedSessionIdFromURL() {
252        return false;
253    }
254
255    @Override
256    public boolean isRequestedSessionIdFromUrl() {
257        return false;
258    }
259
260    @Override
261    public boolean authenticate(final HttpServletResponse httpServletResponse) {
262        return false;
263    }
264
265    @Override
266    public void login(final String s, final String s1) {
267        // no-op
268    }
269
270    @Override
271    public void logout() {
272        // no-op
273    }
274
275    @Override
276    public Collection<Part> getParts() {
277        return emptySet();
278    }
279
280    @Override
281    public Part getPart(final String s) {
282        return null;
283    }
284
285    @Override
286    public <T extends HttpUpgradeHandler> T upgrade(final Class<T> aClass) {
287        return null;
288    }
289
290    @Override
291    public Object getAttribute(final String s) {
292        if (ConnectionSecurityProvider.SKIP.equalsIgnoreCase(s)) {
293            return Boolean.TRUE;
294        }
295        return attributes.get(s);
296    }
297
298    @Override
299    public Enumeration<String> getAttributeNames() {
300        return enumeration(attributes.keySet());
301    }
302
303    @Override
304    public String getCharacterEncoding() {
305        return encoding;
306    }
307
308    @Override
309    public void setCharacterEncoding(final String s) {
310        encoding = s;
311    }
312
313    @Override
314    public int getContentLength() {
315        return (int) length;
316    }
317
318    @Override
319    public long getContentLengthLong() {
320        return length;
321    }
322
323    @Override
324    public String getContentType() {
325        return type;
326    }
327
328    @Override
329    public ServletInputStream getInputStream() throws IOException {
330        return inputStream;
331    }
332
333    @Override
334    public String getParameter(final String s) {
335        final String[] strings = parameters.get(s);
336        return strings == null || strings.length == 0 ? null : strings[0];
337    }
338
339    @Override
340    public Enumeration<String> getParameterNames() {
341        return enumeration(parameters.keySet());
342    }
343
344    @Override
345    public String[] getParameterValues(final String s) {
346        return parameters.get(s);
347    }
348
349    @Override
350    public Map<String, String[]> getParameterMap() {
351        return parameters;
352    }
353
354    @Override
355    public String getProtocol() {
356        return "HTTP/1.1";
357    }
358
359    @Override
360    public String getScheme() {
361        return "http";
362    }
363
364    @Override
365    public String getServerName() {
366        return servletContext.getVirtualServerName();
367    }
368
369    @Override
370    public int getServerPort() {
371        return port;
372    }
373
374    @Override
375    public BufferedReader getReader() throws IOException {
376        return reader == null ? (reader = new BufferedReader(new InputStreamReader(getInputStream()))) : reader;
377    }
378
379    @Override
380    public String getRemoteAddr() {
381        return null;
382    }
383
384    @Override
385    public String getRemoteHost() {
386        return null;
387    }
388
389    @Override
390    public void setAttribute(final String s, final Object o) {
391        attributes.put(s, o);
392    }
393
394    @Override
395    public void removeAttribute(final String s) {
396        attributes.remove(s);
397    }
398
399    @Override
400    public Locale getLocale() {
401        return locale;
402    }
403
404    @Override
405    public Enumeration<Locale> getLocales() {
406        return locale == null ? emptyEnumeration() : enumeration(singleton(locale));
407    }
408
409    @Override
410    public boolean isSecure() {
411        return false;
412    }
413
414    @Override
415    public String getRealPath(final String s) {
416        return null;
417    }
418
419    @Override
420    public int getRemotePort() {
421        return 0;
422    }
423
424    @Override
425    public String getLocalName() {
426        return null;
427    }
428
429    @Override
430    public String getLocalAddr() {
431        return null;
432    }
433
434    @Override
435    public int getLocalPort() {
436        return 0;
437    }
438
439    @Override
440    public ServletContext getServletContext() {
441        return servletContext;
442    }
443
444    @Override
445    public RequestDispatcher getRequestDispatcher(final String s) {
446        return servletContext.getRequestDispatcher(s);
447    }
448
449    @Override
450    public AsyncContext startAsync() throws IllegalStateException {
451        asyncContext = new AsyncContextImpl(this, response, true, controller).start();
452        return asyncContext;
453    }
454
455    @Override
456    public AsyncContext startAsync(final ServletRequest servletRequest, final ServletResponse servletResponse)
457            throws IllegalStateException {
458        asyncContext =
459                new AsyncContextImpl(servletRequest, InMemoryResponse.class.cast(servletResponse), false, controller)
460                        .start();
461        return asyncContext;
462    }
463
464    @Override
465    public boolean isAsyncStarted() {
466        return asyncContext != null;
467    }
468
469    @Override
470    public boolean isAsyncSupported() {
471        return true;
472    }
473
474    @Override
475    public AsyncContext getAsyncContext() {
476        return asyncContext;
477    }
478
479    @Override
480    public DispatcherType getDispatcherType() {
481        throw new UnsupportedOperationException();
482    }
483}