More tests for the HTTP over SPDY layer.
This commit is contained in:
parent
81a8c57e3b
commit
9316a9601b
|
@ -58,4 +58,10 @@ public class HeadersInfo
|
|||
flags += isResetCompression() ? FLAG_RESET_COMPRESSION : 0;
|
||||
return flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("HEADER close=%b %s", close, headers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,4 +48,10 @@ public class ReplyInfo
|
|||
{
|
||||
return isClose() ? FLAG_FIN : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("REPLY close=%b %s", close, headers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,4 +77,10 @@ public class SynInfo
|
|||
flags += isUnidirectional() ? FLAG_UNIDIRECTIONAL : 0;
|
||||
return flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("SYN close=%b %s", close, headers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,12 +46,15 @@ import org.eclipse.jetty.spdy.api.SynInfo;
|
|||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.spdy.nio.EmptyAsyncEndPoint;
|
||||
import org.eclipse.jetty.spdy.nio.ServerSPDYAsyncConnectionFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class HTTP11OverSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnectionFactory
|
||||
public class HTTPOverSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnectionFactory
|
||||
{
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
private final Connector connector;
|
||||
|
||||
public HTTP11OverSPDYAsyncConnectionFactory(Connector connector)
|
||||
public HTTPOverSPDYAsyncConnectionFactory(Connector connector)
|
||||
{
|
||||
this.connector = connector;
|
||||
}
|
||||
|
@ -73,10 +76,13 @@ public class HTTP11OverSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect
|
|||
// cycle is processed at a time, so we need to fake an http connection
|
||||
// for each SYN in order to run concurrently.
|
||||
|
||||
logger.debug("Received {}", synInfo);
|
||||
|
||||
try
|
||||
{
|
||||
HTTPSPDYConnection connection = new HTTPSPDYConnection(connector, new HTTPSPDYAsyncEndPoint(stream), connector.getServer(), stream);
|
||||
stream.setAttribute("connection", connection);
|
||||
stream.setAttribute(ParseStatus.class.getName(), ParseStatus.INITIAL);
|
||||
|
||||
Headers headers = synInfo.getHeaders();
|
||||
if (headers.isEmpty())
|
||||
|
@ -101,6 +107,8 @@ public class HTTP11OverSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect
|
|||
}
|
||||
else
|
||||
{
|
||||
if (headers.names().contains("expect"))
|
||||
forwardHeadersComplete(stream);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -119,11 +127,8 @@ public class HTTP11OverSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect
|
|||
|
||||
private boolean processRequest(Stream stream, Headers headers) throws IOException
|
||||
{
|
||||
Boolean requestSeen = (Boolean)stream.getAttribute("request");
|
||||
if (requestSeen == null || !requestSeen)
|
||||
if (stream.getAttribute(ParseStatus.class.getName()) == ParseStatus.INITIAL)
|
||||
{
|
||||
stream.setAttribute("request", Boolean.TRUE);
|
||||
|
||||
Headers.Header method = headers.get("method");
|
||||
Headers.Header uri = headers.get("url");
|
||||
Headers.Header version = headers.get("version");
|
||||
|
@ -146,6 +151,8 @@ public class HTTP11OverSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect
|
|||
@Override
|
||||
public void onHeaders(Stream stream, HeadersInfo headersInfo)
|
||||
{
|
||||
logger.debug("Received {}", headersInfo);
|
||||
|
||||
// TODO: support trailers
|
||||
Boolean dataSeen = (Boolean)stream.getAttribute("data");
|
||||
if (dataSeen != null && dataSeen)
|
||||
|
@ -176,9 +183,8 @@ public class HTTP11OverSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect
|
|||
{
|
||||
try
|
||||
{
|
||||
forwardHeadersComplete(stream);
|
||||
|
||||
stream.setAttribute("data", Boolean.TRUE);
|
||||
if (stream.getAttribute(ParseStatus.class.getName()) == ParseStatus.REQUEST)
|
||||
forwardHeadersComplete(stream);
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocate(dataInfo.getBytesCount());
|
||||
dataInfo.getBytes(buffer);
|
||||
|
@ -206,12 +212,18 @@ public class HTTP11OverSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect
|
|||
|
||||
private void forwardRequest(Stream stream, String method, String uri, String version) throws IOException
|
||||
{
|
||||
assert stream.getAttribute(ParseStatus.class.getName()) == ParseStatus.INITIAL;
|
||||
|
||||
HTTPSPDYConnection connection = (HTTPSPDYConnection)stream.getAttribute("connection");
|
||||
connection.startRequest(new ByteArrayBuffer(method), new ByteArrayBuffer(uri), new ByteArrayBuffer(version));
|
||||
|
||||
stream.setAttribute(ParseStatus.class.getName(), ParseStatus.REQUEST);
|
||||
}
|
||||
|
||||
private void forwardHeaders(Stream stream, Headers headers) throws IOException
|
||||
{
|
||||
assert stream.getAttribute(ParseStatus.class.getName()) == ParseStatus.REQUEST;
|
||||
|
||||
HTTPSPDYConnection connection = (HTTPSPDYConnection)stream.getAttribute("connection");
|
||||
for (Headers.Header header : headers)
|
||||
{
|
||||
|
@ -259,14 +271,20 @@ public class HTTP11OverSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect
|
|||
|
||||
private void forwardHeadersComplete(Stream stream) throws IOException
|
||||
{
|
||||
assert stream.getAttribute(ParseStatus.class.getName()) == ParseStatus.REQUEST;
|
||||
|
||||
HTTPSPDYConnection connection = (HTTPSPDYConnection)stream.getAttribute("connection");
|
||||
connection.headerComplete();
|
||||
|
||||
stream.setAttribute(ParseStatus.class.getName(), ParseStatus.HEADERS);
|
||||
}
|
||||
|
||||
private void forwardContent(Stream stream, ByteBuffer buffer) throws IOException
|
||||
{
|
||||
HTTPSPDYConnection connection = (HTTPSPDYConnection)stream.getAttribute("connection");
|
||||
connection.content(new IndirectNIOBuffer(buffer, false));
|
||||
|
||||
stream.setAttribute(ParseStatus.class.getName(), ParseStatus.CONTENT);
|
||||
}
|
||||
|
||||
private void forwardRequestComplete(Stream stream) throws IOException
|
||||
|
@ -279,6 +297,12 @@ public class HTTP11OverSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect
|
|||
{
|
||||
stream.getSession().goAway(stream.getVersion());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private enum ParseStatus
|
||||
{
|
||||
INITIAL, REQUEST, HEADERS, CONTENT
|
||||
}
|
||||
|
||||
private class HTTPSPDYConnection extends AbstractHttpConnection
|
||||
|
@ -368,7 +392,10 @@ public class HTTP11OverSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect
|
|||
@Override
|
||||
public void send1xx(int code) throws IOException
|
||||
{
|
||||
// TODO
|
||||
Headers headers = new Headers();
|
||||
headers.put("status", String.valueOf(code));
|
||||
headers.put("version", "HTTP/1.1");
|
||||
stream.reply(new ReplyInfo(headers, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -392,6 +419,7 @@ public class HTTP11OverSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect
|
|||
public void addContent(Buffer content, boolean last) throws IOException
|
||||
{
|
||||
// TODO
|
||||
System.out.println("SIMON");
|
||||
}
|
||||
|
||||
@Override
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.eclipse.jetty.spdy.nio.http;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
@ -33,11 +34,13 @@ import org.eclipse.jetty.spdy.api.ReplyInfo;
|
|||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.api.Stream;
|
||||
import org.eclipse.jetty.spdy.api.StringDataInfo;
|
||||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.spdy.nio.SPDYClient;
|
||||
import org.eclipse.jetty.spdy.nio.SPDYServerConnector;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class HTTPOverSPDYTest
|
||||
|
@ -52,7 +55,7 @@ public class HTTPOverSPDYTest
|
|||
server = new Server();
|
||||
connector = new SPDYServerConnector(null);
|
||||
server.addConnector(connector);
|
||||
connector.putAsyncConnectionFactory("spdy/2", new HTTP11OverSPDYAsyncConnectionFactory(connector));
|
||||
connector.putAsyncConnectionFactory("spdy/2", new HTTPOverSPDYAsyncConnectionFactory(connector));
|
||||
server.setHandler(handler);
|
||||
server.start();
|
||||
|
||||
|
@ -72,6 +75,53 @@ public class HTTPOverSPDYTest
|
|||
server.join();
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void test100Continue() throws Exception
|
||||
{
|
||||
final String data = "data";
|
||||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
|
||||
{
|
||||
request.setHandled(true);
|
||||
httpResponse.sendError(100);
|
||||
|
||||
BufferedReader reader = httpRequest.getReader();
|
||||
String read = reader.readLine();
|
||||
Assert.assertEquals(data, read);
|
||||
Assert.assertNull(reader.readLine());
|
||||
|
||||
httpResponse.setStatus(200);
|
||||
}
|
||||
}, null);
|
||||
|
||||
Headers headers = new Headers();
|
||||
headers.put("method", "POST");
|
||||
headers.put("url", "http://localhost:" + connector.getLocalPort() + "/100");
|
||||
headers.put("version", "HTTP/1.1");
|
||||
headers.put("expect", "100-continue");
|
||||
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
session.syn(SPDY.V2, new SynInfo(headers, false), new Stream.FrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
{
|
||||
Assert.assertTrue(replyInfo.getHeaders().get("status").value().contains("100"));
|
||||
replyLatch.countDown();
|
||||
|
||||
// Now send the data
|
||||
stream.data(new StringDataInfo(data, true));
|
||||
}
|
||||
});
|
||||
|
||||
Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
Thread.sleep(500_000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleGET() throws Exception
|
||||
{
|
||||
|
@ -85,8 +135,8 @@ public class HTTPOverSPDYTest
|
|||
{
|
||||
request.setHandled(true);
|
||||
Assert.assertEquals(path, target);
|
||||
Assert.assertEquals(httpRequest.getRequestURI(), path);
|
||||
Assert.assertEquals(httpRequest.getHeader("host"), "localhost:" + connector.getLocalPort());
|
||||
Assert.assertEquals(path, httpRequest.getRequestURI());
|
||||
Assert.assertEquals("localhost:" + connector.getLocalPort(), httpRequest.getHeader("host"));
|
||||
handlerLatch.countDown();
|
||||
}
|
||||
}, null);
|
||||
|
@ -110,4 +160,45 @@ public class HTTPOverSPDYTest
|
|||
Assert.assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
|
||||
Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGETWithQueryString() throws Exception
|
||||
{
|
||||
final String path = "/foo";
|
||||
final String query = "p=1";
|
||||
final String uri = path + "?" + query;
|
||||
final CountDownLatch handlerLatch = new CountDownLatch(1);
|
||||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
request.setHandled(true);
|
||||
Assert.assertEquals(path, target);
|
||||
Assert.assertEquals(path, httpRequest.getRequestURI());
|
||||
Assert.assertEquals(query, httpRequest.getQueryString());
|
||||
handlerLatch.countDown();
|
||||
}
|
||||
}, null);
|
||||
|
||||
Headers headers = new Headers();
|
||||
headers.put("method", "GET");
|
||||
headers.put("url", "http://localhost:" + connector.getLocalPort() + uri);
|
||||
headers.put("version", "HTTP/1.1");
|
||||
final CountDownLatch replyLatch = new CountDownLatch(1);
|
||||
session.syn(SPDY.V2, new SynInfo(headers, true), new Stream.FrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onReply(Stream stream, ReplyInfo replyInfo)
|
||||
{
|
||||
Assert.assertTrue(replyInfo.isClose());
|
||||
Headers replyHeaders = replyInfo.getHeaders();
|
||||
Assert.assertTrue(replyHeaders.get("status").value().contains("200"));
|
||||
replyLatch.countDown();
|
||||
}
|
||||
});
|
||||
Assert.assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
|
||||
Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue