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 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
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
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 }