1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.jetty.client;
16
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.net.InetSocketAddress;
20
21 import org.mortbay.io.Buffer;
22 import org.mortbay.io.BufferCache.CachedBuffer;
23 import org.mortbay.io.ByteArrayBuffer;
24 import org.mortbay.jetty.HttpFields;
25 import org.mortbay.jetty.HttpHeaders;
26 import org.mortbay.jetty.HttpMethods;
27 import org.mortbay.jetty.HttpSchemes;
28 import org.mortbay.jetty.HttpURI;
29 import org.mortbay.jetty.HttpVersions;
30 import org.mortbay.log.Log;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public class HttpExchange
66 {
67 public static final int STATUS_START = 0;
68 public static final int STATUS_WAITING_FOR_CONNECTION = 1;
69 public static final int STATUS_WAITING_FOR_COMMIT = 2;
70 public static final int STATUS_SENDING_REQUEST = 3;
71 public static final int STATUS_WAITING_FOR_RESPONSE = 4;
72 public static final int STATUS_PARSING_HEADERS = 5;
73 public static final int STATUS_PARSING_CONTENT = 6;
74 public static final int STATUS_COMPLETED = 7;
75 public static final int STATUS_EXPIRED = 8;
76 public static final int STATUS_EXCEPTED = 9;
77
78 Address _address;
79 String _method = HttpMethods.GET;
80 Buffer _scheme = HttpSchemes.HTTP_BUFFER;
81 int _version = HttpVersions.HTTP_1_1_ORDINAL;
82 String _uri;
83 int _status = STATUS_START;
84 HttpFields _requestFields = new HttpFields();
85 Buffer _requestContent;
86 InputStream _requestContentSource;
87 Buffer _requestContentChunk;
88 boolean _retryStatus = false;
89
90
91
92
93
94
95 boolean _configureListeners = true;
96
97
98 private HttpEventListener _listener = new Listener();
99
100
101
102
103
104
105
106 public int getStatus()
107 {
108 return _status;
109 }
110
111
112
113
114
115 public void waitForStatus(int status) throws InterruptedException
116 {
117 synchronized (this)
118 {
119 while (_status < status)
120 {
121 this.wait();
122 }
123 }
124 }
125
126
127 public int waitForDone () throws InterruptedException
128 {
129 synchronized (this)
130 {
131 while (!isDone(_status))
132 this.wait();
133 }
134 return _status;
135 }
136
137
138
139
140
141 public void reset()
142 {
143 setStatus(STATUS_START);
144 }
145
146
147 void setStatus(int status)
148 {
149 synchronized (this)
150 {
151 _status = status;
152 this.notifyAll();
153
154 try
155 {
156 switch (status)
157 {
158 case STATUS_WAITING_FOR_CONNECTION:
159 break;
160
161 case STATUS_WAITING_FOR_COMMIT:
162 break;
163
164 case STATUS_SENDING_REQUEST:
165 break;
166
167 case HttpExchange.STATUS_WAITING_FOR_RESPONSE:
168 getEventListener().onRequestCommitted();
169 break;
170
171 case STATUS_PARSING_HEADERS:
172 break;
173
174 case STATUS_PARSING_CONTENT:
175 getEventListener().onResponseHeaderComplete();
176 break;
177
178 case STATUS_COMPLETED:
179 getEventListener().onResponseComplete();
180 break;
181
182 case STATUS_EXPIRED:
183 getEventListener().onExpire();
184 break;
185
186 }
187 }
188 catch (IOException e)
189 {
190 Log.warn(e);
191 }
192 }
193 }
194
195
196 public boolean isDone (int status)
197 {
198 return ((status == STATUS_COMPLETED) || (status == STATUS_EXPIRED) || (status == STATUS_EXCEPTED));
199 }
200
201
202 public HttpEventListener getEventListener()
203 {
204 return _listener;
205 }
206
207
208 public void setEventListener(HttpEventListener listener)
209 {
210 _listener=listener;
211 }
212
213
214
215
216
217 public void setURL(String url)
218 {
219 HttpURI uri = new HttpURI(url);
220 String scheme = uri.getScheme();
221 if (scheme != null)
222 {
223 if (HttpSchemes.HTTP.equalsIgnoreCase(scheme))
224 setScheme(HttpSchemes.HTTP_BUFFER);
225 else if (HttpSchemes.HTTPS.equalsIgnoreCase(scheme))
226 setScheme(HttpSchemes.HTTPS_BUFFER);
227 else
228 setScheme(new ByteArrayBuffer(scheme));
229 }
230
231 int port = uri.getPort();
232 if (port <= 0)
233 port = "https".equalsIgnoreCase(scheme)?443:80;
234
235 setAddress(new Address(uri.getHost(),port));
236
237 String completePath = uri.getCompletePath();
238 if (completePath != null)
239 setURI(completePath);
240 }
241
242
243
244
245
246 public void setAddress(Address address)
247 {
248 _address = address;
249 }
250
251
252
253
254
255 public Address getAddress()
256 {
257 return _address;
258 }
259
260
261
262
263
264 public void setScheme(Buffer scheme)
265 {
266 _scheme = scheme;
267 }
268
269
270
271
272
273 public Buffer getScheme()
274 {
275 return _scheme;
276 }
277
278
279
280
281
282 public void setVersion(int version)
283 {
284 _version = version;
285 }
286
287
288 public void setVersion(String version)
289 {
290 CachedBuffer v = HttpVersions.CACHE.get(version);
291 if (v == null)
292 _version = 10;
293 else
294 _version = v.getOrdinal();
295 }
296
297
298
299
300
301 public int getVersion()
302 {
303 return _version;
304 }
305
306
307
308
309
310 public void setMethod(String method)
311 {
312 _method = method;
313 }
314
315
316
317
318
319 public String getMethod()
320 {
321 return _method;
322 }
323
324
325
326
327
328 public String getURI()
329 {
330 return _uri;
331 }
332
333
334
335
336
337 public void setURI(String uri)
338 {
339 _uri = uri;
340 }
341
342
343
344
345
346
347 public void addRequestHeader(String name, String value)
348 {
349 getRequestFields().add(name,value);
350 }
351
352
353
354
355
356
357 public void addRequestHeader(Buffer name, Buffer value)
358 {
359 getRequestFields().add(name,value);
360 }
361
362
363
364
365
366
367 public void setRequestHeader(String name, String value)
368 {
369 getRequestFields().put(name,value);
370 }
371
372
373
374
375
376
377 public void setRequestHeader(Buffer name, Buffer value)
378 {
379 getRequestFields().put(name,value);
380 }
381
382
383
384
385
386 public void setRequestContentType(String value)
387 {
388 getRequestFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,value);
389 }
390
391
392
393
394
395 public HttpFields getRequestFields()
396 {
397 return _requestFields;
398 }
399
400
401
402
403
404
405
406
407
408
409 public void setRequestContent(Buffer requestContent)
410 {
411 _requestContent = requestContent;
412 }
413
414
415
416
417
418 public void setRequestContentSource(InputStream in)
419 {
420 _requestContentSource = in;
421 }
422
423
424 public InputStream getRequestContentSource()
425 {
426 return _requestContentSource;
427 }
428
429
430 public Buffer getRequestContentChunk() throws IOException
431 {
432 synchronized (this)
433 {
434 if (_requestContentChunk == null)
435 _requestContentChunk = new ByteArrayBuffer(4096);
436 else
437 {
438 if (_requestContentChunk.hasContent())
439 throw new IllegalStateException();
440 _requestContentChunk.clear();
441 }
442
443 int read = _requestContentChunk.capacity();
444 int length = _requestContentSource.read(_requestContentChunk.array(),0,read);
445 if (length >= 0)
446 {
447 _requestContentChunk.setPutIndex(length);
448 return _requestContentChunk;
449 }
450 return null;
451 }
452 }
453
454
455 public Buffer getRequestContent()
456 {
457 return _requestContent;
458 }
459
460 public boolean getRetryStatus()
461 {
462 return _retryStatus;
463 }
464
465 public void setRetryStatus( boolean retryStatus )
466 {
467 _retryStatus = retryStatus;
468 }
469
470
471
472
473
474 public void cancel()
475 {
476
477 }
478
479
480 public String toString()
481 {
482 return "HttpExchange@" + hashCode() + "=" + _method + "//" + _address.getHost() + ":" + _address.getPort() + _uri + "#" + _status;
483 }
484
485
486
487
488
489
490
491 protected void onRequestCommitted() throws IOException
492 {
493 }
494
495 protected void onRequestComplete() throws IOException
496 {
497 }
498
499 protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
500 {
501 }
502
503 protected void onResponseHeader(Buffer name, Buffer value) throws IOException
504 {
505 }
506
507 protected void onResponseHeaderComplete() throws IOException
508 {
509 }
510
511 protected void onResponseContent(Buffer content) throws IOException
512 {
513 }
514
515 protected void onResponseComplete() throws IOException
516 {
517 }
518
519 protected void onConnectionFailed(Throwable ex)
520 {
521 Log.warn("CONNECTION FAILED on " + this,ex);
522 }
523
524 protected void onException(Throwable ex)
525 {
526
527 Log.warn("EXCEPTION on " + this,ex);
528 }
529
530 protected void onExpire()
531 {
532 Log.debug("EXPIRED " + this);
533 }
534
535 protected void onRetry() throws IOException
536 {}
537
538
539
540
541
542
543
544
545 public boolean configureListeners()
546 {
547 return _configureListeners;
548 }
549
550 public void setConfigureListeners(boolean autoConfigure )
551 {
552 this._configureListeners = autoConfigure;
553 }
554
555 private class Listener implements HttpEventListener
556 {
557 public void onConnectionFailed(Throwable ex)
558 {
559 HttpExchange.this.onConnectionFailed(ex);
560 }
561
562 public void onException(Throwable ex)
563 {
564 HttpExchange.this.onException(ex);
565 }
566
567 public void onExpire()
568 {
569 HttpExchange.this.onExpire();
570 }
571
572 public void onRequestCommitted() throws IOException
573 {
574 HttpExchange.this.onRequestCommitted();
575 }
576
577 public void onRequestComplete() throws IOException
578 {
579 HttpExchange.this.onRequestComplete();
580 }
581
582 public void onResponseComplete() throws IOException
583 {
584 HttpExchange.this.onResponseComplete();
585 }
586
587 public void onResponseContent(Buffer content) throws IOException
588 {
589 HttpExchange.this.onResponseContent(content);
590 }
591
592 public void onResponseHeader(Buffer name, Buffer value) throws IOException
593 {
594 HttpExchange.this.onResponseHeader(name,value);
595 }
596
597 public void onResponseHeaderComplete() throws IOException
598 {
599 HttpExchange.this.onResponseHeaderComplete();
600 }
601
602 public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
603 {
604 HttpExchange.this.onResponseStatus(version,status,reason);
605 }
606
607 public void onRetry()
608 {
609 HttpExchange.this.setRetryStatus( true );
610 try
611 {
612 HttpExchange.this.onRetry();
613 }
614 catch (IOException e)
615 {
616 e.printStackTrace();
617 }
618 }
619 }
620
621
622
623
624
625 public static class CachedExchange extends org.mortbay.jetty.client.CachedExchange
626 {
627 public CachedExchange(boolean cacheFields)
628 {
629 super(cacheFields);
630 }
631 }
632
633
634
635
636
637 public static class ContentExchange extends org.mortbay.jetty.client.ContentExchange
638 {
639
640 }
641
642
643
644 }