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