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