1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.client.http;
20
21 import org.eclipse.jetty.client.HttpChannel;
22 import org.eclipse.jetty.client.HttpExchange;
23 import org.eclipse.jetty.client.api.Response;
24 import org.eclipse.jetty.client.api.Result;
25 import org.eclipse.jetty.http.HttpFields;
26 import org.eclipse.jetty.http.HttpHeader;
27 import org.eclipse.jetty.http.HttpHeaderValue;
28 import org.eclipse.jetty.http.HttpVersion;
29
30 public class HttpChannelOverHTTP extends HttpChannel
31 {
32 private final HttpConnectionOverHTTP connection;
33 private final HttpSenderOverHTTP sender;
34 private final HttpReceiverOverHTTP receiver;
35
36 public HttpChannelOverHTTP(HttpConnectionOverHTTP connection)
37 {
38 super(connection.getHttpDestination());
39 this.connection = connection;
40 this.sender = newHttpSender();
41 this.receiver = newHttpReceiver();
42 }
43
44 protected HttpSenderOverHTTP newHttpSender()
45 {
46 return new HttpSenderOverHTTP(this);
47 }
48
49 protected HttpReceiverOverHTTP newHttpReceiver()
50 {
51 return new HttpReceiverOverHTTP(this);
52 }
53
54 public HttpConnectionOverHTTP getHttpConnection()
55 {
56 return connection;
57 }
58
59 @Override
60 public void send()
61 {
62 HttpExchange exchange = getHttpExchange();
63 if (exchange != null)
64 sender.send(exchange);
65 }
66
67 @Override
68 public void proceed(HttpExchange exchange, Throwable failure)
69 {
70 sender.proceed(exchange, failure);
71 }
72
73 @Override
74 public boolean abort(Throwable cause)
75 {
76 boolean sendAborted = sender.abort(cause);
77 boolean receiveAborted = abortResponse(cause);
78 return sendAborted || receiveAborted;
79 }
80
81 @Override
82 public boolean abortResponse(Throwable cause)
83 {
84 return receiver.abort(cause);
85 }
86
87 public void receive()
88 {
89 receiver.receive();
90 }
91
92 @Override
93 public void exchangeTerminated(Result result)
94 {
95 super.exchangeTerminated(result);
96 Response response = result.getResponse();
97 HttpFields responseHeaders = response.getHeaders();
98 boolean close = result.isFailed() || receiver.isShutdown();
99
100 if (!close)
101 {
102 if (response.getVersion().compareTo(HttpVersion.HTTP_1_1) < 0)
103 {
104
105 close = !responseHeaders.contains(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE.asString());
106 }
107 else
108 {
109
110 close = responseHeaders.contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString());
111 }
112 }
113 if (close)
114 connection.close();
115 else
116 connection.release();
117 }
118
119 @Override
120 public String toString()
121 {
122 return String.format("%s@%x(send=%s,recv=%s)",
123 getClass().getSimpleName(),
124 hashCode(),
125 sender,
126 receiver);
127 }
128 }