1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.client;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.net.URI;
24 import java.util.concurrent.atomic.AtomicInteger;
25
26 import org.eclipse.jetty.client.security.SecurityListener;
27 import org.eclipse.jetty.http.HttpFields;
28 import org.eclipse.jetty.http.HttpHeaders;
29 import org.eclipse.jetty.http.HttpMethods;
30 import org.eclipse.jetty.http.HttpSchemes;
31 import org.eclipse.jetty.http.HttpURI;
32 import org.eclipse.jetty.http.HttpVersions;
33 import org.eclipse.jetty.io.Buffer;
34 import org.eclipse.jetty.io.BufferCache.CachedBuffer;
35 import org.eclipse.jetty.io.ByteArrayBuffer;
36 import org.eclipse.jetty.io.Connection;
37 import org.eclipse.jetty.io.EndPoint;
38 import org.eclipse.jetty.util.log.Log;
39 import org.eclipse.jetty.util.log.Logger;
40 import org.eclipse.jetty.util.thread.Timeout;
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
67
68
69
70
71
72
73
74
75
76
77
78 public class HttpExchange
79 {
80 static final Logger LOG = Log.getLogger(HttpExchange.class);
81
82 public static final int STATUS_START = 0;
83 public static final int STATUS_WAITING_FOR_CONNECTION = 1;
84 public static final int STATUS_WAITING_FOR_COMMIT = 2;
85 public static final int STATUS_SENDING_REQUEST = 3;
86 public static final int STATUS_WAITING_FOR_RESPONSE = 4;
87 public static final int STATUS_PARSING_HEADERS = 5;
88 public static final int STATUS_PARSING_CONTENT = 6;
89 public static final int STATUS_COMPLETED = 7;
90 public static final int STATUS_EXPIRED = 8;
91 public static final int STATUS_EXCEPTED = 9;
92 public static final int STATUS_CANCELLING = 10;
93 public static final int STATUS_CANCELLED = 11;
94
95
96 private String _method = HttpMethods.GET;
97 private Buffer _scheme = HttpSchemes.HTTP_BUFFER;
98 private String _uri;
99 private int _version = HttpVersions.HTTP_1_1_ORDINAL;
100 private Address _address;
101 private final HttpFields _requestFields = new HttpFields();
102 private Buffer _requestContent;
103 private InputStream _requestContentSource;
104
105 private AtomicInteger _status = new AtomicInteger(STATUS_START);
106 private boolean _retryStatus = false;
107
108 private boolean _configureListeners = true;
109 private HttpEventListener _listener = new Listener();
110 private volatile AbstractHttpConnection _connection;
111
112 private Address _localAddress = null;
113
114
115 private long _timeout = -1;
116 private volatile Timeout.Task _timeoutTask;
117 private long _lastStateChange=System.currentTimeMillis();
118 private long _sent=-1;
119 private int _lastState=-1;
120 private int _lastStatePeriod=-1;
121
122 boolean _onRequestCompleteDone;
123 boolean _onResponseCompleteDone;
124 boolean _onDone;
125
126 protected void expire(HttpDestination destination)
127 {
128 AbstractHttpConnection connection = _connection;
129 if (getStatus() < HttpExchange.STATUS_COMPLETED)
130 setStatus(HttpExchange.STATUS_EXPIRED);
131 destination.exchangeExpired(this);
132 if (connection != null)
133 connection.exchangeExpired(this);
134 }
135
136 public int getStatus()
137 {
138 return _status.get();
139 }
140
141
142
143
144
145
146
147
148 @Deprecated
149 public void waitForStatus(int status) throws InterruptedException
150 {
151 throw new UnsupportedOperationException();
152 }
153
154
155
156
157
158
159
160
161
162
163
164
165 public int waitForDone() throws InterruptedException
166 {
167 synchronized (this)
168 {
169 while (!isDone())
170 this.wait();
171 return _status.get();
172 }
173 }
174
175 public void reset()
176 {
177
178
179 synchronized (this)
180 {
181 _timeoutTask = null;
182 _onRequestCompleteDone = false;
183 _onResponseCompleteDone = false;
184 _onDone = false;
185 setStatus(STATUS_START);
186 }
187 }
188
189
190
191
192
193
194 boolean setStatus(int newStatus)
195 {
196 boolean set = false;
197 try
198 {
199 int oldStatus = _status.get();
200 boolean ignored = false;
201 if (oldStatus != newStatus)
202 {
203 long now = System.currentTimeMillis();
204 _lastStatePeriod=(int)(now-_lastStateChange);
205 _lastState=oldStatus;
206 _lastStateChange=now;
207 if (newStatus==STATUS_SENDING_REQUEST)
208 _sent=_lastStateChange;
209 }
210
211
212 switch (oldStatus)
213 {
214 case STATUS_START:
215 switch (newStatus)
216 {
217 case STATUS_START:
218 case STATUS_WAITING_FOR_CONNECTION:
219 case STATUS_WAITING_FOR_COMMIT:
220 case STATUS_CANCELLING:
221 case STATUS_EXCEPTED:
222 set = _status.compareAndSet(oldStatus,newStatus);
223 break;
224 case STATUS_EXPIRED:
225 set = setStatusExpired(newStatus,oldStatus);
226 break;
227 }
228 break;
229 case STATUS_WAITING_FOR_CONNECTION:
230 switch (newStatus)
231 {
232 case STATUS_WAITING_FOR_COMMIT:
233 case STATUS_CANCELLING:
234 case STATUS_EXCEPTED:
235 set = _status.compareAndSet(oldStatus,newStatus);
236 break;
237 case STATUS_EXPIRED:
238 set = setStatusExpired(newStatus,oldStatus);
239 break;
240 }
241 break;
242 case STATUS_WAITING_FOR_COMMIT:
243 switch (newStatus)
244 {
245 case STATUS_SENDING_REQUEST:
246 case STATUS_CANCELLING:
247 case STATUS_EXCEPTED:
248 set = _status.compareAndSet(oldStatus,newStatus);
249 break;
250 case STATUS_EXPIRED:
251 set = setStatusExpired(newStatus,oldStatus);
252 break;
253 }
254 break;
255 case STATUS_SENDING_REQUEST:
256 switch (newStatus)
257 {
258 case STATUS_WAITING_FOR_RESPONSE:
259 if (set = _status.compareAndSet(oldStatus,newStatus))
260 getEventListener().onRequestCommitted();
261 break;
262 case STATUS_CANCELLING:
263 case STATUS_EXCEPTED:
264 set = _status.compareAndSet(oldStatus,newStatus);
265 break;
266 case STATUS_EXPIRED:
267 set = setStatusExpired(newStatus,oldStatus);
268 break;
269 }
270 break;
271 case STATUS_WAITING_FOR_RESPONSE:
272 switch (newStatus)
273 {
274 case STATUS_PARSING_HEADERS:
275 case STATUS_CANCELLING:
276 case STATUS_EXCEPTED:
277 set = _status.compareAndSet(oldStatus,newStatus);
278 break;
279 case STATUS_EXPIRED:
280 set = setStatusExpired(newStatus,oldStatus);
281 break;
282 }
283 break;
284 case STATUS_PARSING_HEADERS:
285 switch (newStatus)
286 {
287 case STATUS_PARSING_CONTENT:
288 if (set = _status.compareAndSet(oldStatus,newStatus))
289 getEventListener().onResponseHeaderComplete();
290 break;
291 case STATUS_CANCELLING:
292 case STATUS_EXCEPTED:
293 set = _status.compareAndSet(oldStatus,newStatus);
294 break;
295 case STATUS_EXPIRED:
296 set = setStatusExpired(newStatus,oldStatus);
297 break;
298 }
299 break;
300 case STATUS_PARSING_CONTENT:
301 switch (newStatus)
302 {
303 case STATUS_COMPLETED:
304 if (set = _status.compareAndSet(oldStatus,newStatus))
305 getEventListener().onResponseComplete();
306 break;
307 case STATUS_CANCELLING:
308 case STATUS_EXCEPTED:
309 set = _status.compareAndSet(oldStatus,newStatus);
310 break;
311 case STATUS_EXPIRED:
312 set = setStatusExpired(newStatus,oldStatus);
313 break;
314 }
315 break;
316 case STATUS_COMPLETED:
317 switch (newStatus)
318 {
319 case STATUS_START:
320 case STATUS_EXCEPTED:
321 case STATUS_WAITING_FOR_RESPONSE:
322 set = _status.compareAndSet(oldStatus,newStatus);
323 break;
324 case STATUS_CANCELLING:
325 case STATUS_EXPIRED:
326
327 ignored = true;
328 break;
329 }
330 break;
331 case STATUS_CANCELLING:
332 switch (newStatus)
333 {
334 case STATUS_EXCEPTED:
335 case STATUS_CANCELLED:
336 if (set = _status.compareAndSet(oldStatus,newStatus))
337 done();
338 break;
339 default:
340
341 ignored = true;
342 break;
343 }
344 break;
345 case STATUS_EXCEPTED:
346 case STATUS_EXPIRED:
347 case STATUS_CANCELLED:
348 switch (newStatus)
349 {
350 case STATUS_START:
351 set = _status.compareAndSet(oldStatus,newStatus);
352 break;
353
354 case STATUS_COMPLETED:
355 ignored = true;
356 done();
357 break;
358
359 default:
360 ignored = true;
361 break;
362 }
363 break;
364 default:
365
366 throw new AssertionError(oldStatus + " => " + newStatus);
367 }
368
369 if (!set && !ignored)
370 throw new IllegalStateException(toState(oldStatus) + " => " + toState(newStatus));
371 LOG.debug("setStatus {} {}",newStatus,this);
372 }
373 catch (IOException x)
374 {
375 LOG.warn(x);
376 }
377 return set;
378 }
379
380 private boolean setStatusExpired(int newStatus, int oldStatus)
381 {
382 boolean set;
383 if (set = _status.compareAndSet(oldStatus,newStatus))
384 getEventListener().onExpire();
385 return set;
386 }
387
388 public boolean isDone()
389 {
390 synchronized (this)
391 {
392 return _onDone;
393 }
394 }
395
396
397
398
399 @Deprecated
400 public boolean isDone(int status)
401 {
402 return isDone();
403 }
404
405 public HttpEventListener getEventListener()
406 {
407 return _listener;
408 }
409
410 public void setEventListener(HttpEventListener listener)
411 {
412 _listener = listener;
413 }
414
415 public void setTimeout(long timeout)
416 {
417 _timeout = timeout;
418 }
419
420 public long getTimeout()
421 {
422 return _timeout;
423 }
424
425
426
427
428
429 public void setURL(String url)
430 {
431 setURI(URI.create(url));
432 }
433
434
435
436
437
438 public void setAddress(Address address)
439 {
440 _address = address;
441 }
442
443
444
445
446 public Address getAddress()
447 {
448 return _address;
449 }
450
451
452
453
454
455
456
457
458 public Address getLocalAddress()
459 {
460 return _localAddress;
461 }
462
463
464
465
466
467 public void setScheme(Buffer scheme)
468 {
469 _scheme = scheme;
470 }
471
472
473
474
475
476 public void setScheme(String scheme)
477 {
478 if (scheme != null)
479 {
480 if (HttpSchemes.HTTP.equalsIgnoreCase(scheme))
481 setScheme(HttpSchemes.HTTP_BUFFER);
482 else if (HttpSchemes.HTTPS.equalsIgnoreCase(scheme))
483 setScheme(HttpSchemes.HTTPS_BUFFER);
484 else
485 setScheme(new ByteArrayBuffer(scheme));
486 }
487 }
488
489
490
491
492 public Buffer getScheme()
493 {
494 return _scheme;
495 }
496
497
498
499
500
501 public void setVersion(int version)
502 {
503 _version = version;
504 }
505
506
507
508
509
510 public void setVersion(String version)
511 {
512 CachedBuffer v = HttpVersions.CACHE.get(version);
513 if (v == null)
514 _version = 10;
515 else
516 _version = v.getOrdinal();
517 }
518
519
520
521
522
523 public int getVersion()
524 {
525 return _version;
526 }
527
528
529
530
531
532 public void setMethod(String method)
533 {
534 _method = method;
535 }
536
537
538
539
540 public String getMethod()
541 {
542 return _method;
543 }
544
545
546
547
548
549
550 @Deprecated
551 public String getURI()
552 {
553 return getRequestURI();
554 }
555
556
557
558
559 public String getRequestURI()
560 {
561 return _uri;
562 }
563
564
565
566
567
568
569
570
571
572 @Deprecated
573 public void setURI(String uri)
574 {
575 setRequestURI(uri);
576 }
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595 public void setRequestURI(String uri)
596 {
597 _uri = uri;
598 }
599
600
601
602
603
604
605 public void setURI(URI uri)
606 {
607 if (!uri.isAbsolute())
608 throw new IllegalArgumentException("!Absolute URI: " + uri);
609
610 if (uri.isOpaque())
611 throw new IllegalArgumentException("Opaque URI: " + uri);
612
613 if (LOG.isDebugEnabled())
614 LOG.debug("URI = {}",uri.toASCIIString());
615
616 String scheme = uri.getScheme();
617 int port = uri.getPort();
618 if (port <= 0)
619 port = "https".equalsIgnoreCase(scheme)?443:80;
620
621 setScheme(scheme);
622 setAddress(new Address(uri.getHost(),port));
623
624 HttpURI httpUri = new HttpURI(uri);
625 String completePath = httpUri.getCompletePath();
626 setRequestURI(completePath == null?"/":completePath);
627 }
628
629
630
631
632
633
634
635
636
637 public void addRequestHeader(String name, String value)
638 {
639 getRequestFields().add(name,value);
640 }
641
642
643
644
645
646
647
648
649
650 public void addRequestHeader(Buffer name, Buffer value)
651 {
652 getRequestFields().add(name,value);
653 }
654
655
656
657
658
659
660
661
662
663 public void setRequestHeader(String name, String value)
664 {
665 getRequestFields().put(name,value);
666 }
667
668
669
670
671
672
673
674
675
676 public void setRequestHeader(Buffer name, Buffer value)
677 {
678 getRequestFields().put(name,value);
679 }
680
681
682
683
684
685 public void setRequestContentType(String value)
686 {
687 getRequestFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,value);
688 }
689
690
691
692
693 public HttpFields getRequestFields()
694 {
695 return _requestFields;
696 }
697
698
699
700
701
702 public void setRequestContent(Buffer requestContent)
703 {
704 _requestContent = requestContent;
705 }
706
707
708
709
710
711 public void setRequestContentSource(InputStream stream)
712 {
713 _requestContentSource = stream;
714 if (_requestContentSource != null && _requestContentSource.markSupported())
715 _requestContentSource.mark(Integer.MAX_VALUE);
716 }
717
718
719
720
721 public InputStream getRequestContentSource()
722 {
723 return _requestContentSource;
724 }
725
726 public Buffer getRequestContentChunk(Buffer buffer) throws IOException
727 {
728 synchronized (this)
729 {
730 if (_requestContentSource!=null)
731 {
732 if (buffer == null)
733 buffer = new ByteArrayBuffer(8192);
734
735 int space = buffer.space();
736 int length = _requestContentSource.read(buffer.array(),buffer.putIndex(),space);
737 if (length >= 0)
738 {
739 buffer.setPutIndex(buffer.putIndex()+length);
740 return buffer;
741 }
742 }
743 return null;
744 }
745 }
746
747
748
749
750 public Buffer getRequestContent()
751 {
752 return _requestContent;
753 }
754
755
756
757
758 public boolean getRetryStatus()
759 {
760 return _retryStatus;
761 }
762
763
764
765
766
767 public void setRetryStatus(boolean retryStatus)
768 {
769 _retryStatus = retryStatus;
770 }
771
772
773
774
775
776
777
778 public void cancel()
779 {
780 setStatus(STATUS_CANCELLING);
781 abort();
782 }
783
784 private void done()
785 {
786 synchronized (this)
787 {
788 disassociate();
789 _onDone = true;
790 notifyAll();
791 }
792 }
793
794 private void abort()
795 {
796 AbstractHttpConnection httpConnection = _connection;
797 if (httpConnection != null)
798 {
799 try
800 {
801
802
803 httpConnection.close();
804 }
805 catch (IOException x)
806 {
807 LOG.debug(x);
808 }
809 finally
810 {
811 disassociate();
812 }
813 }
814 }
815
816 void associate(AbstractHttpConnection connection)
817 {
818 if (connection.getEndPoint().getLocalAddr() != null)
819 _localAddress = new Address(connection.getEndPoint().getLocalAddr(),connection.getEndPoint().getLocalPort());
820
821 _connection = connection;
822 if (getStatus() == STATUS_CANCELLING)
823 abort();
824 }
825
826 boolean isAssociated()
827 {
828 return this._connection != null;
829 }
830
831 AbstractHttpConnection disassociate()
832 {
833 AbstractHttpConnection result = _connection;
834 this._connection = null;
835 if (getStatus() == STATUS_CANCELLING)
836 setStatus(STATUS_CANCELLED);
837 return result;
838 }
839
840 public static String toState(int s)
841 {
842 String state;
843 switch (s)
844 {
845 case STATUS_START:
846 state = "START";
847 break;
848 case STATUS_WAITING_FOR_CONNECTION:
849 state = "CONNECTING";
850 break;
851 case STATUS_WAITING_FOR_COMMIT:
852 state = "CONNECTED";
853 break;
854 case STATUS_SENDING_REQUEST:
855 state = "SENDING";
856 break;
857 case STATUS_WAITING_FOR_RESPONSE:
858 state = "WAITING";
859 break;
860 case STATUS_PARSING_HEADERS:
861 state = "HEADERS";
862 break;
863 case STATUS_PARSING_CONTENT:
864 state = "CONTENT";
865 break;
866 case STATUS_COMPLETED:
867 state = "COMPLETED";
868 break;
869 case STATUS_EXPIRED:
870 state = "EXPIRED";
871 break;
872 case STATUS_EXCEPTED:
873 state = "EXCEPTED";
874 break;
875 case STATUS_CANCELLING:
876 state = "CANCELLING";
877 break;
878 case STATUS_CANCELLED:
879 state = "CANCELLED";
880 break;
881 default:
882 state = "UNKNOWN";
883 }
884 return state;
885 }
886
887 @Override
888 public String toString()
889 {
890 String state=toState(getStatus());
891 long now=System.currentTimeMillis();
892 long forMs = now -_lastStateChange;
893 String s= _lastState>=0
894 ?String.format("%s@%x=%s//%s%s#%s(%dms)->%s(%dms)",getClass().getSimpleName(),hashCode(),_method,_address,_uri,toState(_lastState),_lastStatePeriod,state,forMs)
895 :String.format("%s@%x=%s//%s%s#%s(%dms)",getClass().getSimpleName(),hashCode(),_method,_address,_uri,state,forMs);
896 if (getStatus()>=STATUS_SENDING_REQUEST && _sent>0)
897 s+="sent="+(now-_sent)+"ms";
898 return s;
899 }
900
901
902
903 protected Connection onSwitchProtocol(EndPoint endp) throws IOException
904 {
905 return null;
906 }
907
908
909
910
911
912
913
914 protected void onRequestCommitted() throws IOException
915 {
916 }
917
918
919
920
921
922
923
924 protected void onRequestComplete() throws IOException
925 {
926 }
927
928
929
930
931
932
933
934
935
936
937
938
939
940 protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
941 {
942 }
943
944
945
946
947
948
949
950
951
952
953
954 protected void onResponseHeader(Buffer name, Buffer value) throws IOException
955 {
956 }
957
958
959
960
961
962
963
964 protected void onResponseHeaderComplete() throws IOException
965 {
966 }
967
968
969
970
971
972
973
974
975
976 protected void onResponseContent(Buffer content) throws IOException
977 {
978 }
979
980
981
982
983
984
985
986 protected void onResponseComplete() throws IOException
987 {
988 }
989
990
991
992
993
994
995
996
997 protected void onConnectionFailed(Throwable x)
998 {
999 LOG.warn("CONNECTION FAILED " + this,x);
1000 }
1001
1002
1003
1004
1005
1006
1007
1008 protected void onException(Throwable x)
1009 {
1010 LOG.warn("EXCEPTION " + this,x);
1011 }
1012
1013
1014
1015
1016 protected void onExpire()
1017 {
1018 LOG.warn("EXPIRED " + this);
1019 }
1020
1021
1022
1023
1024
1025
1026
1027 protected void onRetry() throws IOException
1028 {
1029 if (_requestContentSource != null)
1030 {
1031 if (_requestContentSource.markSupported())
1032 {
1033 _requestContent = null;
1034 _requestContentSource.reset();
1035 }
1036 else
1037 {
1038 throw new IOException("Unsupported retry attempt");
1039 }
1040 }
1041 }
1042
1043
1044
1045
1046
1047 public boolean configureListeners()
1048 {
1049 return _configureListeners;
1050 }
1051
1052
1053
1054
1055
1056 public void setConfigureListeners(boolean autoConfigure)
1057 {
1058 this._configureListeners = autoConfigure;
1059 }
1060
1061 protected void scheduleTimeout(final HttpDestination destination)
1062 {
1063 assert _timeoutTask == null;
1064
1065 _timeoutTask = new Timeout.Task()
1066 {
1067 @Override
1068 public void expired()
1069 {
1070 HttpExchange.this.expire(destination);
1071 }
1072 };
1073
1074 HttpClient httpClient = destination.getHttpClient();
1075 long timeout = getTimeout();
1076 if (timeout > 0)
1077 httpClient.schedule(_timeoutTask,timeout);
1078 else
1079 httpClient.schedule(_timeoutTask);
1080 }
1081
1082 protected void cancelTimeout(HttpClient httpClient)
1083 {
1084 Timeout.Task task = _timeoutTask;
1085 if (task != null)
1086 httpClient.cancel(task);
1087 _timeoutTask = null;
1088 }
1089
1090 private class Listener implements HttpEventListener
1091 {
1092 public void onConnectionFailed(Throwable ex)
1093 {
1094 try
1095 {
1096 HttpExchange.this.onConnectionFailed(ex);
1097 }
1098 finally
1099 {
1100 done();
1101 }
1102 }
1103
1104 public void onException(Throwable ex)
1105 {
1106 try
1107 {
1108 HttpExchange.this.onException(ex);
1109 }
1110 finally
1111 {
1112 done();
1113 }
1114 }
1115
1116 public void onExpire()
1117 {
1118 try
1119 {
1120 HttpExchange.this.onExpire();
1121 }
1122 finally
1123 {
1124 done();
1125 }
1126 }
1127
1128 public void onRequestCommitted() throws IOException
1129 {
1130 HttpExchange.this.onRequestCommitted();
1131 }
1132
1133 public void onRequestComplete() throws IOException
1134 {
1135 try
1136 {
1137 HttpExchange.this.onRequestComplete();
1138 }
1139 finally
1140 {
1141 synchronized (HttpExchange.this)
1142 {
1143 _onRequestCompleteDone = true;
1144
1145
1146 _onDone |= _onResponseCompleteDone;
1147 if (_onDone)
1148 disassociate();
1149 HttpExchange.this.notifyAll();
1150 }
1151 }
1152 }
1153
1154 public void onResponseComplete() throws IOException
1155 {
1156 try
1157 {
1158 HttpExchange.this.onResponseComplete();
1159 }
1160 finally
1161 {
1162 synchronized (HttpExchange.this)
1163 {
1164 _onResponseCompleteDone = true;
1165
1166
1167 _onDone |= _onRequestCompleteDone;
1168 if (_onDone)
1169 disassociate();
1170 HttpExchange.this.notifyAll();
1171 }
1172 }
1173 }
1174
1175 public void onResponseContent(Buffer content) throws IOException
1176 {
1177 HttpExchange.this.onResponseContent(content);
1178 }
1179
1180 public void onResponseHeader(Buffer name, Buffer value) throws IOException
1181 {
1182 HttpExchange.this.onResponseHeader(name,value);
1183 }
1184
1185 public void onResponseHeaderComplete() throws IOException
1186 {
1187 HttpExchange.this.onResponseHeaderComplete();
1188 }
1189
1190 public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
1191 {
1192 HttpExchange.this.onResponseStatus(version,status,reason);
1193 }
1194
1195 public void onRetry()
1196 {
1197 HttpExchange.this.setRetryStatus(true);
1198 try
1199 {
1200 HttpExchange.this.onRetry();
1201 }
1202 catch (IOException e)
1203 {
1204 LOG.debug(e);
1205 }
1206 }
1207 }
1208
1209
1210
1211
1212 @Deprecated
1213 public static class CachedExchange extends org.eclipse.jetty.client.CachedExchange
1214 {
1215 public CachedExchange(boolean cacheFields)
1216 {
1217 super(cacheFields);
1218 }
1219 }
1220
1221
1222
1223
1224 @Deprecated
1225 public static class ContentExchange extends org.eclipse.jetty.client.ContentExchange
1226 {
1227 }
1228 }