001package runwar.undertow;
002
003import java.io.BufferedReader;
004import java.io.IOException;
005import java.io.UnsupportedEncodingException;
006import java.util.Collection;
007import java.util.Enumeration;
008import java.util.Locale;
009import java.util.Map;
010
011import javax.servlet.AsyncContext;
012import javax.servlet.DispatcherType;
013import javax.servlet.RequestDispatcher;
014import javax.servlet.ServletContext;
015import javax.servlet.ServletException;
016import javax.servlet.ServletInputStream;
017import javax.servlet.ServletRequest;
018import javax.servlet.ServletRequestWrapper;
019import javax.servlet.ServletResponse;
020import javax.servlet.http.Cookie;
021import javax.servlet.http.HttpServletRequest;
022import javax.servlet.http.HttpServletResponse;
023import javax.servlet.http.HttpSession;
024import javax.servlet.http.HttpUpgradeHandler;
025import javax.servlet.http.Part;
026
027/**
028 * @author Stuart Douglas
029 */
030public class RequestWrapper implements HttpServletRequest {
031
032    private ServletRequest request;
033
034    /**
035     * Creates a ServletRequest adaptor wrapping the given request object.
036     * @throws java.lang.IllegalArgumentException if the request is null
037     */
038    public RequestWrapper(ServletRequest request) {
039        if (request == null) {
040            throw new IllegalArgumentException("Request cannot be null");
041        }
042        this.request = request;
043    }
044
045    /**
046     * Return the wrapped request object.
047     */
048    public ServletRequest getRequest() {
049        return this.request;
050    }
051
052
053    /**
054     * Sets the request object being wrapped.
055     * @throws java.lang.IllegalArgumentException if the request is null.
056     */
057    public void setRequest(ServletRequest request) {
058        if (request == null) {
059            throw new IllegalArgumentException("Request cannot be null");
060        }
061        this.request = request;
062    }
063
064
065    /**
066     * The default behavior of this method is to call getAttribute(String name)
067     * on the wrapped request object.
068     */
069    public Object getAttribute(String name) {
070        return this.request.getAttribute(name);
071    }
072
073
074    /**
075     * The default behavior of this method is to return getAttributeNames()
076     * on the wrapped request object.
077     */
078    public Enumeration<String> getAttributeNames() {
079        return this.request.getAttributeNames();
080    }
081
082
083    /**
084     * The default behavior of this method is to return getCharacterEncoding()
085     * on the wrapped request object.
086     */
087    public String getCharacterEncoding() {
088        return this.request.getCharacterEncoding();
089    }
090
091
092    /**
093     * The default behavior of this method is to set the character encoding
094     * on the wrapped request object.
095     */
096    public void setCharacterEncoding(String enc)
097            throws UnsupportedEncodingException {
098        this.request.setCharacterEncoding(enc);
099    }
100
101
102    /**
103     * The default behavior of this method is to return getContentLength()
104     * on the wrapped request object.
105     */
106    public int getContentLength() {
107        return this.request.getContentLength();
108    }
109
110    /**
111     * The default behavior of this method is to return getContentLengthLong()
112     * on the wrapped request object.
113     *
114     * @since Servlet 3.1
115     */
116    public long getContentLengthLong() {
117        return this.request.getContentLengthLong();
118    }
119
120
121    /**
122     * The default behavior of this method is to return getContentType()
123     * on the wrapped request object.
124     */
125    public String getContentType() {
126        return this.request.getContentType();
127    }
128
129
130    /**
131     * The default behavior of this method is to return getInputStream()
132     * on the wrapped request object.
133     */
134    public ServletInputStream getInputStream() throws IOException {
135        return this.request.getInputStream();
136    }
137
138
139    /**
140     * The default behavior of this method is to return
141     * getParameter(String name) on the wrapped request object.
142     */
143    public String getParameter(String name) {
144        return this.request.getParameter(name);
145    }
146
147
148    /**
149     * The default behavior of this method is to return getParameterMap()
150     * on the wrapped request object.
151     */
152    public Map<String, String[]> getParameterMap() {
153        return this.request.getParameterMap();
154    }
155
156
157    /**
158     * The default behavior of this method is to return getParameterNames()
159     * on the wrapped request object.
160     */
161    public Enumeration<String> getParameterNames() {
162        return this.request.getParameterNames();
163    }
164
165
166    /**
167     * The default behavior of this method is to return
168     * getParameterValues(String name) on the wrapped request object.
169     */
170    public String[] getParameterValues(String name) {
171        return this.request.getParameterValues(name);
172    }
173
174
175    /**
176     * The default behavior of this method is to return getProtocol()
177     * on the wrapped request object.
178     */
179    public String getProtocol() {
180        return this.request.getProtocol();
181    }
182
183
184    /**
185     * The default behavior of this method is to return getScheme()
186     * on the wrapped request object.
187     */
188    public String getScheme() {
189        return this.request.getScheme();
190    }
191
192
193    /**
194     * The default behavior of this method is to return getServerName()
195     * on the wrapped request object.
196     */
197    public String getServerName() {
198        return this.request.getServerName();
199    }
200
201
202    /**
203     * The default behavior of this method is to return getServerPort()
204     * on the wrapped request object.
205     */
206    public int getServerPort() {
207        return this.request.getServerPort();
208    }
209
210
211    /**
212     * The default behavior of this method is to return getReader()
213     * on the wrapped request object.
214     */
215    public BufferedReader getReader() throws IOException {
216        return this.request.getReader();
217    }
218
219
220    /**
221     * The default behavior of this method is to return getRemoteAddr()
222     * on the wrapped request object.
223     */
224    public String getRemoteAddr() {
225        return this.request.getRemoteAddr();
226    }
227
228
229    /**
230     * The default behavior of this method is to return getRemoteHost()
231     * on the wrapped request object.
232     */
233    public String getRemoteHost() {
234        return this.request.getRemoteHost();
235    }
236
237
238    /**
239     * The default behavior of this method is to return
240     * setAttribute(String name, Object o) on the wrapped request object.
241     */
242    public void setAttribute(String name, Object o) {
243        this.request.setAttribute(name, o);
244    }
245
246
247    /**
248     * The default behavior of this method is to call
249     * removeAttribute(String name) on the wrapped request object.
250     */
251    public void removeAttribute(String name) {
252        this.request.removeAttribute(name);
253    }
254
255
256    /**
257     * The default behavior of this method is to return getLocale()
258     * on the wrapped request object.
259     */
260    public Locale getLocale() {
261        return this.request.getLocale();
262    }
263
264
265    /**
266     * The default behavior of this method is to return getLocales()
267     * on the wrapped request object.
268     */
269    public Enumeration<Locale> getLocales() {
270        return this.request.getLocales();
271    }
272
273
274    /**
275     * The default behavior of this method is to return isSecure()
276     * on the wrapped request object.
277     */
278    public boolean isSecure() {
279        return this.request.isSecure();
280    }
281
282
283    /**
284     * The default behavior of this method is to return
285     * getRequestDispatcher(String path) on the wrapped request object.
286     */
287    public RequestDispatcher getRequestDispatcher(String path) {
288        return this.request.getRequestDispatcher(path);
289    }
290
291
292    /**
293     * The default behavior of this method is to return
294     * getRealPath(String path) on the wrapped request object.
295     *
296     * @deprecated As of Version 2.1 of the Java Servlet API,
297     * use {@link ServletContext#getRealPath} instead
298     */
299    public String getRealPath(String path) {
300        return this.request.getRealPath(path);
301    }
302
303
304    /**
305     * The default behavior of this method is to return
306     * getRemotePort() on the wrapped request object.
307     *
308     * @since Servlet 2.4
309     */
310    public int getRemotePort(){
311        return this.request.getRemotePort();
312    }
313
314
315    /**
316     * The default behavior of this method is to return
317     * getLocalName() on the wrapped request object.
318     *
319     * @since Servlet 2.4
320     */
321    public String getLocalName(){
322        return this.request.getLocalName();
323    }
324
325
326    /**
327     * The default behavior of this method is to return
328     * getLocalAddr() on the wrapped request object.
329     *
330     * @since Servlet 2.4
331     */
332    public String getLocalAddr(){
333        return this.request.getLocalAddr();
334    }
335
336
337    /**
338     * The default behavior of this method is to return
339     * getLocalPort() on the wrapped request object.
340     *
341     * @since Servlet 2.4
342     */
343    public int getLocalPort(){
344        return this.request.getLocalPort();
345    }
346
347
348    /**
349     * Gets the servlet context to which the wrapped servlet request was last
350     * dispatched.
351     *
352     * @return the servlet context to which the wrapped servlet request was
353     * last dispatched
354     *
355     * @since Servlet 3.0
356     */
357    public ServletContext getServletContext() {
358        return request.getServletContext();
359    }
360
361
362    /**
363     * The default behavior of this method is to invoke
364     * {@link ServletRequest#startAsync} on the wrapped request object.
365     *
366     * @return the (re)initialized AsyncContext
367     *
368     * @throws IllegalStateException if the request is within the scope of
369     * a filter or servlet that does not support asynchronous operations
370     * (that is, {@link #isAsyncSupported} returns false),
371     * or if this method is called again without any asynchronous dispatch
372     * (resulting from one of the {@link AsyncContext#dispatch} methods),
373     * is called outside the scope of any such dispatch, or is called again
374     * within the scope of the same dispatch, or if the response has
375     * already been closed
376     *
377     * @see ServletRequest#startAsync
378     *
379     * @since Servlet 3.0
380     */
381    public AsyncContext startAsync() throws IllegalStateException {
382        return request.startAsync();
383    }
384
385
386    /**
387     * The default behavior of this method is to invoke
388     * {@link ServletRequest#startAsync(ServletRequest, ServletResponse)}
389     * on the wrapped request object.
390     *
391     * @param servletRequest the ServletRequest used to initialize the
392     * AsyncContext
393     * @param servletResponse the ServletResponse used to initialize the
394     * AsyncContext
395     *
396     * @return the (re)initialized AsyncContext
397     *
398     * @throws IllegalStateException if the request is within the scope of
399     * a filter or servlet that does not support asynchronous operations
400     * (that is, {@link #isAsyncSupported} returns false),
401     * or if this method is called again without any asynchronous dispatch
402     * (resulting from one of the {@link AsyncContext#dispatch} methods),
403     * is called outside the scope of any such dispatch, or is called again
404     * within the scope of the same dispatch, or if the response has
405     * already been closed
406     *
407     * @see ServletRequest#startAsync(ServletRequest, ServletResponse)
408     *
409     * @since Servlet 3.0
410     */
411    public AsyncContext startAsync(ServletRequest servletRequest,
412                                   ServletResponse servletResponse)
413            throws IllegalStateException {
414        return request.startAsync(servletRequest, servletResponse);
415    }
416
417
418    /**
419     * Checks if the wrapped request has been put into asynchronous mode.
420     *
421     * @return true if this request has been put into asynchronous mode,
422     * false otherwise
423     *
424     * @see ServletRequest#isAsyncStarted
425     *
426     * @since Servlet 3.0
427     */
428    public boolean isAsyncStarted() {
429        return request.isAsyncStarted();
430    }
431
432
433    /**
434     * Checks if the wrapped request supports asynchronous operation.
435     *
436     * @return true if this request supports asynchronous operation, false
437     * otherwise
438     *
439     * @see ServletRequest#isAsyncSupported
440     *
441     * @since Servlet 3.0
442     */
443    public boolean isAsyncSupported() {
444        return request.isAsyncSupported();
445    }
446
447
448    /**
449     * Gets the AsyncContext that was created or reinitialized by the
450     * most recent invocation of {@link #startAsync} or
451     * {@link #startAsync(ServletRequest,ServletResponse)} on the wrapped
452     * request.
453     *
454     * @return the AsyncContext that was created or reinitialized by the
455     * most recent invocation of {@link #startAsync} or
456     * {@link #startAsync(ServletRequest,ServletResponse)} on
457     * the wrapped request
458     *
459     * @throws IllegalStateException if this request has not been put
460     * into asynchronous mode, i.e., if neither {@link #startAsync} nor
461     * {@link #startAsync(ServletRequest,ServletResponse)} has been called
462     *
463     * @see ServletRequest#getAsyncContext
464     *
465     * @since Servlet 3.0
466     */
467    public AsyncContext getAsyncContext() {
468        return request.getAsyncContext();
469    }
470
471
472    /**
473     * Checks (recursively) if this ServletRequestWrapper wraps the given
474     * {@link ServletRequest} instance.
475     *
476     * @param wrapped the ServletRequest instance to search for
477     *
478     * @return true if this ServletRequestWrapper wraps the
479     * given ServletRequest instance, false otherwise
480     *
481     * @since Servlet 3.0
482     */
483    public boolean isWrapperFor(ServletRequest wrapped) {
484        if (request == wrapped) {
485            return true;
486        } else if (request instanceof ServletRequestWrapper) {
487            return ((ServletRequestWrapper) request).isWrapperFor(wrapped);
488        } else {
489            return false;
490        }
491    }
492
493
494    /**
495     * Checks (recursively) if this ServletRequestWrapper wraps a
496     * {@link ServletRequest} of the given class type.
497     *
498     * @param wrappedType the ServletRequest class type to
499     * search for
500     *
501     * @return true if this ServletRequestWrapper wraps a
502     * ServletRequest of the given class type, false otherwise
503     *
504     * @throws IllegalArgumentException if the given class does not
505     * implement {@link ServletRequest}
506     *
507     * @since Servlet 3.0
508     */
509    public boolean isWrapperFor(Class<?> wrappedType) {
510        if (!ServletRequest.class.isAssignableFrom(wrappedType)) {
511            throw new IllegalArgumentException("Given class " +
512                wrappedType.getName() + " not a subinterface of " +
513                ServletRequest.class.getName());
514        }
515        if (wrappedType.isAssignableFrom(request.getClass())) {
516            return true;
517        } else if (request instanceof ServletRequestWrapper) {
518            return ((ServletRequestWrapper) request).isWrapperFor(wrappedType);
519        } else {
520            return false;
521        }
522    }
523
524
525    /**
526     * Gets the dispatcher type of the wrapped request.
527     *
528     * @return the dispatcher type of the wrapped request
529     *
530     * @see ServletRequest#getDispatcherType
531     *
532     * @since Servlet 3.0
533     */
534    public DispatcherType getDispatcherType() {
535        return request.getDispatcherType();
536    }
537
538
539    private HttpServletRequest _getHttpServletRequest() {
540        return (HttpServletRequest) getRequest();
541    }
542
543    /**
544     * The default behavior of this method is to return getAuthType()
545     * on the wrapped request object.
546     */
547    @Override
548    public String getAuthType() {
549        return this._getHttpServletRequest().getAuthType();
550    }
551
552    /**
553     * The default behavior of this method is to return getCookies()
554     * on the wrapped request object.
555     */
556    @Override
557    public Cookie[] getCookies() {
558        return this._getHttpServletRequest().getCookies();
559    }
560
561    /**
562     * The default behavior of this method is to return getDateHeader(String name)
563     * on the wrapped request object.
564     */
565    @Override
566    public long getDateHeader(String name) {
567        return this._getHttpServletRequest().getDateHeader(name);
568    }
569
570    /**
571     * The default behavior of this method is to return getHeader(String name)
572     * on the wrapped request object.
573     */
574    @Override
575    public String getHeader(String name) {
576        return this._getHttpServletRequest().getHeader(name);
577    }
578
579    /**
580     * The default behavior of this method is to return getHeaders(String name)
581     * on the wrapped request object.
582     */
583    @Override
584    public Enumeration<String> getHeaders(String name) {
585        return this._getHttpServletRequest().getHeaders(name);
586    }
587
588    /**
589     * The default behavior of this method is to return getHeaderNames()
590     * on the wrapped request object.
591     */
592    @Override
593    public Enumeration<String> getHeaderNames() {
594        return this._getHttpServletRequest().getHeaderNames();
595    }
596
597    /**
598     * The default behavior of this method is to return
599     * getIntHeader(String name) on the wrapped request object.
600     */
601    @Override
602     public int getIntHeader(String name) {
603        return this._getHttpServletRequest().getIntHeader(name);
604    }
605
606    /**
607     * The default behavior of this method is to return getMethod()
608     * on the wrapped request object.
609     */
610    @Override
611    public String getMethod() {
612        return this._getHttpServletRequest().getMethod();
613    }
614
615    /**
616     * The default behavior of this method is to return getPathInfo()
617     * on the wrapped request object.
618     */
619    @Override
620    public String getPathInfo() {
621        return this._getHttpServletRequest().getPathInfo();
622    }
623
624    /**
625     * The default behavior of this method is to return getPathTranslated()
626     * on the wrapped request object.
627     */
628    @Override
629    public String getPathTranslated() {
630        return this._getHttpServletRequest().getPathTranslated();
631    }
632
633    /**
634     * The default behavior of this method is to return getContextPath()
635     * on the wrapped request object.
636     */
637    @Override
638    public String getContextPath() {
639        return this._getHttpServletRequest().getContextPath();
640    }
641
642    /**
643     * The default behavior of this method is to return getQueryString()
644     * on the wrapped request object.
645     */
646    @Override
647    public String getQueryString() {
648        return this._getHttpServletRequest().getQueryString();
649    }
650
651    /**
652     * The default behavior of this method is to return getRemoteUser()
653     * on the wrapped request object.
654     */
655    @Override
656    public String getRemoteUser() {
657        return this._getHttpServletRequest().getRemoteUser();
658    }
659
660    /**
661     * The default behavior of this method is to return isUserInRole(String role)
662     * on the wrapped request object.
663     */
664    @Override
665    public boolean isUserInRole(String role) {
666        return this._getHttpServletRequest().isUserInRole(role);
667    }
668
669    /**
670     * The default behavior of this method is to return getUserPrincipal()
671     * on the wrapped request object.
672     */
673    @Override
674    public java.security.Principal getUserPrincipal() {
675        return this._getHttpServletRequest().getUserPrincipal();
676    }
677
678    /**
679     * The default behavior of this method is to return getRequestedSessionId()
680     * on the wrapped request object.
681     */
682    @Override
683    public String getRequestedSessionId() {
684        return this._getHttpServletRequest().getRequestedSessionId();
685    }
686
687    /**
688     * The default behavior of this method is to return getRequestURI()
689     * on the wrapped request object.
690     */
691    @Override
692    public String getRequestURI() {
693        return this._getHttpServletRequest().getRequestURI();
694    }
695
696    /**
697     * The default behavior of this method is to return getRequestURL()
698     * on the wrapped request object.
699     */
700    @Override
701    public StringBuffer getRequestURL() {
702        return this._getHttpServletRequest().getRequestURL();
703    }
704
705    /**
706     * The default behavior of this method is to return getServletPath()
707     * on the wrapped request object.
708     */
709    @Override
710    public String getServletPath() {
711        return this._getHttpServletRequest().getServletPath();
712    }
713
714    /**
715     * The default behavior of this method is to return getSession(boolean create)
716     * on the wrapped request object.
717     */
718    @Override
719    public HttpSession getSession(boolean create) {
720        return this._getHttpServletRequest().getSession(create);
721    }
722
723    /**
724     * The default behavior of this method is to return getSession()
725     * on the wrapped request object.
726     */
727    @Override
728    public HttpSession getSession() {
729        return this._getHttpServletRequest().getSession();
730    }
731
732    /**
733     * The default behavior of this method is to return changeSessionId()
734     * on the wrapped request object.
735     */
736    @Override
737    public String changeSessionId() {
738        return this._getHttpServletRequest().changeSessionId();
739    }
740
741    /**
742     * The default behavior of this method is to return isRequestedSessionIdValid()
743     * on the wrapped request object.
744     */
745    @Override
746    public boolean isRequestedSessionIdValid() {
747        return this._getHttpServletRequest().isRequestedSessionIdValid();
748    }
749
750    /**
751     * The default behavior of this method is to return isRequestedSessionIdFromCookie()
752     * on the wrapped request object.
753     */
754    @Override
755    public boolean isRequestedSessionIdFromCookie() {
756        return this._getHttpServletRequest().isRequestedSessionIdFromCookie();
757    }
758
759    /**
760     * The default behavior of this method is to return isRequestedSessionIdFromURL()
761     * on the wrapped request object.
762     */
763    @Override
764    public boolean isRequestedSessionIdFromURL() {
765        return this._getHttpServletRequest().isRequestedSessionIdFromURL();
766    }
767
768    /**
769     * The default behavior of this method is to return isRequestedSessionIdFromUrl()
770     * on the wrapped request object.
771     */
772    @Override
773    public boolean isRequestedSessionIdFromUrl() {
774        return this._getHttpServletRequest().isRequestedSessionIdFromUrl();
775    }
776
777    /**
778     * The default behavior of this method is to call authenticate on the
779     * wrapped request object.
780     *
781     * @since Servlet 3.0
782     */
783    @Override
784    public boolean authenticate(HttpServletResponse response)
785            throws IOException, ServletException {
786        return this._getHttpServletRequest().authenticate(response);
787    }
788
789    /**
790     * The default behavior of this method is to call login on the wrapped
791     * request object.
792     *
793     * @since Servlet 3.0
794     */
795    @Override
796    public void login(String username, String password)
797            throws ServletException {
798        this._getHttpServletRequest().login(username,password);
799    }
800
801    /**
802     * The default behavior of this method is to call login on the wrapped
803     * request object.
804     *
805     * @since Servlet 3.0
806     */
807    @Override
808    public void logout() throws ServletException {
809        this._getHttpServletRequest().logout();
810    }
811
812    /**
813     * The default behavior of this method is to call getParts on the wrapped
814     * request object.
815     *
816     * <p>Any changes to the returned <code>Collection</code> must not
817     * affect this <code>HttpServletRequestWrapper</code>.
818     *
819     * @since Servlet 3.0
820     */
821    @Override
822    public Collection<Part> getParts() throws IOException, ServletException {
823        return this._getHttpServletRequest().getParts();
824    }
825
826    /**
827     * The default behavior of this method is to call getPart on the wrapped
828     * request object.
829     *
830     * @since Servlet 3.0
831     */
832    @Override
833    public Part getPart(String name) throws IOException, ServletException {
834        return this._getHttpServletRequest().getPart(name);
835
836    }
837
838    /**
839     * Create an instance of <code>HttpUpgradeHandler</code> for an given
840     * class and uses it for the http protocol upgrade processing.
841     *
842     * @since Servlet 3.1
843     */
844    @Override
845    public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException {
846        return this._getHttpServletRequest().upgrade(handlerClass);
847    }
848}