View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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.http;
20  
21  import java.io.ByteArrayOutputStream;
22  import java.io.IOException;
23  import java.nio.ByteBuffer;
24  import java.nio.charset.Charset;
25  
26  import org.eclipse.jetty.http.HttpGenerator.RequestInfo;
27  import org.eclipse.jetty.http.HttpGenerator.ResponseInfo;
28  import org.eclipse.jetty.util.BufferUtil;
29  import org.eclipse.jetty.util.StringUtil;
30  
31  public class HttpTester
32  {
33      private HttpTester()
34      {
35      }
36  
37      public static Request newRequest()
38      {
39          return new Request();
40      }
41  
42      public static Request parseRequest(String request)
43      {
44          Request r=new Request();
45          HttpParser parser =new HttpParser(r);
46          parser.parseNext(BufferUtil.toBuffer(request));
47          return r;
48      }
49  
50      public static Request parseRequest(ByteBuffer request)
51      {
52          Request r=new Request();
53          HttpParser parser =new HttpParser(r);
54          parser.parseNext(request);
55          return r;
56      }
57  
58      public static Response parseResponse(String response)
59      {
60          Response r=new Response();
61          HttpParser parser =new HttpParser(r);
62          parser.parseNext(BufferUtil.toBuffer(response));
63          return r;
64      }
65  
66      public static Response parseResponse(ByteBuffer response)
67      {
68          Response r=new Response();
69          HttpParser parser =new HttpParser(r);
70          parser.parseNext(response);
71          return r;
72      }
73  
74  
75      public abstract static class Message extends HttpFields implements HttpParser.HttpHandler<ByteBuffer>
76      {
77          ByteArrayOutputStream _content;
78          HttpVersion _version=HttpVersion.HTTP_1_0;
79  
80          public HttpVersion getVersion()
81          {
82              return _version;
83          }
84  
85          public void setVersion(String version)
86          {
87              setVersion(HttpVersion.CACHE.get(version));
88          }
89  
90          public void setVersion(HttpVersion version)
91          {
92              _version=version;
93          }
94  
95          public void setContent(byte[] bytes)
96          {
97              try
98              {
99                  _content=new ByteArrayOutputStream();
100                 _content.write(bytes);
101             }
102             catch (IOException e)
103             {
104                 throw new RuntimeException(e);
105             }
106         }
107 
108         public void setContent(String content)
109         {
110             try
111             {
112                 _content=new ByteArrayOutputStream();
113                 _content.write(StringUtil.getBytes(content));
114             }
115             catch (IOException e)
116             {
117                 throw new RuntimeException(e);
118             }
119         }
120 
121         public void setContent(ByteBuffer content)
122         {
123             try
124             {
125                 _content=new ByteArrayOutputStream();
126                 _content.write(BufferUtil.toArray(content));
127             }
128             catch (IOException e)
129             {
130                 throw new RuntimeException(e);
131             }
132         }
133         @Override
134         public boolean parsedHeader(HttpField field)
135         {
136             put(field.getName(),field.getValue());
137             return false;
138         }
139 
140         @Override
141         public boolean messageComplete()
142         {
143             return true;
144         }
145 
146         @Override
147         public boolean headerComplete()
148         {
149             _content=new ByteArrayOutputStream();
150             return false;
151         }
152 
153         @Override
154         public void earlyEOF()
155         {
156         }
157 
158         @Override
159         public boolean content(ByteBuffer ref)
160         {
161             try
162             {
163                 _content.write(BufferUtil.toArray(ref));
164             }
165             catch (IOException e)
166             {
167                 throw new RuntimeException(e);
168             }
169             return false;
170         }
171 
172         @Override
173         public void badMessage(int status, String reason)
174         {
175             throw new RuntimeException(reason);
176         }
177 
178         public ByteBuffer generate()
179         {
180             try
181             {
182                 HttpGenerator generator = new HttpGenerator();
183                 HttpGenerator.Info info = getInfo();
184                 // System.err.println(info.getClass());
185                 // System.err.println(info);
186 
187                 ByteArrayOutputStream out = new ByteArrayOutputStream();
188                 ByteBuffer header=null;
189                 ByteBuffer chunk=null;
190                 ByteBuffer content=_content==null?null:ByteBuffer.wrap(_content.toByteArray());
191 
192 
193                 loop: while(!generator.isEnd())
194                 {
195                     HttpGenerator.Result result =  info instanceof RequestInfo
196                         ?generator.generateRequest((RequestInfo)info,header,chunk,content,true)
197                         :generator.generateResponse((ResponseInfo)info,header,chunk,content,true);
198                     switch(result)
199                     {
200                         case NEED_HEADER:
201                             header=BufferUtil.allocate(8192);
202                             continue;
203 
204                         case NEED_CHUNK:
205                             chunk=BufferUtil.allocate(HttpGenerator.CHUNK_SIZE);
206                             continue;
207 
208                         case NEED_INFO:
209                             throw new IllegalStateException();
210 
211                         case FLUSH:
212                             if (BufferUtil.hasContent(header))
213                             {
214                                 out.write(BufferUtil.toArray(header));
215                                 BufferUtil.clear(header);
216                             }
217                             if (BufferUtil.hasContent(chunk))
218                             {
219                                 out.write(BufferUtil.toArray(chunk));
220                                 BufferUtil.clear(chunk);
221                             }
222                             if (BufferUtil.hasContent(content))
223                             {
224                                 out.write(BufferUtil.toArray(content));
225                                 BufferUtil.clear(content);
226                             }
227                             break;
228 
229                         case SHUTDOWN_OUT:
230                             break loop;
231                     }
232                 }
233 
234                 return ByteBuffer.wrap(out.toByteArray());
235             }
236             catch (IOException e)
237             {
238                 throw new RuntimeException(e);
239             }
240 
241         }
242         abstract public HttpGenerator.Info getInfo();
243 
244         @Override
245         public int getHeaderCacheSize()
246         {
247             return 0;
248         }
249 
250     }
251 
252     public static class Request extends Message implements HttpParser.RequestHandler<ByteBuffer>
253     {
254         private String _method;
255         private String _uri;
256 
257         @Override
258         public boolean startRequest(HttpMethod method, String methodString, ByteBuffer uri, HttpVersion version)
259         {
260             _method=methodString;
261             _uri=BufferUtil.toUTF8String(uri);
262             _version=version;
263             return false;
264         }
265 
266         public String getMethod()
267         {
268             return _method;
269         }
270 
271         public String getUri()
272         {
273             return _uri;
274         }
275 
276         public void setMethod(String method)
277         {
278             _method=method;
279         }
280 
281         public void setURI(String uri)
282         {
283             _uri=uri;
284         }
285 
286         @Override
287         public HttpGenerator.RequestInfo getInfo()
288         {
289             return new HttpGenerator.RequestInfo(_version,this,_content==null?0:_content.size(),_method,_uri);
290         }
291 
292         @Override
293         public String toString()
294         {
295             return String.format("%s %s %s\n%s\n",_method,_uri,_version,super.toString());
296         }
297 
298         public void setHeader(String name, String value)
299         {
300             put(name,value);
301         }
302 
303         @Override
304         public boolean parsedHostHeader(String host,int port)
305         {
306             return false;
307         }
308     }
309 
310     public static class Response extends Message implements HttpParser.ResponseHandler<ByteBuffer>
311     {
312         private int _status;
313         private String _reason;
314 
315         @Override
316         public boolean startResponse(HttpVersion version, int status, String reason)
317         {
318             _version=version;
319             _status=status;
320             _reason=reason;
321             return false;
322         }
323 
324         public int getStatus()
325         {
326             return _status;
327         }
328 
329         public String getReason()
330         {
331             return _reason;
332         }
333 
334         public byte[] getContentBytes()
335         {
336             if (_content==null)
337                 return null;
338             return _content.toByteArray();
339         }
340 
341         public String getContent()
342         {
343             if (_content==null)
344                 return null;
345             byte[] bytes=_content.toByteArray();
346 
347             String content_type=get(HttpHeader.CONTENT_TYPE);
348             String encoding=MimeTypes.getCharsetFromContentType(content_type);
349             Charset charset=encoding==null?StringUtil.__UTF8_CHARSET:Charset.forName(encoding);
350 
351             return new String(bytes,charset);
352         }
353 
354         @Override
355         public HttpGenerator.ResponseInfo getInfo()
356         {
357             return new HttpGenerator.ResponseInfo(_version,this,_content==null?-1:_content.size(),_status,_reason,false);
358         }
359 
360         @Override
361         public String toString()
362         {
363             return String.format("%s %s %s\n%s\n",_version,_status,_reason,super.toString());
364         }
365     }
366 }