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 }