View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2014 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          sender.abort(cause);
82          return receiver.abort(cause);
83      }
84  
85      protected boolean responseBegin(int code, String reason)
86      {
87          HttpExchange exchange = getHttpExchange();
88          if (exchange == null)
89              return false;
90          exchange.getResponse().version(version).status(code).reason(reason);
91          return receiver.responseBegin(exchange);
92      }
93  
94      protected boolean responseHeader(HttpField field)
95      {
96          HttpExchange exchange = getHttpExchange();
97          return exchange != null && receiver.responseHeader(exchange, field);
98      }
99  
100     protected boolean responseHeaders()
101     {
102         HttpExchange exchange = getHttpExchange();
103         return exchange != null && receiver.responseHeaders(exchange);
104     }
105 
106     protected boolean content(ByteBuffer buffer, Callback callback)
107     {
108         HttpExchange exchange = getHttpExchange();
109         if (exchange != null)
110             return receiver.responseContent(exchange, buffer, callback);
111         callback.succeeded();
112         return false;
113     }
114 
115     protected boolean responseSuccess()
116     {
117         HttpExchange exchange = getHttpExchange();
118         return exchange != null && receiver.responseSuccess(exchange);
119     }
120 
121     protected boolean responseFailure(Throwable failure)
122     {
123         HttpExchange exchange = getHttpExchange();
124         return exchange != null && receiver.responseFailure(failure);
125     }
126 
127     @Override
128     public void exchangeTerminated(Result result)
129     {
130         super.exchangeTerminated(result);
131         idle.onClose();
132         HttpFields responseHeaders = result.getResponse().getHeaders();
133         if (result.isFailed())
134             connection.close(result.getFailure());
135         else if (!connection.closeByHTTP(responseHeaders))
136             connection.release(this);
137     }
138 
139     protected void flush(Generator.Result... results)
140     {
141         flusher.flush(results);
142     }
143 
144     private class FCGIIdleTimeout extends IdleTimeout
145     {
146         private final HttpConnectionOverFCGI connection;
147 
148         public FCGIIdleTimeout(HttpConnectionOverFCGI connection, long idleTimeout)
149         {
150             super(connection.getHttpDestination().getHttpClient().getScheduler());
151             this.connection = connection;
152             setIdleTimeout(idleTimeout);
153         }
154 
155         @Override
156         protected void onIdleExpired(TimeoutException timeout)
157         {
158             if (LOG.isDebugEnabled())
159                 LOG.debug("Idle timeout for request {}", request);
160             connection.abort(timeout);
161         }
162 
163         @Override
164         public boolean isOpen()
165         {
166             return connection.getEndPoint().isOpen();
167         }
168     }
169 }