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