1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
185
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 }