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
    15  package org.mortbay.jetty.testing;
    16
    17  import java.io.IOException;
    18  import java.util.Enumeration;
    19
    20  import javax.servlet.http.Cookie;
    21
    22  import org.mortbay.io.Buffer;
    23  import org.mortbay.io.ByteArrayBuffer;
    24  import org.mortbay.io.ByteArrayEndPoint;
    25  import org.mortbay.io.SimpleBuffers;
    26  import org.mortbay.io.View;
    27  import org.mortbay.io.bio.StringEndPoint;
    28  import org.mortbay.jetty.HttpFields;
    29  import org.mortbay.jetty.HttpGenerator;
    30  import org.mortbay.jetty.HttpHeaders;
    31  import org.mortbay.jetty.HttpParser;
    32  import org.mortbay.jetty.HttpVersions;
    33  import org.mortbay.util.ByteArrayOutputStream2;
    34
    35  /* ------------------------------------------------------------ */
    36  /** Test support class.
    37   * Assist with parsing and generating HTTP requests and responses.
    38   *
    39   * <pre>
    40   *      HttpTester tester = new HttpTester();
    41   *
    42   *      tester.parse(
    43   *          "GET /uri HTTP/1.1\r\n"+
    44   *          "Host: fakehost\r\n"+
    45   *          "Content-Length: 10\r\n" +
    46   *          "\r\n");
    47   *
    48   *      System.err.println(tester.getMethod());
    49   *      System.err.println(tester.getURI());
    50   *      System.err.println(tester.getVersion());
    51   *      System.err.println(tester.getHeader("Host"));
    52   *      System.err.println(tester.getContent());
    53   * </pre>
    54   *
    55   * @author gregw
    56   * @see org.mortbay.jetty.testing.ServletTester
    57   */
    58  public class HttpTester
    59  {
    60      protected HttpFields _fields=new HttpFields();
    61      protected String _method;
    62      protected String _uri;
    63      protected String _version;
    64      protected int _status;
    65      protected String _reason;
    66      protected ByteArrayOutputStream2 _parsedContent;
    67      protected byte[] _genContent;
    68
    69      public HttpTester()
    70      {
    71      }
    72
    73      public void reset()
    74      {
    75          _fields.clear();
    76           _method=null;
    77           _uri=null;
    78           _version=null;
    79           _status=0;
    80           _reason=null;
    81           _parsedContent=null;
    82           _genContent=null;
    83      }
    84
    85      /* ------------------------------------------------------------ */
    86      /**
    87       * Parse one HTTP request or response
    88       * @param rawHTTP Raw HTTP to parse
    89       * @return Any unparsed data in the rawHTTP (eg pipelined requests)
    90       * @throws IOException
    91       */
    92      public String parse(String rawHTTP) throws IOException
    93      {
    94          ByteArrayBuffer buf = new ByteArrayBuffer(rawHTTP);
    95          View view = new View(buf);
    96          HttpParser parser = new HttpParser(view,new PH());
    97          parser.parse();
    98          return view.toString();
    99      }
    100
    101     /* ------------------------------------------------------------ */
    102     public String generate() throws IOException
    103     {
    104         Buffer bb=new ByteArrayBuffer(32*1024 + (_genContent!=null?_genContent.length:0));
    105         Buffer sb=new ByteArrayBuffer(4*1024);
    106         StringEndPoint endp = new StringEndPoint();
    107         HttpGenerator generator = new HttpGenerator(new SimpleBuffers(new Buffer[]{sb,bb}),endp, sb.capacity(), bb.capacity());
    108
    109         if (_method!=null)
    110         {
    111             generator.setRequest(getMethod(),getURI());
    112             if (_version==null)
    113                 generator.setVersion(HttpVersions.HTTP_1_1_ORDINAL);
    114             else
    115                 generator.setVersion(HttpVersions.CACHE.getOrdinal(HttpVersions.CACHE.lookup(_version)));
    116             generator.completeHeader(_fields,false);
    117             if (_genContent!=null)
    118                 generator.addContent(new View(new ByteArrayBuffer(_genContent)),false);
    119             else if (_parsedContent!=null)
    120                 generator.addContent(new ByteArrayBuffer(_parsedContent.toByteArray()),false);
    121         }
    122
    123         generator.complete();
    124         generator.flush();
    125         return endp.getOutput();
    126     }
    127
    128     /* ------------------------------------------------------------ */
    129     /**
    130      * @return the method
    131      */
    132     public String getMethod()
    133     {
    134         return _method;
    135     }
    136
    137     /* ------------------------------------------------------------ */
    138     /**
    139      * @param method the method to set
    140      */
    141     public void setMethod(String method)
    142     {
    143         _method=method;
    144     }
    145
    146     /* ------------------------------------------------------------ */
    147     /**
    148      * @return the reason
    149      */
    150     public String getReason()
    151     {
    152         return _reason;
    153     }
    154
    155     /* ------------------------------------------------------------ */
    156     /**
    157      * @param reason the reason to set
    158      */
    159     public void setReason(String reason)
    160     {
    161         _reason=reason;
    162     }
    163
    164     /* ------------------------------------------------------------ */
    165     /**
    166      * @return the status
    167      */
    168     public int getStatus()
    169     {
    170         return _status;
    171     }
    172
    173     /* ------------------------------------------------------------ */
    174     /**
    175      * @param status the status to set
    176      */
    177     public void setStatus(int status)
    178     {
    179         _status=status;
    180     }
    181
    182     /* ------------------------------------------------------------ */
    183     /**
    184      * @return the uri
    185      */
    186     public String getURI()
    187     {
    188         return _uri;
    189     }
    190
    191     /* ------------------------------------------------------------ */
    192     /**
    193      * @param uri the uri to set
    194      */
    195     public void setURI(String uri)
    196     {
    197         _uri=uri;
    198     }
    199
    200     /* ------------------------------------------------------------ */
    201     /**
    202      * @return the version
    203      */
    204     public String getVersion()
    205     {
    206         return _version;
    207     }
    208
    209     /* ------------------------------------------------------------ */
    210     /**
    211      * @param version the version to set
    212      */
    213     public void setVersion(String version)
    214     {
    215         _version=version;
    216     }
    217
    218     /* ------------------------------------------------------------ */
    219     /**
    220      * @param name
    221      * @param value
    222      * @throws IllegalArgumentException
    223      * @see org.mortbay.jetty.HttpFields#add(java.lang.String, java.lang.String)
    224      */
    225     public void addHeader(String name, String value) throws IllegalArgumentException
    226     {
    227         _fields.add(name,value);
    228     }
    229
    230     /* ------------------------------------------------------------ */
    231     /**
    232      * @param name
    233      * @param date
    234      * @see org.mortbay.jetty.HttpFields#addDateField(java.lang.String, long)
    235      */
    236     public void addDateHeader(String name, long date)
    237     {
    238         _fields.addDateField(name,date);
    239     }
    240
    241     /* ------------------------------------------------------------ */
    242     /**
    243      * @param name
    244      * @param value
    245      * @see org.mortbay.jetty.HttpFields#addLongField(java.lang.String, long)
    246      */
    247     public void addLongHeader(String name, long value)
    248     {
    249         _fields.addLongField(name,value);
    250     }
    251
    252     /* ------------------------------------------------------------ */
    253     /**
    254      * @param cookie
    255      * @see org.mortbay.jetty.HttpFields#addSetCookie(javax.servlet.http.Cookie)
    256      */
    257     public void addSetCookie(Cookie cookie)
    258     {
    259         _fields.addSetCookie(cookie);
    260     }
    261
    262     /* ------------------------------------------------------------ */
    263     /**
    264      * @param name
    265      * @return
    266      * @see org.mortbay.jetty.HttpFields#getDateField(java.lang.String)
    267      */
    268     public long getDateHeader(String name)
    269     {
    270         return _fields.getDateField(name);
    271     }
    272
    273     /* ------------------------------------------------------------ */
    274     /**
    275      * @return
    276      * @see org.mortbay.jetty.HttpFields#getFieldNames()
    277      */
    278     public Enumeration getHeaderNames()
    279     {
    280         return _fields.getFieldNames();
    281     }
    282
    283     /* ------------------------------------------------------------ */
    284     /**
    285      * @param name
    286      * @return
    287      * @throws NumberFormatException
    288      * @see org.mortbay.jetty.HttpFields#getLongField(java.lang.String)
    289      */
    290     public long getLongHeader(String name) throws NumberFormatException
    291     {
    292         return _fields.getLongField(name);
    293     }
    294
    295     /* ------------------------------------------------------------ */
    296     /**
    297      * @param name
    298      * @return
    299      * @see org.mortbay.jetty.HttpFields#getStringField(java.lang.String)
    300      */
    301     public String getHeader(String name)
    302     {
    303         return _fields.getStringField(name);
    304     }
    305
    306     /* ------------------------------------------------------------ */
    307     /**
    308      * @param name
    309      * @return
    310      * @see org.mortbay.jetty.HttpFields#getValues(java.lang.String)
    311      */
    312     public Enumeration getHeaderValues(String name)
    313     {
    314         return _fields.getValues(name);
    315     }
    316
    317     /* ------------------------------------------------------------ */
    318     /**
    319      * @param name
    320      * @param value
    321      * @see org.mortbay.jetty.HttpFields#put(java.lang.String, java.lang.String)
    322      */
    323     public void setHeader(String name, String value)
    324     {
    325         _fields.put(name,value);
    326     }
    327
    328     /* ------------------------------------------------------------ */
    329     /**
    330      * @param name
    331      * @param date
    332      * @see org.mortbay.jetty.HttpFields#putDateField(java.lang.String, long)
    333      */
    334     public void setDateHeader(String name, long date)
    335     {
    336         _fields.putDateField(name,date);
    337     }
    338
    339     /* ------------------------------------------------------------ */
    340     /**
    341      * @param name
    342      * @param value
    343      * @see org.mortbay.jetty.HttpFields#putLongField(java.lang.String, long)
    344      */
    345     public void setLongHeader(String name, long value)
    346     {
    347         _fields.putLongField(name,value);
    348     }
    349
    350     /* ------------------------------------------------------------ */
    351     /**
    352      * @param name
    353      * @see org.mortbay.jetty.HttpFields#remove(java.lang.String)
    354      */
    355     public void removeHeader(String name)
    356     {
    357         _fields.remove(name);
    358     }
    359
    360     /* ------------------------------------------------------------ */
    361     public String getContent()
    362     {
    363         if (_parsedContent!=null)
    364             return _parsedContent.toString();
    365         if (_genContent!=null)
    366             return new String(_genContent);
    367         return null;
    368     }
    369
    370     /* ------------------------------------------------------------ */
    371     public void setContent(String content)
    372     {
    373         _parsedContent=null;
    374         if (content!=null)
    375         {
    376             _genContent=content.getBytes();
    377             setLongHeader(HttpHeaders.CONTENT_LENGTH,_genContent.length);
    378         }
    379         else
    380         {
    381             removeHeader(HttpHeaders.CONTENT_LENGTH);
    382             _genContent=null;
    383         }
    384     }
    385
    386     /* ------------------------------------------------------------ */
    387     private class PH extends HttpParser.EventHandler
    388     {
    389         public void startRequest(Buffer method, Buffer url, Buffer version) throws IOException
    390         {
    391             reset();
    392             _method=method.toString();
    393             _uri=url.toString();
    394             _version=version.toString();
    395         }
    396
    397         public void startResponse(Buffer version, int status, Buffer reason) throws IOException
    398         {
    399             reset();
    400             _version=version.toString();
    401             _status=status;
    402             _reason=reason.toString();
    403         }
    404
    405         public void parsedHeader(Buffer name, Buffer value) throws IOException
    406         {
    407             _fields.add(name,value);
    408         }
    409
    410         public void headerComplete() throws IOException
    411         {
    412         }
    413
    414         public void messageComplete(long contextLength) throws IOException
    415         {
    416         }
    417
    418         public void content(Buffer ref) throws IOException
    419         {
    420             if (_parsedContent==null)
    421                 _parsedContent=new ByteArrayOutputStream2();
    422             _parsedContent.write(ref.asArray());
    423         }
    424     }
    425
    426 }