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 }