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(String content)
96          {
97              try
98              {
99                  _content=new ByteArrayOutputStream();
100                 _content.write(StringUtil.getBytes(content));
101             }
102             catch (IOException e)
103             {
104                 throw new RuntimeException(e);
105             }
106         }
107 
108         public void setContent(ByteBuffer content)
109         {
110             try
111             {
112                 _content=new ByteArrayOutputStream();
113                 _content.write(BufferUtil.toArray(content));
114             }
115             catch (IOException e)
116             {
117                 throw new RuntimeException(e);
118             }
119         }
120         @Override
121         public boolean parsedHeader(HttpField field)
122         {
123             put(field.getName(),field.getValue());
124             return false;
125         }
126 
127         @Override
128         public boolean messageComplete()
129         {
130             return true;
131         }
132 
133         @Override
134         public boolean headerComplete()
135         {
136             _content=new ByteArrayOutputStream();
137             return false;
138         }
139 
140         @Override
141         public boolean earlyEOF()
142         {
143             return true;
144         }
145 
146         @Override
147         public boolean content(ByteBuffer ref)
148         {
149             try
150             {
151                 _content.write(BufferUtil.toArray(ref));
152             }
153             catch (IOException e)
154             {
155                 throw new RuntimeException(e);
156             }
157             return false;
158         }
159 
160         @Override
161         public void badMessage(int status, String reason)
162         {
163             throw new RuntimeException(reason);
164         }
165 
166         public ByteBuffer generate()
167         {
168             try
169             {
170                 HttpGenerator generator = new HttpGenerator();
171                 HttpGenerator.Info info = getInfo();
172                 // System.err.println(info.getClass());
173                 // System.err.println(info);
174 
175                 ByteArrayOutputStream out = new ByteArrayOutputStream();
176                 ByteBuffer header=null;
177                 ByteBuffer chunk=null;
178                 ByteBuffer content=_content==null?null:ByteBuffer.wrap(_content.toByteArray());
179 
180 
181                 loop: while(!generator.isEnd())
182                 {
183                     HttpGenerator.Result result =  info instanceof RequestInfo
184                         ?generator.generateRequest((RequestInfo)info,header,chunk,content,true)
185                         :generator.generateResponse((ResponseInfo)info,header,chunk,content,true);
186                     switch(result)
187                     {
188                         case NEED_HEADER:
189                             header=BufferUtil.allocate(8192);
190                             continue;
191 
192                         case NEED_CHUNK:
193                             chunk=BufferUtil.allocate(HttpGenerator.CHUNK_SIZE);
194                             continue;
195 
196                         case NEED_INFO:
197                             throw new IllegalStateException();
198 
199                         case FLUSH:
200                             if (BufferUtil.hasContent(header))
201                             {
202                                 out.write(BufferUtil.toArray(header));
203                                 BufferUtil.clear(header);
204                             }
205                             if (BufferUtil.hasContent(chunk))
206                             {
207                                 out.write(BufferUtil.toArray(chunk));
208                                 BufferUtil.clear(chunk);
209                             }
210                             if (BufferUtil.hasContent(content))
211                             {
212                                 out.write(BufferUtil.toArray(content));
213                                 BufferUtil.clear(content);
214                             }
215                             break;
216 
217                         case SHUTDOWN_OUT:
218                             break loop;
219                     }
220                 }
221 
222                 return ByteBuffer.wrap(out.toByteArray());
223             }
224             catch (IOException e)
225             {
226                 throw new RuntimeException(e);
227             }
228 
229         }
230         abstract public HttpGenerator.Info getInfo();
231 
232     }
233 
234     public static class Request extends Message implements HttpParser.RequestHandler<ByteBuffer>
235     {
236         private String _method;
237         private String _uri;
238 
239         @Override
240         public boolean startRequest(HttpMethod method, String methodString, ByteBuffer uri, HttpVersion version)
241         {
242             _method=methodString;
243             _uri=BufferUtil.toUTF8String(uri);
244             _version=version;
245             return false;
246         }
247 
248         public String getMethod()
249         {
250             return _method;
251         }
252 
253         public String getUri()
254         {
255             return _uri;
256         }
257 
258         public void setMethod(String method)
259         {
260             _method=method;
261         }
262 
263         public void setURI(String uri)
264         {
265             _uri=uri;
266         }
267 
268         @Override
269         public HttpGenerator.RequestInfo getInfo()
270         {
271             return new HttpGenerator.RequestInfo(_version,this,_content==null?0:_content.size(),_method,_uri);
272         }
273 
274         @Override
275         public String toString()
276         {
277             return String.format("%s %s %s\n%s\n",_method,_uri,_version,super.toString());
278         }
279 
280         public void setHeader(String name, String value)
281         {
282             put(name,value);
283         }
284 
285         @Override
286         public boolean parsedHostHeader(String host,int port)
287         {
288             return false;
289         }
290     }
291 
292     public static class Response extends Message implements HttpParser.ResponseHandler<ByteBuffer>
293     {
294         private int _status;
295         private String _reason;
296 
297         @Override
298         public boolean startResponse(HttpVersion version, int status, String reason)
299         {
300             _version=version;
301             _status=status;
302             _reason=reason;
303             return false;
304         }
305 
306         public int getStatus()
307         {
308             return _status;
309         }
310 
311         public String getReason()
312         {
313             return _reason;
314         }
315 
316         public byte[] getContentBytes()
317         {
318             if (_content==null)
319                 return null;
320             return _content.toByteArray();
321         }
322 
323         public String getContent()
324         {
325             if (_content==null)
326                 return null;
327             byte[] bytes=_content.toByteArray();
328 
329             String content_type=get(HttpHeader.CONTENT_TYPE);
330             String encoding=MimeTypes.getCharsetFromContentType(content_type);
331             Charset charset=encoding==null?StringUtil.__UTF8_CHARSET:Charset.forName(encoding);
332 
333             return new String(bytes,charset);
334         }
335 
336         @Override
337         public HttpGenerator.ResponseInfo getInfo()
338         {
339             return new HttpGenerator.ResponseInfo(_version,this,_content==null?-1:_content.size(),_status,_reason,false);
340         }
341 
342         @Override
343         public String toString()
344         {
345             return String.format("%s %s %s\n%s\n",_version,_status,_reason,super.toString());
346         }
347     }
348 }