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.api.Result;
27 import org.eclipse.jetty.fcgi.generator.Flusher;
28 import org.eclipse.jetty.fcgi.generator.Generator;
29 import org.eclipse.jetty.http.HttpField;
30 import org.eclipse.jetty.http.HttpFields;
31 import org.eclipse.jetty.http.HttpVersion;
32 import org.eclipse.jetty.io.IdleTimeout;
33 import org.eclipse.jetty.util.Callback;
34
35 public class HttpChannelOverFCGI extends HttpChannel
36 {
37 private final HttpConnectionOverFCGI connection;
38 private final Flusher flusher;
39 private final int request;
40 private final HttpSenderOverFCGI sender;
41 private final HttpReceiverOverFCGI receiver;
42 private final FCGIIdleTimeout idle;
43 private HttpVersion version;
44
45 public HttpChannelOverFCGI(final HttpConnectionOverFCGI connection, Flusher flusher, int request, long idleTimeout)
46 {
47 super(connection.getHttpDestination());
48 this.connection = connection;
49 this.flusher = flusher;
50 this.request = request;
51 this.sender = new HttpSenderOverFCGI(this);
52 this.receiver = new HttpReceiverOverFCGI(this);
53 this.idle = new FCGIIdleTimeout(connection, idleTimeout);
54 }
55
56 protected int getRequest()
57 {
58 return request;
59 }
60
61 @Override
62 public void send()
63 {
64 HttpExchange exchange = getHttpExchange();
65 if (exchange != null)
66 {
67 version = exchange.getRequest().getVersion();
68 sender.send(exchange);
69 }
70 }
71
72 @Override
73 public void proceed(HttpExchange exchange, Throwable failure)
74 {
75 sender.proceed(exchange, failure);
76 }
77
78 @Override
79 public boolean abort(Throwable cause)
80 {
81 boolean sendAborted = sender.abort(cause);
82 boolean receiveAborted = abortResponse(cause);
83 return sendAborted || receiveAborted;
84 }
85
86 @Override
87 public boolean abortResponse(Throwable cause)
88 {
89 return receiver.abort(cause);
90 }
91
92 protected boolean responseBegin(int code, String reason)
93 {
94 HttpExchange exchange = getHttpExchange();
95 if (exchange == null)
96 return false;
97 exchange.getResponse().version(version).status(code).reason(reason);
98 return receiver.responseBegin(exchange);
99 }
100
101 protected boolean responseHeader(HttpField field)
102 {
103 HttpExchange exchange = getHttpExchange();
104 return exchange != null && receiver.responseHeader(exchange, field);
105 }
106
107 protected boolean responseHeaders()
108 {
109 HttpExchange exchange = getHttpExchange();
110 return exchange != null && receiver.responseHeaders(exchange);
111 }
112
113 protected boolean content(ByteBuffer buffer, Callback callback)
114 {
115 HttpExchange exchange = getHttpExchange();
116 if (exchange != null)
117 return receiver.responseContent(exchange, buffer, callback);
118 callback.succeeded();
119 return false;
120 }
121
122 protected boolean responseSuccess()
123 {
124 HttpExchange exchange = getHttpExchange();
125 return exchange != null && receiver.responseSuccess(exchange);
126 }
127
128 protected boolean responseFailure(Throwable failure)
129 {
130 HttpExchange exchange = getHttpExchange();
131 return exchange != null && receiver.responseFailure(failure);
132 }
133
134 @Override
135 public void exchangeTerminated(Result result)
136 {
137 super.exchangeTerminated(result);
138 idle.onClose();
139 HttpFields responseHeaders = result.getResponse().getHeaders();
140 if (result.isFailed())
141 connection.close(result.getFailure());
142 else if (!connection.closeByHTTP(responseHeaders))
143 connection.release(this);
144 }
145
146 protected void flush(Generator.Result... results)
147 {
148 flusher.flush(results);
149 }
150
151 private class FCGIIdleTimeout extends IdleTimeout
152 {
153 private final HttpConnectionOverFCGI connection;
154
155 public FCGIIdleTimeout(HttpConnectionOverFCGI connection, long idleTimeout)
156 {
157 super(connection.getHttpDestination().getHttpClient().getScheduler());
158 this.connection = connection;
159 setIdleTimeout(idleTimeout);
160 }
161
162 @Override
163 protected void onIdleExpired(TimeoutException timeout)
164 {
165 if (LOG.isDebugEnabled())
166 LOG.debug("Idle timeout for request {}", request);
167 connection.abort(timeout);
168 }
169
170 @Override
171 public boolean isOpen()
172 {
173 return connection.getEndPoint().isOpen();
174 }
175 }
176 }