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