001: package org.mortbay.jetty.testing;
002:
003: import java.io.IOException;
004: import java.util.Enumeration;
005:
006: import javax.servlet.http.Cookie;
007:
008: import org.mortbay.io.Buffer;
009: import org.mortbay.io.ByteArrayBuffer;
010: import org.mortbay.io.ByteArrayEndPoint;
011: import org.mortbay.io.SimpleBuffers;
012: import org.mortbay.io.View;
013: import org.mortbay.io.bio.StringEndPoint;
014: import org.mortbay.jetty.HttpFields;
015: import org.mortbay.jetty.HttpGenerator;
016: import org.mortbay.jetty.HttpHeaders;
017: import org.mortbay.jetty.HttpParser;
018: import org.mortbay.jetty.HttpVersions;
019: import org.mortbay.util.ByteArrayOutputStream2;
020:
021: /* ------------------------------------------------------------ */
022: /** Test support class.
023: * Assist with parsing and generating HTTP requests and responses.
024: *
025: * <pre>
026: * HttpTester tester = new HttpTester();
027: *
028: * tester.parse(
029: * "GET /uri HTTP/1.1\r\n"+
030: * "Host: fakehost\r\n"+
031: * "Content-Length: 10\r\n" +
032: * "\r\n");
033: *
034: * System.err.println(tester.getMethod());
035: * System.err.println(tester.getURI());
036: * System.err.println(tester.getVersion());
037: * System.err.println(tester.getHeader("Host"));
038: * System.err.println(tester.getContent());
039: * </pre>
040: *
041: * @author gregw
042: * @see org.mortbay.jetty.testing.ServletTester
043: */
044: public class HttpTester {
045: protected HttpFields _fields = new HttpFields();
046: protected String _method;
047: protected String _uri;
048: protected String _version;
049: protected int _status;
050: protected String _reason;
051: protected ByteArrayOutputStream2 _parsedContent;
052: protected byte[] _genContent;
053:
054: public HttpTester() {
055: }
056:
057: public void reset() {
058: _fields.clear();
059: _method = null;
060: _uri = null;
061: _version = null;
062: _status = 0;
063: _reason = null;
064: _parsedContent = null;
065: _genContent = null;
066: }
067:
068: /* ------------------------------------------------------------ */
069: /**
070: * Parse one HTTP request or response
071: * @param rawHTTP Raw HTTP to parse
072: * @return Any unparsed data in the rawHTTP (eg pipelined requests)
073: * @throws IOException
074: */
075: public String parse(String rawHTTP) throws IOException {
076: ByteArrayBuffer buf = new ByteArrayBuffer(rawHTTP);
077: View view = new View(buf);
078: HttpParser parser = new HttpParser(view, new PH());
079: parser.parse();
080: return view.toString();
081: }
082:
083: /* ------------------------------------------------------------ */
084: public String generate() throws IOException {
085: Buffer bb = new ByteArrayBuffer(32 * 1024);
086: Buffer sb = new ByteArrayBuffer(8 * 1024);
087: StringEndPoint endp = new StringEndPoint();
088: HttpGenerator generator = new HttpGenerator(new SimpleBuffers(
089: new Buffer[] { sb, bb }), endp, sb.capacity(), bb
090: .capacity());
091:
092: if (_method != null) {
093: generator.setRequest(getMethod(), getURI());
094: if (_version == null)
095: generator.setVersion(HttpVersions.HTTP_1_1_ORDINAL);
096: else
097: generator
098: .setVersion(HttpVersions.CACHE
099: .getOrdinal(HttpVersions.CACHE
100: .lookup(_version)));
101: generator.completeHeader(_fields, false);
102: if (_genContent != null)
103: generator.addContent(new View(new ByteArrayBuffer(
104: _genContent)), false);
105: else if (_parsedContent != null)
106: generator.addContent(new ByteArrayBuffer(_parsedContent
107: .toByteArray()), false);
108: }
109:
110: generator.complete();
111: generator.flush();
112: return endp.getOutput();
113: }
114:
115: /* ------------------------------------------------------------ */
116: /**
117: * @return the method
118: */
119: public String getMethod() {
120: return _method;
121: }
122:
123: /* ------------------------------------------------------------ */
124: /**
125: * @param method the method to set
126: */
127: public void setMethod(String method) {
128: _method = method;
129: }
130:
131: /* ------------------------------------------------------------ */
132: /**
133: * @return the reason
134: */
135: public String getReason() {
136: return _reason;
137: }
138:
139: /* ------------------------------------------------------------ */
140: /**
141: * @param reason the reason to set
142: */
143: public void setReason(String reason) {
144: _reason = reason;
145: }
146:
147: /* ------------------------------------------------------------ */
148: /**
149: * @return the status
150: */
151: public int getStatus() {
152: return _status;
153: }
154:
155: /* ------------------------------------------------------------ */
156: /**
157: * @param status the status to set
158: */
159: public void setStatus(int status) {
160: _status = status;
161: }
162:
163: /* ------------------------------------------------------------ */
164: /**
165: * @return the uri
166: */
167: public String getURI() {
168: return _uri;
169: }
170:
171: /* ------------------------------------------------------------ */
172: /**
173: * @param uri the uri to set
174: */
175: public void setURI(String uri) {
176: _uri = uri;
177: }
178:
179: /* ------------------------------------------------------------ */
180: /**
181: * @return the version
182: */
183: public String getVersion() {
184: return _version;
185: }
186:
187: /* ------------------------------------------------------------ */
188: /**
189: * @param version the version to set
190: */
191: public void setVersion(String version) {
192: _version = version;
193: }
194:
195: /* ------------------------------------------------------------ */
196: /**
197: * @param name
198: * @param value
199: * @throws IllegalArgumentException
200: * @see org.mortbay.jetty.HttpFields#add(java.lang.String, java.lang.String)
201: */
202: public void addHeader(String name, String value)
203: throws IllegalArgumentException {
204: _fields.add(name, value);
205: }
206:
207: /* ------------------------------------------------------------ */
208: /**
209: * @param name
210: * @param date
211: * @see org.mortbay.jetty.HttpFields#addDateField(java.lang.String, long)
212: */
213: public void addDateHeader(String name, long date) {
214: _fields.addDateField(name, date);
215: }
216:
217: /* ------------------------------------------------------------ */
218: /**
219: * @param name
220: * @param value
221: * @see org.mortbay.jetty.HttpFields#addLongField(java.lang.String, long)
222: */
223: public void addLongHeader(String name, long value) {
224: _fields.addLongField(name, value);
225: }
226:
227: /* ------------------------------------------------------------ */
228: /**
229: * @param cookie
230: * @see org.mortbay.jetty.HttpFields#addSetCookie(javax.servlet.http.Cookie)
231: */
232: public void addSetCookie(Cookie cookie) {
233: _fields.addSetCookie(cookie);
234: }
235:
236: /* ------------------------------------------------------------ */
237: /**
238: * @param name
239: * @return
240: * @see org.mortbay.jetty.HttpFields#getDateField(java.lang.String)
241: */
242: public long getDateHeader(String name) {
243: return _fields.getDateField(name);
244: }
245:
246: /* ------------------------------------------------------------ */
247: /**
248: * @return
249: * @see org.mortbay.jetty.HttpFields#getFieldNames()
250: */
251: public Enumeration getHeaderNames() {
252: return _fields.getFieldNames();
253: }
254:
255: /* ------------------------------------------------------------ */
256: /**
257: * @param name
258: * @return
259: * @throws NumberFormatException
260: * @see org.mortbay.jetty.HttpFields#getLongField(java.lang.String)
261: */
262: public long getLongHeader(String name) throws NumberFormatException {
263: return _fields.getLongField(name);
264: }
265:
266: /* ------------------------------------------------------------ */
267: /**
268: * @param name
269: * @return
270: * @see org.mortbay.jetty.HttpFields#getStringField(java.lang.String)
271: */
272: public String getHeader(String name) {
273: return _fields.getStringField(name);
274: }
275:
276: /* ------------------------------------------------------------ */
277: /**
278: * @param name
279: * @return
280: * @see org.mortbay.jetty.HttpFields#getValues(java.lang.String)
281: */
282: public Enumeration getHeaderValues(String name) {
283: return _fields.getValues(name);
284: }
285:
286: /* ------------------------------------------------------------ */
287: /**
288: * @param name
289: * @param value
290: * @see org.mortbay.jetty.HttpFields#put(java.lang.String, java.lang.String)
291: */
292: public void setHeader(String name, String value) {
293: _fields.put(name, value);
294: }
295:
296: /* ------------------------------------------------------------ */
297: /**
298: * @param name
299: * @param date
300: * @see org.mortbay.jetty.HttpFields#putDateField(java.lang.String, long)
301: */
302: public void setDateHeader(String name, long date) {
303: _fields.putDateField(name, date);
304: }
305:
306: /* ------------------------------------------------------------ */
307: /**
308: * @param name
309: * @param value
310: * @see org.mortbay.jetty.HttpFields#putLongField(java.lang.String, long)
311: */
312: public void setLongHeader(String name, long value) {
313: _fields.putLongField(name, value);
314: }
315:
316: /* ------------------------------------------------------------ */
317: /**
318: * @param name
319: * @see org.mortbay.jetty.HttpFields#remove(java.lang.String)
320: */
321: public void removeHeader(String name) {
322: _fields.remove(name);
323: }
324:
325: /* ------------------------------------------------------------ */
326: public String getContent() {
327: if (_parsedContent != null)
328: return _parsedContent.toString();
329: if (_genContent != null)
330: return new String(_genContent);
331: return null;
332: }
333:
334: /* ------------------------------------------------------------ */
335: public void setContent(String content) {
336: _parsedContent = null;
337: if (content != null) {
338: _genContent = content.getBytes();
339: setLongHeader(HttpHeaders.CONTENT_LENGTH,
340: _genContent.length);
341: } else {
342: removeHeader(HttpHeaders.CONTENT_LENGTH);
343: _genContent = null;
344: }
345: }
346:
347: /* ------------------------------------------------------------ */
348: private class PH extends HttpParser.EventHandler {
349: public void startRequest(Buffer method, Buffer url,
350: Buffer version) throws IOException {
351: reset();
352: _method = method.toString();
353: _uri = url.toString();
354: _version = version.toString();
355: }
356:
357: public void startResponse(Buffer version, int status,
358: Buffer reason) throws IOException {
359: reset();
360: _version = version.toString();
361: _status = status;
362: _reason = reason.toString();
363: }
364:
365: public void parsedHeader(Buffer name, Buffer value)
366: throws IOException {
367: _fields.add(name, value);
368: }
369:
370: public void headerComplete() throws IOException {
371: }
372:
373: public void messageComplete(long contextLength)
374: throws IOException {
375: }
376:
377: public void content(Buffer ref) throws IOException {
378: if (_parsedContent == null)
379: _parsedContent = new ByteArrayOutputStream2();
380: _parsedContent.write(ref.asArray());
381: }
382: }
383:
384: }
|