View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 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.server;
20  
21  import java.nio.ByteBuffer;
22  
23  import org.eclipse.jetty.fcgi.generator.Flusher;
24  import org.eclipse.jetty.fcgi.generator.Generator;
25  import org.eclipse.jetty.fcgi.generator.ServerGenerator;
26  import org.eclipse.jetty.http.HttpHeader;
27  import org.eclipse.jetty.http.HttpHeaderValue;
28  import org.eclipse.jetty.http.MetaData;
29  import org.eclipse.jetty.io.ByteBufferPool;
30  import org.eclipse.jetty.server.HttpTransport;
31  import org.eclipse.jetty.util.BufferUtil;
32  import org.eclipse.jetty.util.Callback;
33  
34  public class HttpTransportOverFCGI implements HttpTransport
35  {
36      private final ServerGenerator generator;
37      private final Flusher flusher;
38      private final int request;
39      private volatile boolean shutdown;
40      private volatile boolean aborted;
41  
42      public HttpTransportOverFCGI(ByteBufferPool byteBufferPool, Flusher flusher, int request, boolean sendStatus200)
43      {
44          this.generator = new ServerGenerator(byteBufferPool, sendStatus200);
45          this.flusher = flusher;
46          this.request = request;
47      }
48  
49      @Override
50      public boolean isOptimizedForDirectBuffers()
51      {
52          return false;
53      }
54  
55      @Override
56      public void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback)
57      {
58          if (info!=null)
59              commit(info,head,content,lastContent,callback);
60          else
61          {
62              if (head)
63              {
64                  if (lastContent)
65                  {
66                      Generator.Result result = generateResponseContent(BufferUtil.EMPTY_BUFFER, true, callback);
67                      flusher.flush(result);
68                  }
69                  else
70                  {
71                      // Skip content generation
72                      callback.succeeded();
73                  }
74              }
75              else
76              {
77                  Generator.Result result = generateResponseContent(content, lastContent, callback);
78                  flusher.flush(result);
79              }
80  
81              if (lastContent && shutdown)
82                  flusher.shutdown();
83          }
84      }
85  
86      @Override
87      public boolean isPushSupported()
88      {
89          return false;
90      }
91  
92      @Override
93      public void push(org.eclipse.jetty.http.MetaData.Request request)
94      {
95          // LOG.debug("ignore push in {}",this);
96      }
97  
98      private void commit(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback)
99      {
100         boolean shutdown = this.shutdown = info.getFields().contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString());
101 
102         if (head)
103         {
104             if (lastContent)
105             {
106                 Generator.Result headersResult = generateResponseHeaders(info, Callback.NOOP);
107                 Generator.Result contentResult = generateResponseContent(BufferUtil.EMPTY_BUFFER, true, callback);
108                 flusher.flush(headersResult, contentResult);
109             }
110             else
111             {
112                 Generator.Result headersResult = generateResponseHeaders(info, callback);
113                 flusher.flush(headersResult);
114             }
115         }
116         else
117         {
118             Generator.Result headersResult = generateResponseHeaders(info, Callback.NOOP);
119             Generator.Result contentResult = generateResponseContent(content, lastContent, callback);
120             flusher.flush(headersResult, contentResult);
121         }
122 
123         if (lastContent && shutdown)
124             flusher.shutdown();
125     }
126 
127     protected Generator.Result generateResponseHeaders(MetaData.Response info, Callback callback)
128     {
129         return generator.generateResponseHeaders(request, info.getStatus(), info.getReason(), info.getFields(), callback);
130     }
131 
132     protected Generator.Result generateResponseContent(ByteBuffer buffer, boolean lastContent, Callback callback)
133     {
134         return generator.generateResponseContent(request, buffer, lastContent, aborted, callback);
135     }
136 
137     @Override
138     public void abort(Throwable failure)
139     {
140         aborted = true;
141     }
142 
143     @Override
144     public void onCompleted()
145     {
146     }
147 }