1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.fcgi.client.http;
20
21 import java.nio.ByteBuffer;
22 import java.util.concurrent.TimeoutException;
23
24 import org.eclipse.jetty.client.HttpChannel;
25 import org.eclipse.jetty.client.HttpExchange;
26 import org.eclipse.jetty.client.HttpReceiver;
27 import org.eclipse.jetty.client.HttpSender;
28 import org.eclipse.jetty.client.api.Result;
29 import org.eclipse.jetty.fcgi.generator.Flusher;
30 import org.eclipse.jetty.fcgi.generator.Generator;
31 import org.eclipse.jetty.http.HttpField;
32 import org.eclipse.jetty.http.HttpFields;
33 import org.eclipse.jetty.http.HttpVersion;
34 import org.eclipse.jetty.io.IdleTimeout;
35 import org.eclipse.jetty.util.Callback;
36
37 public class HttpChannelOverFCGI extends HttpChannel
38 {
39 private final HttpConnectionOverFCGI connection;
40 private final Flusher flusher;
41 private final int request;
42 private final HttpSenderOverFCGI sender;
43 private final HttpReceiverOverFCGI receiver;
44 private final FCGIIdleTimeout idle;
45 private HttpVersion version;
46
47 public HttpChannelOverFCGI(final HttpConnectionOverFCGI connection, Flusher flusher, int request, long idleTimeout)
48 {
49 super(connection.getHttpDestination());
50 this.connection = connection;
51 this.flusher = flusher;
52 this.request = request;
53 this.sender = new HttpSenderOverFCGI(this);
54 this.receiver = new HttpReceiverOverFCGI(this);
55 this.idle = new FCGIIdleTimeout(connection, idleTimeout);
56 }
57
58 protected int getRequest()
59 {
60 return request;
61 }
62
63 @Override
64 protected HttpSender getHttpSender()
65 {
66 return sender;
67 }
68
69 @Override
70 protected HttpReceiver getHttpReceiver()
71 {
72 return receiver;
73 }
74
75 @Override
76 public void send()
77 {
78 HttpExchange exchange = getHttpExchange();
79 if (exchange != null)
80 {
81 version = exchange.getRequest().getVersion();
82 idle.onOpen();
83 sender.send(exchange);
84 }
85 }
86
87 @Override
88 public void release()
89 {
90 connection.release(this);
91 }
92
93 protected boolean responseBegin(int code, String reason)
94 {
95 idle.notIdle();
96 HttpExchange exchange = getHttpExchange();
97 if (exchange == null)
98 return false;
99 exchange.getResponse().version(version).status(code).reason(reason);
100 return receiver.responseBegin(exchange);
101 }
102
103 protected boolean responseHeader(HttpField field)
104 {
105 HttpExchange exchange = getHttpExchange();
106 return exchange != null && receiver.responseHeader(exchange, field);
107 }
108
109 protected boolean responseHeaders()
110 {
111 idle.notIdle();
112 HttpExchange exchange = getHttpExchange();
113 return exchange != null && receiver.responseHeaders(exchange);
114 }
115
116 protected boolean content(ByteBuffer buffer, Callback callback)
117 {
118 idle.notIdle();
119 HttpExchange exchange = getHttpExchange();
120 if (exchange != null)
121 return receiver.responseContent(exchange, buffer, callback);
122 callback.succeeded();
123 return false;
124 }
125
126 protected boolean responseSuccess()
127 {
128 HttpExchange exchange = getHttpExchange();
129 return exchange != null && receiver.responseSuccess(exchange);
130 }
131
132 protected boolean responseFailure(Throwable failure)
133 {
134 HttpExchange exchange = getHttpExchange();
135 return exchange != null && receiver.responseFailure(failure);
136 }
137
138 @Override
139 public void exchangeTerminated(HttpExchange exchange, Result result)
140 {
141 super.exchangeTerminated(exchange, result);
142 idle.onClose();
143 HttpFields responseHeaders = result.getResponse().getHeaders();
144 if (result.isFailed())
145 connection.close(result.getFailure());
146 else if (!connection.closeByHTTP(responseHeaders))
147 release();
148 }
149
150 protected void flush(Generator.Result... results)
151 {
152 flusher.flush(results);
153 }
154
155 private class FCGIIdleTimeout extends IdleTimeout
156 {
157 private final HttpConnectionOverFCGI connection;
158 private boolean open;
159
160 public FCGIIdleTimeout(HttpConnectionOverFCGI connection, long idleTimeout)
161 {
162 super(connection.getHttpDestination().getHttpClient().getScheduler());
163 this.connection = connection;
164 setIdleTimeout(idleTimeout);
165 }
166
167 @Override
168 public void onOpen()
169 {
170 open = true;
171 notIdle();
172 super.onOpen();
173 }
174
175 @Override
176 public void onClose()
177 {
178 super.onClose();
179 open = false;
180 }
181
182 @Override
183 protected void onIdleExpired(TimeoutException timeout)
184 {
185 if (LOG.isDebugEnabled())
186 LOG.debug("Idle timeout for request {}", request);
187 connection.abort(timeout);
188 }
189
190 @Override
191 public boolean isOpen()
192 {
193 return open;
194 }
195 }
196 }