View Javadoc

1   // ========================================================================
2   // Copyright 2004-2008 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // Licensed under the Apache License, Version 2.0 (the "License");
5   // you may not use this file except in compliance with the License.
6   // You may obtain a copy of the License at 
7   // http://www.apache.org/licenses/LICENSE-2.0
8   // Unless required by applicable law or agreed to in writing, software
9   // distributed under the License is distributed on an "AS IS" BASIS,
10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  // See the License for the specific language governing permissions and
12  // limitations under the License.
13  // ========================================================================
14  package org.mortbay.jetty.testing;
15  
16  import java.io.IOException;
17  import java.net.Inet4Address;
18  import java.net.InetAddress;
19  import java.net.URL;
20  import java.util.Enumeration;
21  import java.util.EventListener;
22  
23  import org.mortbay.io.ByteArrayBuffer;
24  import org.mortbay.jetty.LocalConnector;
25  import org.mortbay.jetty.Server;
26  import org.mortbay.jetty.bio.SocketConnector;
27  import org.mortbay.jetty.nio.SelectChannelConnector;
28  import org.mortbay.jetty.servlet.Context;
29  import org.mortbay.jetty.servlet.FilterHolder;
30  import org.mortbay.jetty.servlet.ServletHolder;
31  import org.mortbay.util.Attributes;
32  
33  
34  
35  /* ------------------------------------------------------------ */
36  /** Testing support for servlets and filters.
37   * 
38   * Allows a programatic setup of a context with servlets and filters for 
39   * testing.  Raw HTTP requests may be sent to the context and responses received.
40   * To avoid handling raw HTTP see {@link org.mortbay.jetty.testing.HttpTester}.
41   * <pre>
42   *      ServletTester tester=new ServletTester();
43   *      tester.setContextPath("/context");
44   *      tester.addServlet(TestServlet.class, "/servlet/*");
45   *      tester.addServlet("org.mortbay.jetty.servlet.DefaultServlet", "/");
46   *      tester.start();
47   *      String response = tester.getResponses("GET /context/servlet/info HTTP/1.0\r\n\r\n");
48   * </pre>
49   * 
50   * @see org.mortbay.jetty.testing.HttpTester
51   * @author gregw
52   *
53   */
54  public class ServletTester
55  {
56      Server _server = new Server();
57      LocalConnector _connector = new LocalConnector();
58      Context _context = new Context(Context.SESSIONS|Context.SECURITY);
59      int _maxIdleTime = -1;
60  
61      public ServletTester()
62      {
63          try
64          {
65              _server.setSendServerVersion(false);
66              _server.addConnector(_connector);
67              _server.addHandler(_context);
68          }
69          catch (Error e)
70          {
71              throw e;
72          }
73          catch (RuntimeException e)
74          {
75              throw e;
76          }
77          catch (Exception e)
78          {
79              throw new RuntimeException(e);
80          }
81      }
82  
83      /* ------------------------------------------------------------ */
84      public void start() throws Exception
85      {
86          _server.start();
87      }
88      
89      /* ------------------------------------------------------------ */
90      public void stop() throws Exception
91      {
92          _server.stop();
93      }
94  
95      /* ------------------------------------------------------------ */
96      public Context getContext()
97      {
98          return _context;
99      }
100     
101     /* ------------------------------------------------------------ */
102     /** Get raw HTTP responses from raw HTTP requests.
103      * Multiple requests and responses may be handled, but only if
104      * persistent connections conditions apply.
105      * @param rawRequests String of raw HTTP requests
106      * @return String of raw HTTP responses
107      * @throws Exception
108      */
109     public String getResponses(String rawRequests) throws Exception
110     {
111         _connector.reopen();
112         String responses = _connector.getResponses(rawRequests);
113         return responses;
114     }
115 
116     /* ------------------------------------------------------------ */
117     /** Get raw HTTP responses from raw HTTP requests.
118      * Multiple requests and responses may be handled, but only if
119      * persistent connections conditions apply.
120      * @param rawRequests String of raw HTTP requests
121      * @param connector The connector to handle the responses
122      * @return String of raw HTTP responses
123      * @throws Exception
124      */
125     public String getResponses(String rawRequests, LocalConnector connector) throws Exception
126     {
127         connector.reopen();
128         String responses = connector.getResponses(rawRequests);
129         return responses;
130     }
131 
132     /* ------------------------------------------------------------ */
133     /** Get raw HTTP responses from raw HTTP requests.
134      * Multiple requests and responses may be handled, but only if
135      * persistent connections conditions apply.
136      * @param rawRequests String of raw HTTP requests
137      * @return String of raw HTTP responses
138      * @throws Exception
139      */
140     public ByteArrayBuffer getResponses(ByteArrayBuffer rawRequests) throws Exception
141     {
142         _connector.reopen();
143         ByteArrayBuffer responses = _connector.getResponses(rawRequests,false);
144         return responses;
145     }
146     
147     /* ------------------------------------------------------------ */
148     /** Get raw HTTP responses from raw HTTP requests.
149      * Multiple requests and responses may be handled, but only if
150      * persistent connections conditions apply.
151      * @param rawRequests String of raw HTTP requests
152      * @param connector The connector to handle the responses
153      * @return String of raw HTTP responses
154      * @throws Exception
155      */
156     public ByteArrayBuffer getResponses(ByteArrayBuffer rawRequests, LocalConnector connector) throws Exception
157     {
158         connector.reopen();
159         ByteArrayBuffer responses = connector.getResponses(rawRequests,false);
160         return responses;
161     }
162     
163     /* ------------------------------------------------------------ */
164     /** Create a Socket connector.
165      * This methods adds a socket connector to the server
166      * @param locahost if true, only listen on local host, else listen on all interfaces.
167      * @return A URL to access the server via the socket connector.
168      * @throws Exception
169      */
170     public String createSocketConnector(boolean localhost)
171     throws Exception
172     {
173         synchronized (this)
174         {
175             SelectChannelConnector connector = new SelectChannelConnector();
176             if (localhost)
177                 connector.setHost("127.0.0.1");
178             _server.addConnector(connector);
179             if (_maxIdleTime != -1 )
180                 connector.setMaxIdleTime(_maxIdleTime);
181             if (_server.isStarted())
182                 connector.start();
183             else
184                 connector.open();
185 
186             return "http://"+(localhost?"127.0.0.1":
187                 InetAddress.getLocalHost().getHostAddress()    
188             )+":"+connector.getLocalPort();
189         }
190    }
191 
192     /* ------------------------------------------------------------ */
193     /** Create a Socket connector.
194      * This methods adds a socket connector to the server
195      * @param locahost if true, only listen on local host, else listen on all interfaces.
196      * @return A URL to access the server via the socket connector.
197      * @throws Exception
198      */
199     public LocalConnector createLocalConnector()
200         throws Exception
201     {
202         synchronized (this)
203         {
204             LocalConnector connector = new LocalConnector();
205             _server.addConnector(connector);
206 
207             if (_server.isStarted())
208                 connector.start();
209 
210             return connector;
211         }
212     }
213 
214     /* ------------------------------------------------------------ */
215     /**
216      * @param listener
217      * @see org.mortbay.jetty.handler.ContextHandler#addEventListener(java.util.EventListener)
218      */
219     public void addEventListener(EventListener listener)
220     {
221         _context.addEventListener(listener);
222     }
223 
224     /* ------------------------------------------------------------ */
225     /**
226      * @param filterClass
227      * @param pathSpec
228      * @param dispatches
229      * @return
230      * @see org.mortbay.jetty.servlet.Context#addFilter(java.lang.Class, java.lang.String, int)
231      */
232     public FilterHolder addFilter(Class filterClass, String pathSpec, int dispatches)
233     {
234         return _context.addFilter(filterClass,pathSpec,dispatches);
235     }
236 
237     /* ------------------------------------------------------------ */
238     /**
239      * @param filterClass
240      * @param pathSpec
241      * @param dispatches
242      * @return
243      * @see org.mortbay.jetty.servlet.Context#addFilter(java.lang.String, java.lang.String, int)
244      */
245     public FilterHolder addFilter(String filterClass, String pathSpec, int dispatches)
246     {
247         return _context.addFilter(filterClass,pathSpec,dispatches);
248     }
249 
250     /* ------------------------------------------------------------ */
251     /**
252      * @param servlet
253      * @param pathSpec
254      * @return
255      * @see org.mortbay.jetty.servlet.Context#addServlet(java.lang.Class, java.lang.String)
256      */
257     public ServletHolder addServlet(Class servlet, String pathSpec)
258     {
259         return _context.addServlet(servlet,pathSpec);
260     }
261 
262     /* ------------------------------------------------------------ */
263     /**
264      * @param className
265      * @param pathSpec
266      * @return
267      * @see org.mortbay.jetty.servlet.Context#addServlet(java.lang.String, java.lang.String)
268      */
269     public ServletHolder addServlet(String className, String pathSpec)
270     {
271         return _context.addServlet(className,pathSpec);
272     }
273 
274     /* ------------------------------------------------------------ */
275     /**
276      * @param name
277      * @return
278      * @see org.mortbay.jetty.handler.ContextHandler#getAttribute(java.lang.String)
279      */
280     public Object getAttribute(String name)
281     {
282         return _context.getAttribute(name);
283     }
284 
285     /* ------------------------------------------------------------ */
286     /**
287      * @return
288      * @see org.mortbay.jetty.handler.ContextHandler#getAttributeNames()
289      */
290     public Enumeration getAttributeNames()
291     {
292         return _context.getAttributeNames();
293     }
294 
295     /* ------------------------------------------------------------ */
296     /**
297      * @return
298      * @see org.mortbay.jetty.handler.ContextHandler#getAttributes()
299      */
300     public Attributes getAttributes()
301     {
302         return _context.getAttributes();
303     }
304 
305     /* ------------------------------------------------------------ */
306     /**
307      * @return
308      * @see org.mortbay.jetty.handler.ContextHandler#getResourceBase()
309      */
310     public String getResourceBase()
311     {
312         return _context.getResourceBase();
313     }
314 
315     /* ------------------------------------------------------------ */
316     /**
317      * @param name
318      * @param value
319      * @see org.mortbay.jetty.handler.ContextHandler#setAttribute(java.lang.String, java.lang.Object)
320      */
321     public void setAttribute(String name, Object value)
322     {
323         _context.setAttribute(name,value);
324     }
325 
326     /* ------------------------------------------------------------ */
327     /**
328      * @param classLoader
329      * @see org.mortbay.jetty.handler.ContextHandler#setClassLoader(java.lang.ClassLoader)
330      */
331     public void setClassLoader(ClassLoader classLoader)
332     {
333         _context.setClassLoader(classLoader);
334     }
335 
336     /* ------------------------------------------------------------ */
337     /**
338      * @param contextPath
339      * @see org.mortbay.jetty.handler.ContextHandler#setContextPath(java.lang.String)
340      */
341     public void setContextPath(String contextPath)
342     {
343         _context.setContextPath(contextPath);
344     }
345 
346     /* ------------------------------------------------------------ */
347     /**
348      * @param eventListeners
349      * @see org.mortbay.jetty.handler.ContextHandler#setEventListeners(java.util.EventListener[])
350      */
351     public void setEventListeners(EventListener[] eventListeners)
352     {
353         _context.setEventListeners(eventListeners);
354     }
355 
356     /* ------------------------------------------------------------ */
357     /**
358      * @param resourceBase
359      * @see org.mortbay.jetty.handler.ContextHandler#setResourceBase(java.lang.String)
360      */
361     public void setResourceBase(String resourceBase)
362     {
363         _context.setResourceBase(resourceBase);
364     }
365     
366     /* ------------------------------------------------------------ */
367     public void setMaxIdleTime(int maxIdleTime)
368     {
369         _maxIdleTime = maxIdleTime;
370     }
371 }