1   package servletunit;
2   
3   import javax.servlet.RequestDispatcher;
4   import javax.servlet.ServletContext;
5   import javax.servlet.ServletInputStream;
6   import javax.servlet.ServletRequest;
7   import javax.servlet.http.Cookie;
8   import javax.servlet.http.HttpServletRequest;
9   import javax.servlet.http.HttpSession;
10  import java.io.BufferedReader;
11  import java.io.IOException;
12  import java.io.File;
13  import java.security.Principal;
14  import java.util.*;
15  import java.text.SimpleDateFormat;
16  import java.text.DateFormat;
17  import java.text.ParseException;
18  
19  
20  //  StrutsTestCase - a JUnit extension for testing Struts actions
21  //  within the context of the ActionServlet.
22  //  Copyright (C) 2002 Deryl Seale
23  //
24  //  This library is free software; you can redistribute it and/or
25  //  modify it under the terms of the Apache Software License as
26  //  published by the Apache Software Foundation; either version 1.1
27  //  of the License, or (at your option) any later version.
28  //
29  //  This library is distributed in the hope that it will be useful,
30  //  but WITHOUT ANY WARRANTY; without even the implied warranty of
31  //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32  //  Apache Software Foundation Licens for more details.
33  //
34  //  You may view the full text here: http://www.apache.org/LICENSE.txt
35  
36  public class HttpServletRequestSimulator implements HttpServletRequest
37  {
38      private Hashtable attributes;
39      private String scheme;
40      private String protocol = "HTTP/1.1";
41      private String requestURI;
42      private String requestURL;
43      private String contextPath = "";
44      private String servletPath;
45      private String pathInfo;
46      private String queryString;
47      private String method;
48      private String contentType;
49      private Locale locale;
50      private Principal principal;
51      String remoteAddr;
52      String localAddr;
53      String remoteHost;
54      String localName;
55      int remotePort;
56      int localPort;
57      private String remoteUser;
58      private String userRole;
59      private String reqSessionId;
60      String authType;
61      String charEncoding;
62      private String serverName;
63      private int port;
64  
65      private Hashtable parameters;
66      private Hashtable headers;
67      private Vector cookies;
68  
69      private HttpSession session;
70      private ServletContext context;
71  
72      /**
73       * Constant used by {@link #setMethod} to indicate that the GET method
74       * made this request.
75       */
76  
77      public final static int GET = 0;
78  
79      /**
80       * Constant used by {@link #setMethod} to indicate that the POST method
81       * made this request.
82       */
83      public final static int POST = 1;
84  
85      /**
86       * Constant used by {@link #setMethod} to indicate that the PUT method
87       * made this request.
88       */
89      public final static int PUT = 2;
90  
91      public HttpServletRequestSimulator(ServletContext context)
92      {
93          scheme = "http";
94          attributes = new Hashtable();
95          parameters = new Hashtable();
96          headers = new Hashtable();
97          cookies = new Vector();
98          this.context = context;
99          //if (getHeader("Accept")==null)
100         //setHeader("Accept","dummy accept");
101     }
102 
103     /**
104      * Adds a parameter to this object's list of parameters
105      *
106      * @param   key     The name of the parameter
107      * @param   value   The value of the parameter
108      */
109     public void addParameter( String key, String value )
110     {
111         if ((key != null) && (value != null))
112             this.parameters.put( key, value );
113     }
114 
115     /**
116      * Adds a parameter as a String array to this object's list of parameters
117      */
118     public void addParameter(String name, String[] values) {
119         if ((name != null) && (values != null))
120             parameters.put(name,values);
121     }
122 
123     /**
124      * Returns a java.util.Map of the parameters of this request.
125      * Request parameters
126      * are extra information sent with the request.  For HTTP servlets,
127      * parameters are contained in the query string or posted form data.
128      *
129      * @return an immutable java.util.Map containing parameter names as
130      * keys and parameter values as map values. The keys in the parameter
131      * map are of type String. The values in the parameter map are of type
132      * String array.
133      *
134      */
135     public Map getParameterMap() {
136         return this.parameters;
137     }
138 
139     /**
140      *
141      * Returns the value of the named attribute as an <code>Object</code>,
142      * or <code>null</code> if no attribute of the given name exists.
143      *
144      * <p> Attributes can be set two ways.  The servlet container may set
145      * attributes to make available custom information about a request.
146      * For example, for requests made using HTTPS, the attribute
147      * <code>javax.servlet.request.X509Certificate</code> can be used to
148      * retrieve information on the certificate of the client.  Attributes
149      * can also be set programatically using
150      * {@link ServletRequest#setAttribute}.  This allows information to be
151      * embedded into a request before a {@link RequestDispatcher} call.
152      *
153      * <p>Attribute names should follow the same conventions as package
154      * names. This specification reserves names matching <code>java.*</code>,
155      * <code>javax.*</code>, and <code>sun.*</code>.
156      *
157      * @param s a <code>String</code> specifying the name of
158      *          the attribute
159      *
160      * @return      an <code>Object</code> containing the value
161      *          of the attribute, or <code>null</code> if
162      *          the attribute does not exist
163      *
164      */
165     public Object getAttribute(String s)
166     {
167         return attributes.get(s);
168     }
169 
170     /**
171      * Returns an <code>Enumeration</code> containing the
172      * names of the attributes available to this request.
173      * This method returns an empty <code>Enumeration</code>
174      * if the request has no attributes available to it.
175      *
176      *
177      * @return      an <code>Enumeration</code> of strings
178      *          containing the names
179      *          of the request's attributes
180      *
181      */
182     public Enumeration getAttributeNames()
183     {
184         return attributes.keys();
185     }
186 
187     /**
188      * Returns the name of the authentication scheme used to protect
189      * the servlet. All servlet containers support basic, form and client
190      * certificate authentication, and may additionally support digest
191      * authentication.
192      * If the servlet is not authenticated <code>null</code> is returned.
193      *
194      * <p>Same as the value of the CGI variable AUTH_TYPE.
195      *
196      *
197      * @return      one of the static members BASIC_AUTH,
198      *          FORM_AUTH, CLIENT_CERT_AUTH, DIGEST_AUTH
199      *          (suitable for == comparison)
200      *          indicating the authentication scheme, or
201      *          <code>null</code> if the request was
202      *          not authenticated.
203      *
204      */
205     public String getAuthType()
206     {
207         return authType;
208     }
209 
210     /**
211      * Returns the name of the character encoding used in the body of this
212      * request. This method returns <code>null</code> if the request
213      * does not specify a character encoding
214      *
215      *
216      * @return      a <code>String</code> containing the name of
217      *          the chararacter encoding, or <code>null</code>
218      *          if the request does not specify a character encoding
219      */
220     public String getCharacterEncoding()
221     {
222         return charEncoding;
223     }
224 
225     /**
226      * Returns the length, in bytes, of the request body
227      * and made available by the input stream, or -1 if the
228      * length is not known. For HTTP servlets, same as the value
229      * of the CGI variable CONTENT_LENGTH.
230      *
231      * @return      -1, since this is a mock container
232      */
233     public int getContentLength()
234     {
235         return -1;
236     }
237 
238     /**
239      * Returns the MIME type of the body of the request, or
240      * <code>null</code> if the type is not known. For HTTP servlets,
241      * same as the value of the CGI variable CONTENT_TYPE.
242      *
243      * @return      a <code>String</code> containing the name
244      *          of the MIME type of
245      *          the request, or null if the type is not known
246      *
247      */
248     public String getContentType()
249     {
250         return contentType;
251     }
252 
253     /**
254      *
255      * Returns the portion of the request URI that indicates the context
256      * of the request.  The context path always comes first in a request
257      * URI.  The path starts with a "/" character but does not end with a "/"
258      * character.  For servlets in the default (root) context, this method
259      * returns "". The container does not decode this string.
260      *
261      *
262      * @return      a <code>String</code> specifying the
263      *          portion of the request URI that indicates the context
264      *          of the request
265      *
266      *
267      */
268     public String getContextPath()
269     {
270         return contextPath;
271     }
272 
273     /**
274      * Adds a cookie that can be retrieved from this request via the
275      * getCookies() method.
276      *
277      * @param cookie a Cookie object to be retrieved from this
278      * request.
279      *
280      * @see #getCookies
281      */
282     public void addCookie(Cookie cookie) {
283         cookies.addElement(cookie);
284     }
285 
286     /**
287      * Adds a set of cookies that can be retrieved from this request via the
288      * getCookies() method.
289      *
290      * @param cookies an array of Cookie object to be retrieved from this
291      * request.
292      *
293      * @see #getCookies
294      */
295     public void setCookies(Cookie[] cookies) {
296         for (int i = 0; i < cookies.length; i++)
297             this.cookies.addElement(cookies[i]);
298     }
299 
300     /**
301      *
302      * Returns an array containing all of the <code>Cookie</code>
303      * objects the client sent with this request.
304      * This method returns <code>null</code> if no cookies were sent.
305      *
306      * @return      an array of all the <code>Cookies</code>
307      *          included with this request, or <code>null</code>
308      *          if the request has no cookies
309      *
310      *
311      */
312     public Cookie [] getCookies()
313     {
314         if (cookies.isEmpty())
315             return null;
316         else {
317             Cookie[] cookieArray = new Cookie[cookies.size()];
318             return (Cookie []) cookies.toArray(cookieArray);
319         }
320     }
321 
322     /**
323      * Returns the value of the specified request header as a long value that represents a Date object. Use this
324      * method with headers that contain dates, such as If-Modified-Since.
325      * <br><br>
326      * The date is returned as the number of milliseconds since January 1, 1970 GMT. The header name is case insensitive.
327      * <br><br>
328      * If the request did not have a header of the specified name, this method returns -1. If the header can't be converted to a date, the method throws an IllegalArgumentException.
329      * @param name a String specifying the name of the header
330      * @return a <code>long</code> value representing the date specified in the header expressed as the number of milliseconds since January 1, 1970 GMT, or -1 if the named header was not included with the reqest.
331      */
332     public long getDateHeader(String name)
333     {
334         String s1 = getHeader(name);
335         if(s1 == null)
336             return -1L;
337         try
338         {
339             DateFormat dateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z");
340             return dateFormat.parse(s1).getTime();
341         }
342         catch(ParseException exception) {
343             throw new IllegalArgumentException("Cannot parse date: " + s1);
344         }
345     }
346 
347     /**
348      * Sets a header with the appropriate date string given the time in milliseconds.
349      * @param name the name of the header
350      * @param millis the time in milliseconds
351      */
352     public void setDateHeader(String name, long millis)
353     {
354         String dateString = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z").format(new Date(millis));
355         setHeader(name, dateString);
356     }
357 
358     /**
359      *
360      * Returns the value of the specified request header
361      * as a <code>String</code>. If the request did not include a header
362      * of the specified name, this method returns <code>null</code>.
363      * The header name is case insensitive. You can use
364      * this method with any request header.
365      *
366      * @param s     a <code>String</code> specifying the
367      *              header name
368      *
369      * @return          a <code>String</code> containing the
370      *              value of the requested
371      *              header, or <code>null</code>
372      *              if the request does not
373      *              have a header of that name
374      *
375      */
376     public String getHeader(String s)
377     {
378         return (String) headers.get(s);
379     }
380 
381     /**
382      *
383      * Returns an enumeration of all the header names
384      * this request contains. If the request has no
385      * headers, this method returns an empty enumeration.
386      *
387      * <p>Some servlet containers do not allow do not allow
388      * servlets to access headers using this method, in
389      * which case this method returns <code>null</code>
390      *
391      * @return          an enumeration of all the
392      *              header names sent with this
393      *              request; if the request has
394      *              no headers, an empty enumeration;
395      *              if the servlet container does not
396      *              allow servlets to use this method,
397      *              <code>null</code>
398      *
399      *
400      */
401     public Enumeration getHeaderNames()
402     {
403         return headers.keys();
404     }
405 
406     /**
407      * This operation is not supported.
408      */
409     public Enumeration getHeaders(String s)
410     {
411         throw new UnsupportedOperationException("getHeaders operation is not supported!");
412     }
413 
414     /**
415      * This operation is not supported.
416      */
417     public ServletInputStream getInputStream() throws IOException {
418         throw new UnsupportedOperationException("getInputStream operation is not supported!");
419     }
420 
421     /**
422      *
423      * Returns the value of the specified request header
424      * as an <code>int</code>. If the request does not have a header
425      * of the specified name, this method returns -1. If the
426      * header cannot be converted to an integer, this method
427      * throws a <code>NumberFormatException</code>.
428      *
429      * <p>The header name is case insensitive.
430      *
431      * @param s     a <code>String</code> specifying the name
432      *              of a request header
433      *
434      * @return          an integer expressing the value
435      *              of the request header or -1
436      *              if the request doesn't have a
437      *              header of this name
438      *
439      * @exception   NumberFormatException       If the header value
440      *                          can't be converted
441      *                          to an <code>int</code>
442      */
443     public int getIntHeader(String s)
444     {
445         Object header = headers.get(s);
446         if (header != null) {
447             try {
448                 Integer intHeader = (Integer) header;
449                 return intHeader.intValue();
450             } catch (ClassCastException e) {
451                 throw new NumberFormatException("header '" + s + "' cannot be converted to number format.");
452             }
453         } else
454             return -1;
455     }
456 
457     /**
458      *
459      * Returns the preferred <code>Locale</code> that the client will
460      * accept content in, based on the Accept-Language header.
461      * If the client request doesn't provide an Accept-Language header,
462      * this method returns the default locale for the server.
463      *
464      *
465      * @return      the preferred <code>Locale</code> for the client,
466      *                  defaults to Locale.US if {@link #setLocale} has
467      *                  not been called.
468      *
469      */
470     public  Locale getLocale()
471     {
472         if (this.locale == null)
473             return Locale.US;
474         else
475             return this.locale;
476     }
477 
478     /**
479      * Returns an Enumeration of Locale objects indicating, in decreasing order starting with the preferred locale, the locales that are acceptable to the client based on the Accept-Language header. If the client request doesn't provide an Accept-Language header, this method returns an Enumeration containing one Locale, the default locale for the server.
480      * @return an <code>Enumeration</code> of preferred Locale objects for the client
481      */
482 
483 
484 
485     public Enumeration getLocales()
486     {
487         return java.util.Collections.enumeration(Collections.singleton(getLocale()));
488     }
489 
490     /**
491      *
492      * Returns the name of the HTTP method with which this
493      * request was made, for example, GET, POST, or PUT.
494      * Same as the value of the CGI variable REQUEST_METHOD.
495      *
496      * @return          a <code>String</code>
497      *              specifying the name
498      *              of the method with which
499      *              this request was made
500      *
501      */
502     public String getMethod()
503     {
504         if (method == null)
505             return "POST";
506         else
507             return method;
508     }
509 
510     /**
511      * Returns the value of a request parameter as a <code>String</code>,
512      * or <code>null</code> if the parameter does not exist. Request parameters
513      * are extra information sent with the request.  For HTTP servlets,
514      * parameters are contained in the query string or posted form data.
515      *
516      * <p>You should only use this method when you are sure the
517      * parameter has only one value. If the parameter might have
518      * more than one value, use {@link #getParameterValues}.
519      *
520      * <p>If you use this method with a multivalued
521      * parameter, the value returned is equal to the first value
522      * in the array returned by <code>getParameterValues</code>.
523      *
524      * <p>If the parameter data was sent in the request body, such as occurs
525      * with an HTTP POST request, then reading the body directly via {@link
526      * #getInputStream} or {@link #getReader} can interfere
527      * with the execution of this method.
528      *
529      * @param s     a <code>String</code> specifying the
530      *          name of the parameter
531      *
532      * @return      a <code>String</code> representing the
533      *          single value of the parameter
534      *
535      * @see         #getParameterValues
536      *
537      */
538     public String getParameter( String s )
539     {
540         if (s == null)
541             return null;
542 
543         Object param = parameters.get(s);
544         if( null == param )
545             return null;
546         if( param.getClass().isArray() )
547             return ((String[]) param)[0];
548         return (String)param;
549     }
550 
551     /**
552      *
553      * Returns an <code>Enumeration</code> of <code>String</code>
554      * objects containing the names of the parameters contained
555      * in this request. If the request has
556      * no parameters, the method returns an
557      * empty <code>Enumeration</code>.
558      *
559      * @return      an <code>Enumeration</code> of <code>String</code>
560      *          objects, each <code>String</code> containing
561      *          the name of a request parameter; or an
562      *          empty <code>Enumeration</code> if the
563      *          request has no parameters
564      *
565      */
566     public Enumeration getParameterNames()
567     {
568         return parameters.keys();
569     }
570 
571     /**
572      * Returns an array of <code>String</code> objects containing
573      * all of the values the given request parameter has, or
574      * <code>null</code> if the parameter does not exist.
575      *
576      * <p>If the parameter has a single value, the array has a length
577      * of 1.
578      *
579      * @param s a <code>String</code> containing the name of
580      *          the parameter whose value is requested
581      *
582      * @return      an array of <code>String</code> objects
583      *          containing the parameter's values
584      *
585      * @see     #getParameter
586      *
587      */
588     public String[] getParameterValues( String s )
589     {
590         if (s == null)
591             return null;
592         Object param = parameters.get( s );
593         if( null == param )
594             return null;
595         else {
596             if (param.getClass().isArray()) {
597                 return (String[]) param;
598             } else {
599                 return new String[] {(String) param};
600             }
601         }
602     }
603 
604     /**
605      *
606      * Returns any extra path information associated with
607      * the URL the client sent when it made this request.
608      * The extra path information follows the servlet path
609      * but precedes the query string.
610      * This method returns <code>null</code> if there
611      * was no extra path information.
612      *
613      * <p>Same as the value of the CGI variable PATH_INFO.
614      *
615      *
616      * @return      a <code>String</code>, decoded by the
617      *          web container, specifying
618      *          extra path information that comes
619      *          after the servlet path but before
620      *          the query string in the request URL;
621      *          or <code>null</code> if the URL does not have
622      *          any extra path information
623      *
624      */
625     public String getPathInfo()
626     {
627         return pathInfo;
628     }
629 
630     /**
631      * This operation is not supported.
632      */
633     public String getPathTranslated()
634     {
635         throw new UnsupportedOperationException("getPathTranslated operation is not supported!");
636     }
637 
638     /**
639      * Returns the name and version of the protocol the request uses
640      * in the form <i>protocol/majorVersion.minorVersion</i>, for
641      * example, HTTP/1.1. For HTTP servlets, the value
642      * returned is the same as the value of the CGI variable
643      * <code>SERVER_PROTOCOL</code>.
644      *
645      * @return      a <code>String</code> containing the protocol
646      *          name and version number
647      *
648      */
649     public String getProtocol()
650     {
651         return protocol;
652     }
653 
654     /**
655      *
656      * Returns the query string that is contained in the request
657      * URL after the path. This method returns <code>null</code>
658      * if the URL does not have a query string. Same as the value
659      * of the CGI variable QUERY_STRING.
660      *
661      * @return      a <code>String</code> containing the query
662      *          string or <code>null</code> if the URL
663      *          contains no query string. The value is not
664      *          decoded by the container.
665      *
666      */
667     public String getQueryString()
668     {
669         return queryString;
670     }
671 
672     /**
673      * This operation is not supported.
674      */
675     public BufferedReader getReader() throws IOException {
676         throw new UnsupportedOperationException("getReader operation is not supported!");
677     }
678 
679     /**
680      *
681      * @deprecated  As of Version 2.1 of the Java Servlet API,
682      *          use {@link ServletContext#getRealPath} instead.
683      *
684      */
685     public String getRealPath(String path)
686     {
687         File contextDirectory = ((ServletContextSimulator) context).getContextDirectory();
688         if ((contextDirectory == null) || (path == null))
689             return null;
690         else
691             return (new File(contextDirectory, path)).getAbsolutePath();
692     }
693 
694     /**
695      * Returns the Internet Protocol (IP) address of the client
696      * that sent the request.  For HTTP servlets, same as the value of the
697      * CGI variable <code>REMOTE_ADDR</code>.
698      *
699      * @return      a <code>String</code> containing the
700      *          IP address of the client that sent the request
701      *
702      */
703     public String getRemoteAddr() {
704         return remoteAddr;
705     }
706 
707     /**
708      * Returns the fully qualified name of the client that sent the
709      * request. If the engine cannot or chooses not to resolve the hostname
710      * (to improve performance), this method returns the dotted-string form of
711      * the IP address. For HTTP servlets, same as the value of the CGI variable
712      * <code>REMOTE_HOST</code>.
713      *
714      * @return      a <code>String</code> containing the fully
715      * qualified name of the client
716      *
717      */
718     public String getRemoteHost() {
719         return remoteHost;
720     }
721 
722     /**
723      * Returns the fully qualified name of the client that sent the
724      * request. If the engine cannot or chooses not to resolve the hostname
725      * (to improve performance), this method returns the dotted-string form of
726      * the IP address. For HTTP servlets, same as the value of the CGI variable
727      * <code>REMOTE_HOST</code>.
728      *
729      * @return      a <code>String</code> containing the fully
730      * qualified name of the client
731      *
732      */
733     public String getRemoteUser()
734     {
735         return remoteUser;
736     }
737 
738     /**
739      *
740      * Returns a {@link RequestDispatcher} object that acts as a wrapper for
741      * the resource located at the given path.
742      * A <code>RequestDispatcher</code> object can be used to forward
743      * a request to the resource or to include the resource in a response.
744      * The resource can be dynamic or static.
745      *
746      * <p>The pathname specified may be relative, although it cannot extend
747      * outside the current servlet context.  If the path begins with
748      * a "/" it is interpreted as relative to the current context root.
749      * This method returns <code>null</code> if the servlet container
750      * cannot return a <code>RequestDispatcher</code>.
751      *
752      * <p>The difference between this method and {@link
753      * ServletContext#getRequestDispatcher} is that this method can take a
754      * relative path.
755      *
756      * @param url      a <code>String</code> specifying the pathname
757      *                  to the resource
758      *
759      * @return          a <code>RequestDispatcher</code> object
760      *                  that acts as a wrapper for the resource
761      *                  at the specified path
762      *
763      * @see             RequestDispatcherSimulator
764      * @see             ServletContextSimulator#getRequestDispatcher
765      *
766      */
767     public  RequestDispatcher getRequestDispatcher( String url )
768     {
769         return context.getRequestDispatcher(url);
770     }
771 
772     /**
773      *
774      * Returns the session ID specified by the client. This may
775      * not be the same as the ID of the actual session in use.
776      * For example, if the request specified an old (expired)
777      * session ID and the server has started a new session, this
778      * method gets a new session with a new ID. If the request
779      * did not specify a session ID, this method returns
780      * <code>null</code>.
781      *
782      *
783      * @return      a <code>String</code> specifying the session
784      *          ID, or <code>null</code> if the request did
785      *          not specify a session ID
786      *
787      * @see     #isRequestedSessionIdValid
788      *
789      */
790     public String getRequestedSessionId()
791     {
792         return reqSessionId;
793     }
794 
795     /**
796      *
797      * Returns the part of this request's URL from the protocol
798      * name up to the query string in the first line of the HTTP request.
799      * The web container does not decode this String.
800      * For example:
801      *
802      *
803      * <table>
804      * <tr align=left><th>First line of HTTP request      </th>
805      * <th>     Returned Value</th>
806      * <tr><td>POST /some/path.html HTTP/1.1<td><td>/some/path.html
807      * <tr><td>GET http://foo.bar/a.html HTTP/1.0
808      * <td><td>/a.html
809      * <tr><td>HEAD /xyz?a=b HTTP/1.1<td><td>/xyz
810      * </table>
811      *
812      *
813      * @return      a <code>String</code> containing
814      *          the part of the URL from the
815      *          protocol name up to the query string
816      *
817      *
818      */
819     public String getRequestURI()
820     {
821         return requestURI;
822     }
823 
824 
825     /**
826      * Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port number, and server path, but it does not include query string parameters.
827      * <br><br>
828      * Because this method returns a StringBuffer, not a string, you can modify the URL easily, for example, to append query parameters.
829      * <br><br>
830      * This method is useful for creating redirect messages and for reporting errors.
831      * @return a <code>StringBuffer</code> object containing the reconstructed URL
832      */
833 
834     public StringBuffer getRequestURL()
835     {
836         return new StringBuffer(requestURL);
837     }
838 
839     /**
840      * Returns the name of the scheme used to make this request,
841      * for example,
842      * <code>http</code>, <code>https</code>, or <code>ftp</code>.
843      * Different schemes have different rules for constructing URLs,
844      * as noted in RFC 1738.
845      *
846      * @return      a <code>String</code> containing the name
847      *          of the scheme used to make this request
848      *
849      */
850     public String getScheme()
851     {
852         return scheme;
853     }
854 
855     /**
856      *     Returns the host name of the server that received
857      *     the request. For HTTP servlets, same as the value of
858      *     the CGI variable SERVER_NAME.
859      *     @return the name of the server to which the request was sent
860      */
861     public String getServerName() {
862         return serverName;
863     }
864 
865     /**
866      * Returns the port number on which this request was received. For HTTP servlets, same as the value of the CGI variable SERVER_PORT.
867      * @return an integer specifying the port number
868      */
869     public int getServerPort() {
870         return this.port;
871     }
872 
873     /**
874      * Sets the server port to be used with {@link#getServerPort}.
875      */
876     public void setServerPort(int port) {
877         this.port = port;
878     }
879 
880     /**
881      *
882      * Returns the part of this request's URL that calls
883      * the servlet. This includes either the servlet name or
884      * a path to the servlet, but does not include any extra
885      * path information or a query string. Same as the value
886      * of the CGI variable SCRIPT_NAME.
887      *
888      *
889      * @return      a <code>String</code> containing
890      *          the name or path of the servlet being
891      *          called, as specified in the request URL,
892      *          decoded.
893      *
894      *
895      */
896     public String getServletPath()
897     {
898         return servletPath;
899     }
900 
901     /**
902      *
903      * Returns the current session associated with this request,
904      * or if the request does not have a session, creates one.
905      *
906      * @return      the <code>HttpSession</code> associated
907      *          with this request
908      *
909      * @see #getSession(boolean)
910      *
911      */
912     public HttpSession getSession()
913     {
914         return getSession(true);
915     }
916 
917     /**
918      *
919      * Returns the current <code>HttpSession</code>
920      * associated with this request or, if if there is no
921      * current session and <code>create</code> is true, returns
922      * a new session.
923      *
924      * <p>If <code>create</code> is <code>false</code>
925      * and the request has no valid <code>HttpSession</code>,
926      * this method returns <code>null</code>.
927      *
928      * <p>To make sure the session is properly maintained,
929      * you must call this method before
930      * the response is committed. If the container is using cookies
931      * to maintain session integrity and is asked to create a new session
932      * when the response is committed, an IllegalStateException is thrown.
933      *
934      *
935      *
936      *
937      * @param b <code>true</code> to create
938      *          a new session for this request if necessary;
939      *          <code>false</code> to return <code>null</code>
940      *          if there's no current session
941      *
942      *
943      * @return      the <code>HttpSession</code> associated
944      *          with this request or <code>null</code> if
945      *          <code>create</code> is <code>false</code>
946      *          and the request has no valid session
947      *
948      * @see #getSession()
949      *
950      *
951      */
952     public HttpSession getSession(boolean b)
953     {
954         if ((session == null) && (b))
955             this.session = new HttpSessionSimulator(context);
956         else if ((session != null) && (!((HttpSessionSimulator) session).isValid()) && (b))
957             this.session = new HttpSessionSimulator(context);
958         if ((session != null) && (((HttpSessionSimulator) session).isValid()))
959             return this.session;
960         else
961             return null;
962     }
963 
964     /**
965      *
966      * Returns a <code>java.security.Principal</code> object containing
967      * the name of the current authenticated user. If the user has not been
968      * authenticated, the method returns <code>null</code>.
969      *
970      * @return      a <code>java.security.Principal</code> containing
971      *          the name of the user making this request;
972      *          <code>null</code> if the user has not been
973      *          authenticated
974      *
975      */
976     public Principal getUserPrincipal()
977     {
978         return this.principal;
979     }
980 
981     /**
982      *
983      * Checks whether the requested session ID came in as a cookie.
984      *
985      * @return          <code>true</code> in all cases
986      *
987      * @see         #getSession
988      *
989      */
990     public boolean isRequestedSessionIdFromCookie()
991     {
992         return true;
993     }
994 
995     /**
996      *
997      * @deprecated      As of Version 2.1 of the Java Servlet
998      *              API, use {@link #isRequestedSessionIdFromURL}
999      *              instead.
1000      *
1001      */
1002     public boolean isRequestedSessionIdFromUrl()
1003     {
1004         return isRequestedSessionIdFromURL();
1005     }
1006 
1007     /**
1008      *
1009      * Checks whether the requested session ID came in as part of the
1010      * request URL.
1011      *
1012      * @return          <code>false</code> in all cases.
1013      *
1014      * @see         #getSession
1015      *
1016      */
1017     public boolean isRequestedSessionIdFromURL()
1018     {
1019         return false;
1020     }
1021 
1022     /**
1023      *
1024      * Checks whether the requested session ID is still valid.
1025      *
1026      * @return          <code>true</code> if this
1027      *              request has an id for a valid session
1028      *              in the current session context;
1029      *              <code>false</code> otherwise
1030      *
1031      * @see         #getRequestedSessionId
1032      * @see         #getSession
1033      *
1034      */
1035     public boolean isRequestedSessionIdValid()
1036     {
1037         if (session != null) {
1038             try {
1039                 session.getId();
1040                 return true;
1041             } catch (IllegalStateException e) {
1042                 return false;
1043             }
1044         } else
1045             return false;
1046     }
1047 
1048     /**
1049      *
1050      * Returns a boolean indicating whether this request was made using a
1051      * secure channel, such as HTTPS.
1052      *
1053      *
1054      * @return true if scheme has been set to HTTPS (ignoring case)
1055      *
1056      */
1057     public boolean isSecure()
1058     {
1059         if(scheme==null){
1060             return false;
1061         } else{
1062             return scheme.equalsIgnoreCase("HTTPS");
1063         }
1064     }
1065 
1066     /**
1067      *
1068      * Returns a boolean indicating whether the authenticated user is included
1069      * in the specified logical "role".  Roles and role membership can be
1070      * defined using deployment descriptors.  If the user has not been
1071      * authenticated, the method returns <code>false</code>.
1072      *
1073      * @param s     a <code>String</code> specifying the name
1074      *              of the role
1075      *
1076      * @return      <code>false</code> in all cases
1077      *
1078      */
1079     public boolean isUserInRole(String s)
1080     {
1081         return s.equals(userRole);
1082     }
1083 
1084     /**
1085      * Sets user role to be used in {@link #isUserInRole}
1086      */
1087     public void setUserRole(String role) {
1088         this.userRole = role;
1089     }
1090 
1091     /**
1092      *
1093      * Removes an attribute from this request.  This method is not
1094      * generally needed as attributes only persist as long as the request
1095      * is being handled.
1096      *
1097      * <p>Attribute names should follow the same conventions as
1098      * package names. Names beginning with <code>java.*</code>,
1099      * <code>javax.*</code>, and <code>com.sun.*</code>, are
1100      * reserved for use by Sun Microsystems.
1101      *
1102      *
1103      * @param s         a <code>String</code> specifying
1104      *                  the name of the attribute to remove
1105      *
1106      */
1107     public void removeAttribute(String s)
1108     {
1109         attributes.remove(s);
1110     }
1111 
1112     /**
1113      *
1114      * Stores an attribute in this request.
1115      * Attributes are reset between requests.  This method is most
1116      * often used in conjunction with {@link RequestDispatcher}.
1117      *
1118      * <p>Attribute names should follow the same conventions as
1119      * package names. Names beginning with <code>java.*</code>,
1120      * <code>javax.*</code>, and <code>com.sun.*</code>, are
1121      * reserved for use by Sun Microsystems.
1122      *<br> If the value passed in is null, the effect is the same as
1123      * calling {@link #removeAttribute}.
1124      *
1125      *
1126      *
1127      * @param name          a <code>String</code> specifying
1128      *                  the name of the attribute
1129      *
1130      * @param o             the <code>Object</code> to be stored
1131      *
1132      */
1133     public void setAttribute(String name, Object o)
1134     {
1135         if (o == null)
1136             attributes.remove(name);
1137         else
1138             attributes.put(name, o);
1139     }
1140 
1141 
1142     /**
1143      * Sets authentication scheme to be used in {@link #getAuthType}.
1144      */
1145     public void setAuthType(String s)
1146     {
1147         authType = s;
1148     }
1149 
1150     /**
1151      * Sets character encoding to be used in {@link #getCharacterEncoding}.
1152      */
1153     public void setCharacterEncoding(String s)
1154     {
1155         charEncoding = s;
1156     }
1157 
1158     /**
1159      * Sets content type to be used in {@link #getContentType}.
1160      */
1161     public void setContentType(String s) {
1162         contentType = s;
1163     }
1164 
1165     /**
1166      * Sets a header to be used in {@link #getHeader}.
1167      */
1168     public void setHeader(String key, String value)
1169     {
1170         headers.put(key,value);
1171     }
1172 
1173     /**
1174      * Sets the name of the HTTP method with which this request
1175      * was made.  This value will be returned in the getMethod
1176      * method.
1177      *
1178      *
1179      * @param methodType one of the following constant values
1180      * defined in this class: {@link #GET}, {@link #POST}, and {@link #PUT}
1181      *
1182      */
1183     public void setMethod(int methodType)
1184     {
1185         switch (methodType)
1186         {
1187             case GET:method="GET";break;
1188             case PUT:method="PUT";break;
1189             case POST:method="POST";break;
1190             default:method="POST";
1191         }
1192     }
1193 
1194     /**
1195      * Sets parameter value to be used by {@link #getParameter}.
1196      */
1197     public void setParameterValue( String key, String[] value )
1198     {
1199         parameters.put( key, value );
1200     }
1201 
1202     /**
1203      * Sets path information to be used by {@link #getPathInfo}.
1204      */
1205     public void setPathInfo(String s)
1206     {
1207         pathInfo = s;
1208     }
1209 
1210     /**
1211      * Sets query string to be used by {@link #getQueryString}.
1212      */
1213     public void setQueryString(String s) {
1214         this.queryString = s;
1215     }
1216 
1217     /**
1218      * Sets remote user to be used by {@link #getRemoteUser}.
1219      */
1220     public void setRemoteUser(String remoteUser)
1221     {
1222         this.remoteUser = remoteUser;
1223     }
1224 
1225     /**
1226      * Sets remote address to be used by {@link #getRemoteAddr}.
1227      */
1228     public void setRemoteAddr(String remoteAddr) {
1229         this.remoteAddr = remoteAddr;
1230     }
1231 
1232     /**
1233      * Sets remote host to be used by {@link #getRemoteHost}.
1234      */
1235     public void setRemoteHost(String remoteHost) {
1236         this.remoteHost = remoteHost;
1237     }
1238 
1239     /**
1240      * Sets requested session ID to be used by {@link #getRequestedSessionId}.
1241      */
1242     public void setRequestedSessionId(String s)
1243     {
1244         reqSessionId = s;
1245     }
1246 
1247     /**
1248      * Sets request URI to be used by {@link #getRequestURI}.
1249      */
1250     public void setRequestURI(String requestURI)
1251     {
1252         this.requestURI = requestURI;
1253     }
1254 
1255     /**
1256      * Sets the request URL to be used in this test.  This method uses
1257      * the given request URL to also set the scheme, server name, server
1258      * port, request URI, and query string.
1259      */
1260     public void setRequestURL(String url) {
1261 
1262         // set request url
1263         int queryIndex = url.lastIndexOf('?');
1264         if (queryIndex < 0)
1265             queryIndex = url.length();
1266         this.requestURL = url.substring(0,queryIndex);
1267 
1268         // set query string
1269         if (queryIndex != url.length())
1270             setQueryString(url.substring(queryIndex + 1));
1271 
1272         // set scheme
1273         int schemeIndex = url.lastIndexOf("://");
1274         setScheme(url.substring(0,schemeIndex));
1275 
1276         // set uri
1277         setRequestURI(url.substring(url.indexOf('/',schemeIndex + 3),queryIndex));
1278 
1279         // set server name and port
1280         int portIndex = url.indexOf(':',schemeIndex + 2);
1281         if (portIndex > 0) {
1282             setServerName(url.substring(schemeIndex + 3, portIndex));
1283             setServerPort(Integer.parseInt(url.substring(portIndex + 1,url.indexOf('/',schemeIndex + 3))));
1284         } else {
1285             setServerName(url.substring(schemeIndex + 3,url.indexOf('/',schemeIndex + 3)));
1286             if (isSecure())
1287                 setServerPort(443);
1288             else
1289                 setServerPort(80);
1290         }
1291     }
1292 
1293     /**
1294      * Sets scheme to be used by {@link #getScheme}.
1295      */
1296     public void setScheme(String s)
1297     {
1298         scheme = s;
1299     }
1300 
1301     /**
1302      * Sets servlet path to be used by {@link #getServletPath}.
1303      */
1304     public void setServletPath(String s)
1305     {
1306         servletPath = s;
1307     }
1308 
1309     /**
1310      * Sets server name to be used by {@link #getServerName}.
1311      */
1312     public void setServerName(String s)
1313     {
1314         serverName = s;
1315     }
1316 
1317     /**
1318      * Sets the context path to be used by {@link #getContextPath}.
1319      */
1320     public void setContextPath(String s)
1321     {
1322         contextPath = s;
1323     }
1324 
1325 
1326     /**
1327      * Sets the locale to be used by {@link #getLocale}.
1328      */
1329     public void setLocale(Locale locale) {
1330         this.locale = locale;
1331     }
1332 
1333     /**
1334      * Sets the Principal used by {@link #getUserPrincipal}.
1335      */
1336     public void setUserPrincipal(Principal principal) {
1337         this.principal = principal;
1338     }
1339 
1340     public int getRemotePort() {
1341         return remotePort;
1342     }
1343 
1344     public void setRemotePort(int remotePort) {
1345         this.remotePort = remotePort;
1346     }
1347 
1348     public String getLocalAddr() {
1349         return localAddr;
1350     }
1351 
1352     public void setLocalAddr(String localAddr) {
1353         this.localAddr = localAddr;
1354     }
1355 
1356     public String getLocalName() {
1357         return localName;
1358     }
1359 
1360     public void setLocalName(String localName) {
1361         this.localName = localName;
1362     }
1363 
1364     public int getLocalPort() {
1365         return localPort;
1366     }
1367 
1368     public void setLocalPort(int localPort) {
1369         this.localPort = localPort;
1370     }
1371 
1372 
1373 }