Fixed code and tests, first clean build.
This commit is contained in:
parent
b08e415ca0
commit
24d4a971d2
|
@ -45,6 +45,12 @@ public class ResponseContentParser extends StreamContentParser
|
|||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noContent()
|
||||
{
|
||||
// Does nothing, since for responses the end of content is signaled via a FCGI_END_REQUEST frame
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onContent(ByteBuffer buffer)
|
||||
{
|
||||
|
|
|
@ -40,15 +40,15 @@ public class ClientParserTest
|
|||
final int id = 13;
|
||||
HttpFields fields = new HttpFields();
|
||||
|
||||
final String statusName = "Status";
|
||||
final int code = 200;
|
||||
final int statusCode = 200;
|
||||
final String statusMessage = "OK";
|
||||
final String contentTypeName = "Content-Type";
|
||||
final String contentTypeValue = "text/html;charset=utf-8";
|
||||
fields.put(contentTypeName, contentTypeValue);
|
||||
|
||||
ByteBufferPool byteBufferPool = new MappedByteBufferPool();
|
||||
ServerGenerator generator = new ServerGenerator(byteBufferPool);
|
||||
Generator.Result result = generator.generateResponseHeaders(id, code, "OK", fields, null);
|
||||
Generator.Result result = generator.generateResponseHeaders(id, statusCode, statusMessage, fields, null);
|
||||
|
||||
// Use the fundamental theorem of arithmetic to test the results.
|
||||
// This way we know onHeader() has been called the right number of
|
||||
|
@ -61,20 +61,26 @@ public class ClientParserTest
|
|||
final AtomicInteger params = new AtomicInteger(1);
|
||||
ClientParser parser = new ClientParser(new ClientParser.Listener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onBegin(int request, int code, String reason)
|
||||
{
|
||||
Assert.assertEquals(statusCode, code);
|
||||
Assert.assertEquals(statusMessage, reason);
|
||||
params.set(params.get() * primes[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeader(int request, HttpField field)
|
||||
{
|
||||
Assert.assertEquals(id, request);
|
||||
switch (field.getName())
|
||||
{
|
||||
case statusName:
|
||||
Assert.assertTrue(field.getValue().startsWith(String.valueOf(code)));
|
||||
params.set(params.get() * primes[0]);
|
||||
break;
|
||||
case contentTypeName:
|
||||
Assert.assertEquals(contentTypeValue, field.getValue());
|
||||
params.set(params.get() * primes[1]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,15 +106,11 @@ public class ClientParserTest
|
|||
{
|
||||
final int id = 13;
|
||||
HttpFields fields = new HttpFields();
|
||||
|
||||
final int code = 200;
|
||||
final String contentTypeName = "Content-Length";
|
||||
final String contentTypeValue = "0";
|
||||
fields.put(contentTypeName, contentTypeValue);
|
||||
fields.put("Content-Length", "0");
|
||||
|
||||
ByteBufferPool byteBufferPool = new MappedByteBufferPool();
|
||||
ServerGenerator generator = new ServerGenerator(byteBufferPool);
|
||||
Generator.Result result1 = generator.generateResponseHeaders(id, code, "OK", fields, null);
|
||||
Generator.Result result1 = generator.generateResponseHeaders(id, 200, "OK", fields, null);
|
||||
Generator.Result result2 = generator.generateResponseContent(id, null, true, null);
|
||||
|
||||
final AtomicInteger verifier = new AtomicInteger();
|
||||
|
|
|
@ -136,9 +136,12 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements Connec
|
|||
|
||||
private void shutdown()
|
||||
{
|
||||
// First close then abort, to be sure that the
|
||||
// connection cannot be reused from an onFailure()
|
||||
// handler or by blocking code waiting for completion.
|
||||
close();
|
||||
for (HttpChannelOverFCGI channel : channels.values())
|
||||
channel.abort(new EOFException());
|
||||
close();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -45,9 +45,9 @@ public class HttpSenderOverFCGI extends HttpSender
|
|||
|
||||
// FastCGI headers based on the URI
|
||||
URI uri = request.getURI();
|
||||
String path = uri.getPath();
|
||||
String path = uri.getRawPath();
|
||||
fcgiHeaders.put(FCGI.Headers.REQUEST_URI, path);
|
||||
String query = uri.getQuery();
|
||||
String query = uri.getRawQuery();
|
||||
fcgiHeaders.put(FCGI.Headers.QUERY_STRING, query == null ? "" : query);
|
||||
int lastSegment = path.lastIndexOf('/');
|
||||
String scriptName = lastSegment < 0 ? path : path.substring(lastSegment);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
package org.eclipse.jetty.fcgi.server;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
|
||||
import org.eclipse.jetty.fcgi.FCGI;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
|
@ -42,12 +43,12 @@ public class HttpChannelOverFCGI extends HttpChannel<ByteBuffer>
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(HttpChannelOverFCGI.class);
|
||||
|
||||
private final List<HttpField> fields = new ArrayList<>();
|
||||
private final Dispatcher dispatcher;
|
||||
private String method;
|
||||
private String uri;
|
||||
private String path;
|
||||
private String query;
|
||||
private String version;
|
||||
private boolean started;
|
||||
private List<HttpField> fields;
|
||||
|
||||
public HttpChannelOverFCGI(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput<ByteBuffer> input)
|
||||
{
|
||||
|
@ -58,57 +59,37 @@ public class HttpChannelOverFCGI extends HttpChannel<ByteBuffer>
|
|||
protected void header(HttpField field)
|
||||
{
|
||||
if (FCGI.Headers.REQUEST_METHOD.equalsIgnoreCase(field.getName()))
|
||||
{
|
||||
method = field.getValue();
|
||||
if (uri != null && version != null)
|
||||
startRequest();
|
||||
}
|
||||
else if (FCGI.Headers.REQUEST_URI.equalsIgnoreCase(field.getName()))
|
||||
{
|
||||
uri = field.getValue();
|
||||
if (method != null && version != null)
|
||||
startRequest();
|
||||
}
|
||||
path = field.getValue();
|
||||
else if (FCGI.Headers.QUERY_STRING.equalsIgnoreCase(field.getName()))
|
||||
query = field.getValue();
|
||||
else if (FCGI.Headers.SERVER_PROTOCOL.equalsIgnoreCase(field.getName()))
|
||||
{
|
||||
version = field.getValue();
|
||||
if (method != null && uri != null)
|
||||
startRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (started)
|
||||
{
|
||||
resumeHeaders();
|
||||
convertHeader(field);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fields == null)
|
||||
fields = new ArrayList<>();
|
||||
fields.add(field);
|
||||
}
|
||||
}
|
||||
fields.add(field);
|
||||
}
|
||||
|
||||
private void startRequest()
|
||||
@Override
|
||||
public boolean headerComplete()
|
||||
{
|
||||
started = true;
|
||||
startRequest(null, method, ByteBuffer.wrap(uri.getBytes(Charset.forName("UTF-8"))), HttpVersion.fromString(version));
|
||||
resumeHeaders();
|
||||
}
|
||||
String uri = path;
|
||||
if (query != null && query.length() > 0)
|
||||
uri += "?" + query;
|
||||
startRequest(HttpMethod.fromString(method), method, ByteBuffer.wrap(uri.getBytes(StandardCharsets.UTF_8)),
|
||||
HttpVersion.fromString(version));
|
||||
|
||||
private void resumeHeaders()
|
||||
{
|
||||
if (fields != null)
|
||||
for (HttpField fcgiField : fields)
|
||||
{
|
||||
for (HttpField field : fields)
|
||||
convertHeader(field);
|
||||
fields = null;
|
||||
HttpField httpField = convertHeader(fcgiField);
|
||||
if (httpField != null)
|
||||
parsedHeader(httpField);
|
||||
}
|
||||
|
||||
return super.headerComplete();
|
||||
}
|
||||
|
||||
private void convertHeader(HttpField field)
|
||||
private HttpField convertHeader(HttpField field)
|
||||
{
|
||||
String name = field.getName();
|
||||
if (name.startsWith("HTTP_"))
|
||||
|
@ -124,17 +105,9 @@ public class HttpChannelOverFCGI extends HttpChannel<ByteBuffer>
|
|||
httpName.append(Character.toUpperCase(part.charAt(0)));
|
||||
httpName.append(part.substring(1).toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
field = new HttpField(httpName.toString(), field.getValue());
|
||||
return new HttpField(httpName.toString(), field.getValue());
|
||||
}
|
||||
parsedHeader(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean headerComplete()
|
||||
{
|
||||
boolean result = super.headerComplete();
|
||||
started = false;
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void dispatch()
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.jetty.fcgi.generator.ServerGenerator;
|
|||
import org.eclipse.jetty.http.HttpGenerator;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.server.HttpTransport;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
||||
public class HttpTransportOverFCGI implements HttpTransport
|
||||
|
@ -33,6 +34,7 @@ public class HttpTransportOverFCGI implements HttpTransport
|
|||
private final ServerGenerator generator;
|
||||
private final Flusher flusher;
|
||||
private final int request;
|
||||
private volatile boolean head;
|
||||
|
||||
public HttpTransportOverFCGI(ByteBufferPool byteBufferPool, Flusher flusher, int request)
|
||||
{
|
||||
|
@ -44,17 +46,53 @@ public class HttpTransportOverFCGI implements HttpTransport
|
|||
@Override
|
||||
public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback)
|
||||
{
|
||||
Generator.Result headersResult = generator.generateResponseHeaders(request, info.getStatus(), info.getReason(),
|
||||
info.getHttpFields(), new Callback.Adapter());
|
||||
Generator.Result contentResult = generator.generateResponseContent(request, content, lastContent, callback);
|
||||
flusher.flush(headersResult, contentResult);
|
||||
boolean head = this.head = info.isHead();
|
||||
if (head)
|
||||
{
|
||||
if (lastContent)
|
||||
{
|
||||
Generator.Result headersResult = generator.generateResponseHeaders(request, info.getStatus(), info.getReason(),
|
||||
info.getHttpFields(), new Callback.Adapter());
|
||||
Generator.Result contentResult = generator.generateResponseContent(request, BufferUtil.EMPTY_BUFFER, lastContent, callback);
|
||||
flusher.flush(headersResult, contentResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Generator.Result headersResult = generator.generateResponseHeaders(request, info.getStatus(), info.getReason(),
|
||||
info.getHttpFields(), callback);
|
||||
flusher.flush(headersResult);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Generator.Result headersResult = generator.generateResponseHeaders(request, info.getStatus(), info.getReason(),
|
||||
info.getHttpFields(), new Callback.Adapter());
|
||||
Generator.Result contentResult = generator.generateResponseContent(request, content, lastContent, callback);
|
||||
flusher.flush(headersResult, contentResult);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(ByteBuffer content, boolean lastContent, Callback callback)
|
||||
{
|
||||
Generator.Result result = generator.generateResponseContent(request, content, lastContent, callback);
|
||||
flusher.flush(result);
|
||||
if (head)
|
||||
{
|
||||
if (lastContent)
|
||||
{
|
||||
Generator.Result result = generator.generateResponseContent(request, BufferUtil.EMPTY_BUFFER, lastContent, callback);
|
||||
flusher.flush(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip content generation
|
||||
callback.succeeded();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Generator.Result result = generator.generateResponseContent(request, content, lastContent, callback);
|
||||
flusher.flush(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue