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 }