View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
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 }