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.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.HttpGenerator;
27  import org.eclipse.jetty.http.HttpHeader;
28  import org.eclipse.jetty.http.HttpHeaderValue;
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 head;
40      private volatile boolean shutdown;
41      private volatile boolean aborted;
42  
43      public HttpTransportOverFCGI(ByteBufferPool byteBufferPool, Flusher flusher, int request, boolean sendStatus200)
44      {
45          this.generator = new ServerGenerator(byteBufferPool, sendStatus200);
46          this.flusher = flusher;
47          this.request = request;
48      }
49  
50      @Override
51      public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback)
52      {
53          boolean head = this.head = info.isHead();
54          boolean shutdown = this.shutdown = info.getHttpFields().contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString());
55  
56          if (head)
57          {
58              if (lastContent)
59              {
60                  Generator.Result headersResult = generateResponseHeaders(info, Callback.Adapter.INSTANCE);
61                  Generator.Result contentResult = generateResponseContent(BufferUtil.EMPTY_BUFFER, true, callback);
62                  flusher.flush(headersResult, contentResult);
63              }
64              else
65              {
66                  Generator.Result headersResult = generateResponseHeaders(info, callback);
67                  flusher.flush(headersResult);
68              }
69          }
70          else
71          {
72              Generator.Result headersResult = generateResponseHeaders(info, Callback.Adapter.INSTANCE);
73              Generator.Result contentResult = generateResponseContent(content, lastContent, callback);
74              flusher.flush(headersResult, contentResult);
75          }
76  
77          if (lastContent && shutdown)
78              flusher.shutdown();
79      }
80  
81      @Override
82      public void send(ByteBuffer content, boolean lastContent, Callback callback)
83      {
84          if (head)
85          {
86              if (lastContent)
87              {
88                  Generator.Result result = generateResponseContent(BufferUtil.EMPTY_BUFFER, true, callback);
89                  flusher.flush(result);
90              }
91              else
92              {
93                  // Skip content generation
94                  callback.succeeded();
95              }
96          }
97          else
98          {
99              Generator.Result result = generateResponseContent(content, lastContent, callback);
100             flusher.flush(result);
101         }
102 
103         if (lastContent && shutdown)
104             flusher.shutdown();
105     }
106 
107     protected Generator.Result generateResponseHeaders(HttpGenerator.ResponseInfo info, Callback callback)
108     {
109         return generator.generateResponseHeaders(request, info.getStatus(), info.getReason(), info.getHttpFields(), callback);
110     }
111 
112     protected Generator.Result generateResponseContent(ByteBuffer buffer, boolean lastContent, Callback callback)
113     {
114         return generator.generateResponseContent(request, buffer, lastContent, aborted, callback);
115     }
116 
117     @Override
118     public void abort()
119     {
120         aborted = true;
121     }
122 
123     @Override
124     public void completed()
125     {
126     }
127 }