1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 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 boolean isOptimizedForDirectBuffers()
52 {
53 return false;
54 }
55
56 @Override
57 public void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback)
58 {
59 if (info!=null)
60 commit(info,head,content,lastContent,callback);
61 else
62 {
63 if (head)
64 {
65 if (lastContent)
66 {
67 Generator.Result result = generateResponseContent(BufferUtil.EMPTY_BUFFER, true, callback);
68 flusher.flush(result);
69 }
70 else
71 {
72
73 callback.succeeded();
74 }
75 }
76 else
77 {
78 Generator.Result result = generateResponseContent(content, lastContent, callback);
79 flusher.flush(result);
80 }
81
82 if (lastContent && shutdown)
83 flusher.shutdown();
84 }
85 }
86
87 @Override
88 public boolean isPushSupported()
89 {
90 return false;
91 }
92
93 @Override
94 public void push(org.eclipse.jetty.http.MetaData.Request request)
95 {
96
97 }
98
99 private void commit(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback)
100 {
101 this.head = head;
102 boolean shutdown = this.shutdown = info.getFields().contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString());
103
104 if (head)
105 {
106 if (lastContent)
107 {
108 Generator.Result headersResult = generateResponseHeaders(info, Callback.NOOP);
109 Generator.Result contentResult = generateResponseContent(BufferUtil.EMPTY_BUFFER, true, callback);
110 flusher.flush(headersResult, contentResult);
111 }
112 else
113 {
114 Generator.Result headersResult = generateResponseHeaders(info, callback);
115 flusher.flush(headersResult);
116 }
117 }
118 else
119 {
120 Generator.Result headersResult = generateResponseHeaders(info, Callback.NOOP);
121 Generator.Result contentResult = generateResponseContent(content, lastContent, callback);
122 flusher.flush(headersResult, contentResult);
123 }
124
125 if (lastContent && shutdown)
126 flusher.shutdown();
127 }
128
129 protected Generator.Result generateResponseHeaders(MetaData.Response info, Callback callback)
130 {
131 return generator.generateResponseHeaders(request, info.getStatus(), info.getReason(), info.getFields(), callback);
132 }
133
134 protected Generator.Result generateResponseContent(ByteBuffer buffer, boolean lastContent, Callback callback)
135 {
136 return generator.generateResponseContent(request, buffer, lastContent, aborted, callback);
137 }
138
139 @Override
140 public void abort(Throwable failure)
141 {
142 aborted = true;
143 }
144
145 @Override
146 public void onCompleted()
147 {
148 }
149 }