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 completePath = "/";
240
241 setURI(completePath);
242 }
243
244
245
246
247
248 public void setAddress(Address address)
249 {
250 _address = address;
251 }
252
253
254
255
256
257 public Address getAddress()
258 {
259 return _address;
260 }
261
262
263
264
265
266 public void setScheme(Buffer scheme)
267 {
268 _scheme = scheme;
269 }
270
271
272
273
274
275 public Buffer getScheme()
276 {
277 return _scheme;
278 }
279
280
281
282
283
284 public void setVersion(int version)
285 {
286 _version = version;
287 }
288
289
290 public void setVersion(String version)
291 {
292 CachedBuffer v = HttpVersions.CACHE.get(version);
293 if (v == null)
294 _version = 10;
295 else
296 _version = v.getOrdinal();
297 }
298
299
300
301
302
303 public int getVersion()
304 {
305 return _version;
306 }
307
308
309
310
311
312 public void setMethod(String method)
313 {
314 _method = method;
315 }
316
317
318
319
320
321 public String getMethod()
322 {
323 return _method;
324 }
325
326
327
328
329
330 public String getURI()
331 {
332 return _uri;
333 }
334
335
336
337
338
339 public void setURI(String uri)
340 {
341 _uri = uri;
342 }
343
344
345
346
347
348
349 public void addRequestHeader(String name, String value)
350 {
351 getRequestFields().add(name,value);
352 }
353
354
355
356
357
358
359 public void addRequestHeader(Buffer name, Buffer value)
360 {
361 getRequestFields().add(name,value);
362 }
363
364
365
366
367
368
369 public void setRequestHeader(String name, String value)
370 {
371 getRequestFields().put(name,value);
372 }
373
374
375
376
377
378
379 public void setRequestHeader(Buffer name, Buffer value)
380 {
381 getRequestFields().put(name,value);
382 }
383
384
385
386
387
388 public void setRequestContentType(String value)
389 {
390 getRequestFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,value);
391 }
392
393
394
395
396
397 public HttpFields getRequestFields()
398 {
399 return _requestFields;
400 }
401
402
403
404
405
406
407
408
409
410
411 public void setRequestContent(Buffer requestContent)
412 {
413 _requestContent = requestContent;
414 }
415
416
417
418
419
420 public void setRequestContentSource(InputStream in)
421 {
422 _requestContentSource = in;
423 }
424
425
426 public InputStream getRequestContentSource()
427 {
428 return _requestContentSource;
429 }
430
431
432 public Buffer getRequestContentChunk() throws IOException
433 {
434 synchronized (this)
435 {
436 if (_requestContentChunk == null)
437 _requestContentChunk = new ByteArrayBuffer(4096);
438 else
439 {
440 if (_requestContentChunk.hasContent())
441 throw new IllegalStateException();
442 _requestContentChunk.clear();
443 }
444
445 int read = _requestContentChunk.capacity();
446 int length = _requestContentSource.read(_requestContentChunk.array(),0,read);
447 if (length >= 0)
448 {
449 _requestContentChunk.setPutIndex(length);
450 return _requestContentChunk;
451 }
452 return null;
453 }
454 }
455
456
457 public Buffer getRequestContent()
458 {
459 return _requestContent;
460 }
461
462 public boolean getRetryStatus()
463 {
464 return _retryStatus;
465 }
466
467 public void setRetryStatus( boolean retryStatus )
468 {
469 _retryStatus = retryStatus;
470 }
471
472
473
474
475
476 public void cancel()
477 {
478
479 }
480
481
482 public String toString()
483 {
484 return "HttpExchange@" + hashCode() + "=" + _method + "//" + _address.getHost() + ":" + _address.getPort() + _uri + "#" + _status;
485 }
486
487
488
489
490
491
492
493 protected void onRequestCommitted() throws IOException
494 {
495 }
496
497 protected void onRequestComplete() throws IOException
498 {
499 }
500
501 protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
502 {
503 }
504
505 protected void onResponseHeader(Buffer name, Buffer value) throws IOException
506 {
507 }
508
509 protected void onResponseHeaderComplete() throws IOException
510 {
511 }
512
513 protected void onResponseContent(Buffer content) throws IOException
514 {
515 }
516
517 protected void onResponseComplete() throws IOException
518 {
519 }
520
521 protected void onConnectionFailed(Throwable ex)
522 {
523 Log.warn("CONNECTION FAILED on " + this,ex);
524 }
525
526 protected void onException(Throwable ex)
527 {
528 Log.warn("EXCEPTION on " + this,ex);
529 }
530
531 protected void onExpire()
532 {
533 Log.warn("EXPIRED " + this);
534 }
535
536 protected void onRetry() throws IOException
537 {}
538
539
540
541
542
543
544
545
546 public boolean configureListeners()
547 {
548 return _configureListeners;
549 }
550
551 public void setConfigureListeners(boolean autoConfigure )
552 {
553 this._configureListeners = autoConfigure;
554 }
555
556 private class Listener implements HttpEventListener
557 {
558 public void onConnectionFailed(Throwable ex)
559 {
560 HttpExchange.this.onConnectionFailed(ex);
561 }
562
563 public void onException(Throwable ex)
564 {
565 HttpExchange.this.onException(ex);
566 }
567
568 public void onExpire()
569 {
570 HttpExchange.this.onExpire();
571 }
572
573 public void onRequestCommitted() throws IOException
574 {
575 HttpExchange.this.onRequestCommitted();
576 }
577
578 public void onRequestComplete() throws IOException
579 {
580 HttpExchange.this.onRequestComplete();
581 }
582
583 public void onResponseComplete() throws IOException
584 {
585 HttpExchange.this.onResponseComplete();
586 }
587
588 public void onResponseContent(Buffer content) throws IOException
589 {
590 HttpExchange.this.onResponseContent(content);
591 }
592
593 public void onResponseHeader(Buffer name, Buffer value) throws IOException
594 {
595 HttpExchange.this.onResponseHeader(name,value);
596 }
597
598 public void onResponseHeaderComplete() throws IOException
599 {
600 HttpExchange.this.onResponseHeaderComplete();
601 }
602
603 public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
604 {
605 HttpExchange.this.onResponseStatus(version,status,reason);
606 }
607
608 public void onRetry()
609 {
610 HttpExchange.this.setRetryStatus( true );
611 try
612 {
613 HttpExchange.this.onRetry();
614 }
615 catch (IOException e)
616 {
617 e.printStackTrace();
618 }
619 }
620 }
621
622
623
624
625
626 public static class CachedExchange extends org.mortbay.jetty.client.CachedExchange
627 {
628 public CachedExchange(boolean cacheFields)
629 {
630 super(cacheFields);
631 }
632 }
633
634
635
636
637
638 public static class ContentExchange extends org.mortbay.jetty.client.ContentExchange
639 {
640
641 }
642
643
644
645 }