Merge branch 'jetty-9.4.x'

This commit is contained in:
Joakim Erdfelt 2016-07-07 13:43:16 -07:00
commit 294362954d
15 changed files with 623 additions and 234 deletions

View File

@ -477,7 +477,7 @@ public class HttpURI
case ASTERISK: case ASTERISK:
{ {
throw new IllegalArgumentException("only '*'"); throw new IllegalArgumentException("Bad character '*'");
} }
case FRAGMENT: case FRAGMENT:

View File

@ -107,9 +107,19 @@ public class HttpTester
public abstract static class Input public abstract static class Input
{ {
final ByteBuffer _buffer;
boolean _eof=false; boolean _eof=false;
HttpParser _parser; HttpParser _parser;
ByteBuffer _buffer = BufferUtil.allocate(8192);
Input()
{
this(BufferUtil.allocate(8192));
}
Input(ByteBuffer buffer)
{
_buffer = buffer;
}
public ByteBuffer getBuffer() public ByteBuffer getBuffer()
{ {
@ -142,6 +152,19 @@ public class HttpTester
} }
public static Input from(final ByteBuffer data)
{
return new Input(data.slice())
{
@Override
public int fillBuffer() throws IOException
{
_eof=true;
return -1;
}
};
}
public static Input from(final InputStream in) public static Input from(final InputStream in)
{ {
return new Input() return new Input()

View File

@ -143,6 +143,28 @@ public class ByteArrayEndPoint extends AbstractEndPoint
onOpen(); onOpen();
} }
/* ------------------------------------------------------------ */
@Override
public void doShutdownOutput()
{
super.doShutdownOutput();
try(Locker.Lock lock = _locker.lock())
{
_hasOutput.signalAll();
}
}
/* ------------------------------------------------------------ */
@Override
public void doClose()
{
super.doClose();
try(Locker.Lock lock = _locker.lock())
{
_hasOutput.signalAll();
}
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public InetSocketAddress getLocalAddress() public InetSocketAddress getLocalAddress()
@ -317,7 +339,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
try(Locker.Lock lock = _locker.lock()) try(Locker.Lock lock = _locker.lock())
{ {
if (BufferUtil.isEmpty(_out)) if (BufferUtil.isEmpty(_out) && isOpen() && !isOutputShutdown())
_hasOutput.await(time,unit); _hasOutput.await(time,unit);
b=_out; b=_out;

View File

@ -36,11 +36,6 @@
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
@ -71,6 +66,18 @@
<version>${project.version}</version> <version>${project.version}</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId> <artifactId>mockito-core</artifactId>

View File

@ -38,11 +38,20 @@ import org.eclipse.jetty.util.ByteArrayOutputStream2;
import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.util.thread.Scheduler;
/**
* A local connector, mostly for testing purposes.
* <pre>
* HttpTester.Request request = HttpTester.newRequest();
* request.setURI("/some/resource");
* HttpTester.Response response =
* HttpTester.parseResponse(HttpTester.from(localConnector.getResponse(request.generate())));
* </pre>
*
*/
public class LocalConnector extends AbstractConnector public class LocalConnector extends AbstractConnector
{ {
private final BlockingQueue<LocalEndPoint> _connects = new LinkedBlockingQueue<>(); private final BlockingQueue<LocalEndPoint> _connects = new LinkedBlockingQueue<>();
public LocalConnector(Server server, Executor executor, Scheduler scheduler, ByteBufferPool pool, int acceptors, ConnectionFactory... factories) public LocalConnector(Server server, Executor executor, Scheduler scheduler, ByteBufferPool pool, int acceptors, ConnectionFactory... factories)
{ {
super(server,executor,scheduler,pool,acceptors,factories); super(server,executor,scheduler,pool,acceptors,factories);
@ -85,6 +94,7 @@ public class LocalConnector extends AbstractConnector
* @param requests the requests * @param requests the requests
* @return the responses * @return the responses
* @throws Exception if the requests fail * @throws Exception if the requests fail
* @deprecated Use {@link #getResponse(String)}
*/ */
public String getResponses(String requests) throws Exception public String getResponses(String requests) throws Exception
{ {
@ -103,6 +113,7 @@ public class LocalConnector extends AbstractConnector
* @param units The units of idleFor * @param units The units of idleFor
* @return the responses * @return the responses
* @throws Exception if the requests fail * @throws Exception if the requests fail
* @deprecated Use {@link #getResponse(String, boolean, long, TimeUnit)}
*/ */
public String getResponses(String requests,long idleFor,TimeUnit units) throws Exception public String getResponses(String requests,long idleFor,TimeUnit units) throws Exception
{ {
@ -120,6 +131,7 @@ public class LocalConnector extends AbstractConnector
* @param requestsBuffer the requests * @param requestsBuffer the requests
* @return the responses * @return the responses
* @throws Exception if the requests fail * @throws Exception if the requests fail
* @deprecated Use {@link #getResponse(ByteBuffer)}
*/ */
public ByteBuffer getResponses(ByteBuffer requestsBuffer) throws Exception public ByteBuffer getResponses(ByteBuffer requestsBuffer) throws Exception
{ {
@ -137,6 +149,7 @@ public class LocalConnector extends AbstractConnector
* @param units The units of idleFor * @param units The units of idleFor
* @return the responses * @return the responses
* @throws Exception if the requests fail * @throws Exception if the requests fail
* @deprecated Use {@link #getResponse(ByteBuffer, boolean, long, TimeUnit)}
*/ */
public ByteBuffer getResponses(ByteBuffer requestsBuffer,long idleFor,TimeUnit units) throws Exception public ByteBuffer getResponses(ByteBuffer requestsBuffer,long idleFor,TimeUnit units) throws Exception
{ {
@ -198,20 +211,36 @@ public class LocalConnector extends AbstractConnector
{ {
return getResponse(requestsBuffer,false,10,TimeUnit.SECONDS); return getResponse(requestsBuffer,false,10,TimeUnit.SECONDS);
} }
/** Get a single response using a parser to search for the end of the message.
* @param requestBuffer The request to send
* @param time The time to wait
* @param unit The units of the wait
* @return ByteBuffer containing response or null.
* @throws Exception If there is a problem
*/
public ByteBuffer getResponse(ByteBuffer requestBuffer, long time,TimeUnit unit) throws Exception
{
boolean head = BufferUtil.toString(requestBuffer).toLowerCase().startsWith("head ");
if (LOG.isDebugEnabled())
LOG.debug("requests {}", BufferUtil.toUTF8String(requestBuffer));
LocalEndPoint endp = executeRequest(requestBuffer);
return endp.waitForResponse(head,time,unit);
}
/** Get a single response using a parser to search for the end of the message. /** Get a single response using a parser to search for the end of the message.
* @param requestsBuffer The request to send * @param requestBuffer The request to send
* @param head True if the response is for a head request * @param head True if the response is for a head request
* @param time The time to wait * @param time The time to wait
* @param unit The units of the wait * @param unit The units of the wait
* @return ByteBuffer containing response or null. * @return ByteBuffer containing response or null.
* @throws Exception If there is a problem * @throws Exception If there is a problem
*/ */
public ByteBuffer getResponse(ByteBuffer requestsBuffer,boolean head, long time,TimeUnit unit) throws Exception public ByteBuffer getResponse(ByteBuffer requestBuffer,boolean head, long time,TimeUnit unit) throws Exception
{ {
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("requests {}", BufferUtil.toUTF8String(requestsBuffer)); LOG.debug("requests {}", BufferUtil.toUTF8String(requestBuffer));
LocalEndPoint endp = executeRequest(requestsBuffer); LocalEndPoint endp = executeRequest(requestBuffer);
return endp.waitForResponse(head,time,unit); return endp.waitForResponse(head,time,unit);
} }
@ -225,6 +254,25 @@ public class LocalConnector extends AbstractConnector
{ {
return getResponse(rawRequest,false,30,TimeUnit.SECONDS); return getResponse(rawRequest,false,30,TimeUnit.SECONDS);
} }
/** Get a single response using a parser to search for the end of the message.
* @param rawRequest The request to send
* @param time The time to wait
* @param unit The units of the wait
* @return ByteBuffer containing response or null.
* @throws Exception If there is a problem
*/
public String getResponse(String rawRequest,long time,TimeUnit unit) throws Exception
{
boolean head = rawRequest.toLowerCase().startsWith("head ");
ByteBuffer requestsBuffer = BufferUtil.toBuffer(rawRequest, StandardCharsets.ISO_8859_1);
if (LOG.isDebugEnabled())
LOG.debug("request {}", BufferUtil.toUTF8String(requestsBuffer));
LocalEndPoint endp = executeRequest(requestsBuffer);
return BufferUtil.toString(endp.waitForResponse(head,time,unit), StandardCharsets.ISO_8859_1);
}
/** Get a single response using a parser to search for the end of the message. /** Get a single response using a parser to search for the end of the message.
* @param rawRequest The request to send * @param rawRequest The request to send
@ -244,8 +292,6 @@ public class LocalConnector extends AbstractConnector
return BufferUtil.toString(endp.waitForResponse(head,time,unit), StandardCharsets.ISO_8859_1); return BufferUtil.toString(endp.waitForResponse(head,time,unit), StandardCharsets.ISO_8859_1);
} }
/** Local EndPoint /** Local EndPoint
*/ */
public class LocalEndPoint extends ByteArrayEndPoint public class LocalEndPoint extends ByteArrayEndPoint
@ -321,7 +367,30 @@ public class LocalConnector extends AbstractConnector
} }
} }
} }
/** Wait for a response using a parser to detect the end of message
* @return Buffer containing full response or null for EOF;
* @throws Exception
*/
public String getResponse() throws Exception
{
return getResponse(false,30,TimeUnit.SECONDS);
}
/** Wait for a response using a parser to detect the end of message
* @param head
* @param time
* @param unit
* @return Buffer containing full response or null for EOF;
* @throws Exception
*/
public String getResponse(boolean head, long time,TimeUnit unit) throws Exception
{
ByteBuffer response = waitForResponse(head,time,unit);
if (response!=null)
return BufferUtil.toString(response);
return null;
}
/** Wait for a response using a parser to detect the end of message /** Wait for a response using a parser to detect the end of message
* @param head * @param head
@ -380,7 +449,6 @@ public class LocalConnector extends AbstractConnector
} }
}; };
HttpParser parser = new HttpParser(handler); HttpParser parser = new HttpParser(handler);
parser.setHeadResponse(head); parser.setHeadResponse(head);
try(ByteArrayOutputStream2 bout = new ByteArrayOutputStream2();) try(ByteArrayOutputStream2 bout = new ByteArrayOutputStream2();)
@ -388,10 +456,20 @@ public class LocalConnector extends AbstractConnector
loop: while(true) loop: while(true)
{ {
// read a chunk of response // read a chunk of response
ByteBuffer chunk = BufferUtil.hasContent(_responseData) ByteBuffer chunk;
? _responseData : waitForOutput(time,unit); if (BufferUtil.hasContent(_responseData))
_responseData=null; chunk = _responseData;
else
{
chunk = waitForOutput(time,unit);
if (BufferUtil.isEmpty(chunk) && (!isOpen() || isOutputShutdown()))
{
parser.atEOF();
parser.parseNext(BufferUtil.EMPTY_BUFFER);
break loop;
}
}
// Parse the content of this chunk // Parse the content of this chunk
while (BufferUtil.hasContent(chunk)) while (BufferUtil.hasContent(chunk))
{ {
@ -417,6 +495,9 @@ public class LocalConnector extends AbstractConnector
} }
} }
} }
if (bout.getCount()==0 && isOutputShutdown())
return null;
return ByteBuffer.wrap(bout.getBuf(),0,bout.getCount()); return ByteBuffer.wrap(bout.getBuf(),0,bout.getCount());
} }
} }

View File

@ -46,8 +46,10 @@ import org.eclipse.jetty.http.HttpCompliance;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.LocalConnector.LocalEndPoint;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.log.StacklessLogging;
@ -99,7 +101,7 @@ public class HttpConnectionTest
int offset=0; int offset=0;
// Chunk last // Chunk last
response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+ response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+ "Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain\r\n"+ "Content-Type: text/plain\r\n"+
@ -114,7 +116,7 @@ public class HttpConnectionTest
checkContains(response,offset,"12345"); checkContains(response,offset,"12345");
offset = 0; offset = 0;
response=connector.getResponses("GET /R2 HTTP/1.1\r\n"+ response=connector.getResponse("GET /R2 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+ "Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain\r\n"+ "Content-Type: text/plain\r\n"+
@ -139,7 +141,7 @@ public class HttpConnectionTest
@Test @Test
public void testNoPath() throws Exception public void testNoPath() throws Exception
{ {
String response=connector.getResponses("GET http://localhost:80 HTTP/1.1\r\n"+ String response=connector.getResponse("GET http://localhost:80 HTTP/1.1\r\n"+
"Host: localhost:80\r\n"+ "Host: localhost:80\r\n"+
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"); "\r\n");
@ -152,7 +154,7 @@ public class HttpConnectionTest
@Test @Test
public void testDate() throws Exception public void testDate() throws Exception
{ {
String response=connector.getResponses("GET / HTTP/1.1\r\n"+ String response=connector.getResponse("GET / HTTP/1.1\r\n"+
"Host: localhost:80\r\n"+ "Host: localhost:80\r\n"+
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"); "\r\n");
@ -166,7 +168,7 @@ public class HttpConnectionTest
@Test @Test
public void testSetDate() throws Exception public void testSetDate() throws Exception
{ {
String response=connector.getResponses("GET /?date=1+Jan+1970 HTTP/1.1\r\n"+ String response=connector.getResponse("GET /?date=1+Jan+1970 HTTP/1.1\r\n"+
"Host: localhost:80\r\n"+ "Host: localhost:80\r\n"+
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"); "\r\n");
@ -180,7 +182,7 @@ public class HttpConnectionTest
@Test @Test
public void testBadNoPath() throws Exception public void testBadNoPath() throws Exception
{ {
String response=connector.getResponses("GET http://localhost:80/../cheat HTTP/1.1\r\n"+ String response=connector.getResponse("GET http://localhost:80/../cheat HTTP/1.1\r\n"+
"Host: localhost:80\r\n"+ "Host: localhost:80\r\n"+
"\r\n"); "\r\n");
checkContains(response,0,"HTTP/1.1 400"); checkContains(response,0,"HTTP/1.1 400");
@ -189,7 +191,7 @@ public class HttpConnectionTest
@Test @Test
public void testOKPathDotDotPath() throws Exception public void testOKPathDotDotPath() throws Exception
{ {
String response=connector.getResponses("GET /ooops/../path HTTP/1.0\r\nHost: localhost:80\r\n\n"); String response=connector.getResponse("GET /ooops/../path HTTP/1.0\r\nHost: localhost:80\r\n\n");
checkContains(response,0,"HTTP/1.1 200 OK"); checkContains(response,0,"HTTP/1.1 200 OK");
checkContains(response,0,"pathInfo=/path"); checkContains(response,0,"pathInfo=/path");
} }
@ -197,14 +199,14 @@ public class HttpConnectionTest
@Test @Test
public void testBadPathDotDotPath() throws Exception public void testBadPathDotDotPath() throws Exception
{ {
String response=connector.getResponses("GET /ooops/../../path HTTP/1.0\r\nHost: localhost:80\r\n\n"); String response=connector.getResponse("GET /ooops/../../path HTTP/1.0\r\nHost: localhost:80\r\n\n");
checkContains(response,0,"HTTP/1.1 400 Bad URI"); checkContains(response,0,"HTTP/1.1 400 Bad URI");
} }
@Test @Test
public void testOKPathEncodedDotDotPath() throws Exception public void testOKPathEncodedDotDotPath() throws Exception
{ {
String response=connector.getResponses("GET /ooops/%2e%2e/path HTTP/1.0\r\nHost: localhost:80\r\n\n"); String response=connector.getResponse("GET /ooops/%2e%2e/path HTTP/1.0\r\nHost: localhost:80\r\n\n");
checkContains(response,0,"HTTP/1.1 200 OK"); checkContains(response,0,"HTTP/1.1 200 OK");
checkContains(response,0,"pathInfo=/path"); checkContains(response,0,"pathInfo=/path");
} }
@ -212,28 +214,28 @@ public class HttpConnectionTest
@Test @Test
public void testBadPathEncodedDotDotPath() throws Exception public void testBadPathEncodedDotDotPath() throws Exception
{ {
String response=connector.getResponses("GET /ooops/%2e%2e/%2e%2e/path HTTP/1.0\r\nHost: localhost:80\r\n\n"); String response=connector.getResponse("GET /ooops/%2e%2e/%2e%2e/path HTTP/1.0\r\nHost: localhost:80\r\n\n");
checkContains(response,0,"HTTP/1.1 400 Bad URI"); checkContains(response,0,"HTTP/1.1 400 Bad URI");
} }
@Test @Test
public void testBadDotDotPath() throws Exception public void testBadDotDotPath() throws Exception
{ {
String response=connector.getResponses("GET ../path HTTP/1.0\r\nHost: localhost:80\r\n\n"); String response=connector.getResponse("GET ../path HTTP/1.0\r\nHost: localhost:80\r\n\n");
checkContains(response,0,"HTTP/1.1 400 Bad URI"); checkContains(response,0,"HTTP/1.1 400 Bad URI");
} }
@Test @Test
public void testBadSlashDotDotPath() throws Exception public void testBadSlashDotDotPath() throws Exception
{ {
String response=connector.getResponses("GET /../path HTTP/1.0\r\nHost: localhost:80\r\n\n"); String response=connector.getResponse("GET /../path HTTP/1.0\r\nHost: localhost:80\r\n\n");
checkContains(response,0,"HTTP/1.1 400 Bad URI"); checkContains(response,0,"HTTP/1.1 400 Bad URI");
} }
@Test @Test
public void testEncodedBadDotDotPath() throws Exception public void testEncodedBadDotDotPath() throws Exception
{ {
String response=connector.getResponses("GET %2e%2e/path HTTP/1.0\r\nHost: localhost:80\r\n\n"); String response=connector.getResponse("GET %2e%2e/path HTTP/1.0\r\nHost: localhost:80\r\n\n");
checkContains(response,0,"HTTP/1.1 400 Bad URI"); checkContains(response,0,"HTTP/1.1 400 Bad URI");
} }
@ -241,7 +243,9 @@ public class HttpConnectionTest
public void test_0_9() throws Exception public void test_0_9() throws Exception
{ {
connector.getConnectionFactory(HttpConnectionFactory.class).setHttpCompliance(HttpCompliance.RFC2616); connector.getConnectionFactory(HttpConnectionFactory.class).setHttpCompliance(HttpCompliance.RFC2616);
String response=connector.getResponses("GET /R1\n"); LocalEndPoint endp = connector.executeRequest("GET /R1\n");
endp.waitUntilClosed();
String response=BufferUtil.toString(endp.takeOutput());
int offset=0; int offset=0;
checkNotContained(response,offset,"HTTP/1.1"); checkNotContained(response,offset,"HTTP/1.1");
@ -252,7 +256,7 @@ public class HttpConnectionTest
@Test @Test
public void testSimple() throws Exception public void testSimple() throws Exception
{ {
String response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+ String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"); "\r\n");
@ -265,7 +269,7 @@ public class HttpConnectionTest
@Test @Test
public void testEmptyChunk() throws Exception public void testEmptyChunk() throws Exception
{ {
String response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+ String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+ "Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain\r\n"+ "Content-Type: text/plain\r\n"+
@ -282,12 +286,12 @@ public class HttpConnectionTest
@Test @Test
public void testHead() throws Exception public void testHead() throws Exception
{ {
String responsePOST=connector.getResponses("POST /R1 HTTP/1.1\r\n"+ String responsePOST=connector.getResponse("POST /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"); "\r\n");
String responseHEAD=connector.getResponses("HEAD /R1 HTTP/1.1\r\n"+ String responseHEAD=connector.getResponse("HEAD /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"); "\r\n");
@ -385,7 +389,7 @@ public class HttpConnectionTest
Log.getLogger(HttpParser.class).info("badMessage: Number formate exception expected ..."); Log.getLogger(HttpParser.class).info("badMessage: Number formate exception expected ...");
String response; String response;
response=connector.getResponses("GET http://localhost:EXPECTED_NUMBER_FORMAT_EXCEPTION/ HTTP/1.1\r\n"+ response=connector.getResponse("GET http://localhost:EXPECTED_NUMBER_FORMAT_EXCEPTION/ HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"); "\r\n");
@ -400,7 +404,7 @@ public class HttpConnectionTest
try(StacklessLogging stackless = new StacklessLogging(HttpParser.class)) try(StacklessLogging stackless = new StacklessLogging(HttpParser.class))
{ {
response=connector.getResponses("GET /bad/encoding%1 HTTP/1.1\r\n"+ response=connector.getResponse("GET /bad/encoding%1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"); "\r\n");
@ -414,13 +418,13 @@ public class HttpConnectionTest
Log.getLogger(HttpParser.class).info("badMessage: bad encoding expected ..."); Log.getLogger(HttpParser.class).info("badMessage: bad encoding expected ...");
String response; String response;
response=connector.getResponses("GET /foo/bar%c0%00 HTTP/1.1\r\n"+ response=connector.getResponse("GET /foo/bar%c0%00 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"); "\r\n");
checkContains(response,0,"HTTP/1.1 200"); //now fallback to iso-8859-1 checkContains(response,0,"HTTP/1.1 200"); //now fallback to iso-8859-1
response=connector.getResponses("GET /bad/utf8%c1 HTTP/1.1\r\n"+ response=connector.getResponse("GET /bad/utf8%c1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"); "\r\n");
@ -432,7 +436,7 @@ public class HttpConnectionTest
{ {
int offset=0; int offset=0;
String response = connector.getResponses("GET /R1 HTTP/1.1\r\n" + String response = connector.getResponse("GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Transfer-Encoding: chunked\r\n" + "Transfer-Encoding: chunked\r\n" +
"Content-Type: text/plain\r\n" + "Content-Type: text/plain\r\n" +
@ -458,14 +462,14 @@ public class HttpConnectionTest
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{ {
response.setStatus(200); response.setStatus(200);
OutputStream out =response.getOutputStream(); OutputStream out = response.getOutputStream();
out.flush(); out.flush();
out.flush(); out.flush();
} }
}); });
server.start(); server.start();
String response=connector.getResponses("GET / HTTP/1.1\r\n"+ String response=connector.getResponse("GET / HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"); "\r\n");
@ -480,7 +484,7 @@ public class HttpConnectionTest
try try
{ {
int offset=0; int offset=0;
response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+ response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+ "Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain; charset=utf-8\r\n"+ "Content-Type: text/plain; charset=utf-8\r\n"+
@ -496,7 +500,7 @@ public class HttpConnectionTest
checkContains(response,offset,"12345"); checkContains(response,offset,"12345");
offset=0; offset=0;
response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+ response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+ "Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain; charset = iso-8859-1 ; other=value\r\n"+ "Content-Type: text/plain; charset = iso-8859-1 ; other=value\r\n"+
@ -512,7 +516,7 @@ public class HttpConnectionTest
checkContains(response,offset,"12345"); checkContains(response,offset,"12345");
offset=0; offset=0;
response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+ response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+ "Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain; charset=unknown\r\n"+ "Content-Type: text/plain; charset=unknown\r\n"+
@ -559,7 +563,8 @@ public class HttpConnectionTest
"\r\n" + "\r\n" +
"abcdefghij\r\n"; "abcdefghij\r\n";
String response = connector.getResponses(requests); LocalEndPoint endp = connector.executeRequest(requests);
String response = endp.getResponse()+endp.getResponse();
offset = checkContains(response,offset,"HTTP/1.1 200"); offset = checkContains(response,offset,"HTTP/1.1 200");
offset = checkContains(response,offset,"pathInfo=/R1"); offset = checkContains(response,offset,"pathInfo=/R1");
@ -586,7 +591,7 @@ public class HttpConnectionTest
"12345\r\n"; "12345\r\n";
long start=System.currentTimeMillis(); long start=System.currentTimeMillis();
String response = connector.getResponses(requests, 2000, TimeUnit.MILLISECONDS); String response = connector.getResponse(requests, 2000, TimeUnit.MILLISECONDS);
if ((System.currentTimeMillis()-start)>=2000) if ((System.currentTimeMillis()-start)>=2000)
Assert.fail(); Assert.fail();
@ -620,7 +625,8 @@ public class HttpConnectionTest
"\r\n"+ "\r\n"+
"abcdefghij\r\n"; "abcdefghij\r\n";
String response = connector.getResponses(requests); LocalEndPoint endp = connector.executeRequest(requests);
String response = endp.getResponse()+endp.getResponse();
offset = checkContains(response,offset,"HTTP/1.1 499"); offset = checkContains(response,offset,"HTTP/1.1 499");
offset = checkContains(response,offset,"HTTP/1.1 200"); offset = checkContains(response,offset,"HTTP/1.1 200");
@ -653,7 +659,8 @@ public class HttpConnectionTest
"\r\n"+ "\r\n"+
"abcdefghij\r\n"; "abcdefghij\r\n";
String response = connector.getResponses(requests); LocalEndPoint endp = connector.executeRequest(requests);
String response = endp.getResponse()+endp.getResponse();
offset = checkContains(response,offset,"HTTP/1.1 599"); offset = checkContains(response,offset,"HTTP/1.1 599");
offset = checkContains(response,offset,"HTTP/1.1 200"); offset = checkContains(response,offset,"HTTP/1.1 200");
@ -688,7 +695,7 @@ public class HttpConnectionTest
try (StacklessLogging stackless = new StacklessLogging(logger)) try (StacklessLogging stackless = new StacklessLogging(logger))
{ {
logger.info("EXPECTING: java.lang.IllegalStateException..."); logger.info("EXPECTING: java.lang.IllegalStateException...");
String response = connector.getResponses(requests); String response = connector.getResponse(requests);
offset = checkContains(response,offset,"HTTP/1.1 500"); offset = checkContains(response,offset,"HTTP/1.1 500");
offset = checkContains(response,offset,"Connection: close"); offset = checkContains(response,offset,"Connection: close");
checkNotContained(response,offset,"HTTP/1.1 200"); checkNotContained(response,offset,"HTTP/1.1 200");
@ -702,7 +709,7 @@ public class HttpConnectionTest
try try
{ {
int offset=0; int offset=0;
response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+ response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Connection: TE, close\r\n"+ "Connection: TE, close\r\n"+
"Transfer-Encoding: chunked\r\n"+ "Transfer-Encoding: chunked\r\n"+
@ -736,7 +743,7 @@ public class HttpConnectionTest
String cookie = "thisisastringthatshouldreachover1kbytes"; String cookie = "thisisastringthatshouldreachover1kbytes";
for (int i=0;i<100;i++) for (int i=0;i<100;i++)
cookie+="xxxxxxxxxxxx"; cookie+="xxxxxxxxxxxx";
response = connector.getResponses("GET / HTTP/1.1\r\n"+ response = connector.getResponse("GET / HTTP/1.1\r\n"+
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Cookie: "+cookie+"\r\n"+ "Cookie: "+cookie+"\r\n"+
"\r\n" "\r\n"
@ -769,7 +776,7 @@ public class HttpConnectionTest
} }
request.append("\r\n"); request.append("\r\n");
String response = connector.getResponses(request.toString()); String response = connector.getResponse(request.toString());
offset = checkContains(response, offset, "HTTP/1.1 413"); offset = checkContains(response, offset, "HTTP/1.1 413");
checkContains(response, offset, "<h1>Bad Message 413</h1><pre>reason: Request Entity Too Large</pre>"); checkContains(response, offset, "<h1>Bad Message 413</h1><pre>reason: Request Entity Too Large</pre>");
} }
@ -806,7 +813,7 @@ public class HttpConnectionTest
try (StacklessLogging stackless = new StacklessLogging(logger)) try (StacklessLogging stackless = new StacklessLogging(logger))
{ {
logger.info("Expect IOException: Response header too large..."); logger.info("Expect IOException: Response header too large...");
response = connector.getResponses("GET / HTTP/1.1\r\n"+ response = connector.getResponse("GET / HTTP/1.1\r\n"+
"Host: localhost\r\n" + "Host: localhost\r\n" +
"\r\n" "\r\n"
); );
@ -830,7 +837,7 @@ public class HttpConnectionTest
{ {
int offset=0; int offset=0;
response=connector.getResponses("OPTIONS * HTTP/1.1\r\n"+ response=connector.getResponse("OPTIONS * HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+ "Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain; charset=utf-8\r\n"+ "Content-Type: text/plain; charset=utf-8\r\n"+
@ -843,7 +850,7 @@ public class HttpConnectionTest
checkContains(response,offset,"HTTP/1.1 200"); checkContains(response,offset,"HTTP/1.1 200");
offset=0; offset=0;
response=connector.getResponses("GET * HTTP/1.1\r\n"+ response=connector.getResponse("GET * HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+ "Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain; charset=utf-8\r\n"+ "Content-Type: text/plain; charset=utf-8\r\n"+
@ -856,7 +863,7 @@ public class HttpConnectionTest
checkContains(response,offset,"HTTP/1.1 400"); checkContains(response,offset,"HTTP/1.1 400");
offset=0; offset=0;
response=connector.getResponses("GET ** HTTP/1.1\r\n"+ response=connector.getResponse("GET ** HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+ "Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain; charset=utf-8\r\n"+ "Content-Type: text/plain; charset=utf-8\r\n"+
@ -884,7 +891,7 @@ public class HttpConnectionTest
{ {
int offset=0; int offset=0;
response=connector.getResponses("CONNECT www.webtide.com:8080 HTTP/1.1\r\n"+ response=connector.getResponse("CONNECT www.webtide.com:8080 HTTP/1.1\r\n"+
"Host: myproxy:8888\r\n"+ "Host: myproxy:8888\r\n"+
"\r\n",200,TimeUnit.MILLISECONDS); "\r\n",200,TimeUnit.MILLISECONDS);
checkContains(response,offset,"HTTP/1.1 200"); checkContains(response,offset,"HTTP/1.1 200");

View File

@ -28,8 +28,6 @@ import java.io.InputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.AsyncContext; import javax.servlet.AsyncContext;
@ -39,7 +37,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.HttpOutput.Interceptor; import org.eclipse.jetty.server.HttpOutput.Interceptor;
import org.eclipse.jetty.server.HttpOutputTest.ChainedInterceptor; import org.eclipse.jetty.server.LocalConnector.LocalEndPoint;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HotSwapHandler; import org.eclipse.jetty.server.handler.HotSwapHandler;
import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.BufferUtil;
@ -90,7 +88,7 @@ public class HttpOutputTest
@Test @Test
public void testSimple() throws Exception public void testSimple() throws Exception
{ {
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
} }
@ -99,7 +97,7 @@ public class HttpOutputTest
@Test @Test
public void testByteUnknown() throws Exception public void testByteUnknown() throws Exception
{ {
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
} }
@ -114,7 +112,7 @@ public class HttpOutputTest
_handler._content=ByteBuffer.wrap(buffer); _handler._content=ByteBuffer.wrap(buffer);
_handler._content.limit(12*1024); _handler._content.limit(12*1024);
_handler._content.position(4*1024); _handler._content.position(4*1024);
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("\r\nXXXXXXXXXXXXXXXXXXXXXXXXXXX")); assertThat(response,containsString("\r\nXXXXXXXXXXXXXXXXXXXXXXXXXXX"));
@ -129,7 +127,7 @@ public class HttpOutputTest
{ {
Resource simple = Resource.newClassPathResource("simple/simple.txt"); Resource simple = Resource.newClassPathResource("simple/simple.txt");
_handler._contentInputStream=simple.getInputStream(); _handler._contentInputStream=simple.getInputStream();
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Content-Length: 11")); assertThat(response,containsString("Content-Length: 11"));
} }
@ -139,7 +137,7 @@ public class HttpOutputTest
{ {
Resource big = Resource.newClassPathResource("simple/big.txt"); Resource big = Resource.newClassPathResource("simple/big.txt");
_handler._contentInputStream=big.getInputStream(); _handler._contentInputStream=big.getInputStream();
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
} }
@ -157,16 +155,22 @@ public class HttpOutputTest
return filled; return filled;
} }
}; };
String response=_connector.getResponses( LocalEndPoint endp=_connector.executeRequest(
"GET / HTTP/1.1\nHost: localhost:80\n\n"+ "GET / HTTP/1.1\nHost: localhost:80\n\n"+
"GET / HTTP/1.1\nHost: localhost:80\nConnection: close\n\n" "GET / HTTP/1.1\nHost: localhost:80\nConnection: close\n\n"
); );
response=response.substring(0,response.lastIndexOf("HTTP/1.1 200 OK"));
String response = endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Transfer-Encoding: chunked")); assertThat(response,containsString("Transfer-Encoding: chunked"));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
assertThat(response,containsString("\r\n0\r\n")); assertThat(response,containsString("\r\n0\r\n"));
response = endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Connection: close"));
} }
@Test @Test
@ -174,7 +178,7 @@ public class HttpOutputTest
{ {
Resource simple = Resource.newClassPathResource("simple/simple.txt"); Resource simple = Resource.newClassPathResource("simple/simple.txt");
_handler._contentChannel=simple.getReadableByteChannel(); _handler._contentChannel=simple.getReadableByteChannel();
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Content-Length: 11")); assertThat(response,containsString("Content-Length: 11"));
} }
@ -184,7 +188,7 @@ public class HttpOutputTest
{ {
Resource big = Resource.newClassPathResource("simple/big.txt"); Resource big = Resource.newClassPathResource("simple/big.txt");
_handler._contentChannel=big.getReadableByteChannel(); _handler._contentChannel=big.getReadableByteChannel();
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -195,7 +199,7 @@ public class HttpOutputTest
{ {
Resource big = Resource.newClassPathResource("simple/big.txt"); Resource big = Resource.newClassPathResource("simple/big.txt");
_handler._content=BufferUtil.toBuffer(big,true); _handler._content=BufferUtil.toBuffer(big,true);
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Content-Length")); assertThat(response,containsString("Content-Length"));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -206,7 +210,7 @@ public class HttpOutputTest
{ {
Resource big = Resource.newClassPathResource("simple/big.txt"); Resource big = Resource.newClassPathResource("simple/big.txt");
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Content-Length")); assertThat(response,containsString("Content-Length"));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -249,15 +253,19 @@ public class HttpOutputTest
} }
}; };
String response=_connector.getResponses( LocalEndPoint endp=_connector.executeRequest(
"GET / HTTP/1.1\nHost: localhost:80\n\n"+ "GET / HTTP/1.1\nHost: localhost:80\n\n"+
"GET / HTTP/1.1\nHost: localhost:80\nConnection: close\n\n" "GET / HTTP/1.1\nHost: localhost:80\nConnection: close\n\n"
); );
response=response.substring(0,response.lastIndexOf("HTTP/1.1 200 OK"));
String response = endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Transfer-Encoding: chunked")); assertThat(response,containsString("Transfer-Encoding: chunked"));
assertThat(response,containsString("\r\n0\r\n")); assertThat(response,containsString("\r\n0\r\n"));
response = endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Connection: close"));
} }
@Test @Test
@ -268,7 +276,7 @@ public class HttpOutputTest
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
_handler._arrayBuffer=new byte[1]; _handler._arrayBuffer=new byte[1];
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -282,7 +290,7 @@ public class HttpOutputTest
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
_handler._arrayBuffer=new byte[8]; _handler._arrayBuffer=new byte[8];
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -296,7 +304,7 @@ public class HttpOutputTest
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
_handler._arrayBuffer=new byte[4000]; _handler._arrayBuffer=new byte[4000];
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -310,7 +318,7 @@ public class HttpOutputTest
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
_handler._arrayBuffer=new byte[8192]; _handler._arrayBuffer=new byte[8192];
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -324,7 +332,7 @@ public class HttpOutputTest
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
_handler._arrayBuffer=new byte[1]; _handler._arrayBuffer=new byte[1];
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Content-Length")); assertThat(response,containsString("Content-Length"));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -338,7 +346,7 @@ public class HttpOutputTest
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
_handler._arrayBuffer=new byte[8]; _handler._arrayBuffer=new byte[8];
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Content-Length")); assertThat(response,containsString("Content-Length"));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -352,7 +360,7 @@ public class HttpOutputTest
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
_handler._arrayBuffer=new byte[4000]; _handler._arrayBuffer=new byte[4000];
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Content-Length")); assertThat(response,containsString("Content-Length"));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -366,7 +374,7 @@ public class HttpOutputTest
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
_handler._arrayBuffer=new byte[8192]; _handler._arrayBuffer=new byte[8192];
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Content-Length")); assertThat(response,containsString("Content-Length"));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -383,7 +391,7 @@ public class HttpOutputTest
_handler._content.put(i,(byte)'x'); _handler._content.put(i,(byte)'x');
_handler._arrayBuffer=new byte[8192]; _handler._arrayBuffer=new byte[8192];
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Content-Length")); assertThat(response,containsString("Content-Length"));
} }
@ -397,7 +405,7 @@ public class HttpOutputTest
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
_handler._byteBuffer=BufferUtil.allocate(8); _handler._byteBuffer=BufferUtil.allocate(8);
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -411,7 +419,7 @@ public class HttpOutputTest
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
_handler._byteBuffer=BufferUtil.allocate(4000); _handler._byteBuffer=BufferUtil.allocate(4000);
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -425,7 +433,7 @@ public class HttpOutputTest
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
_handler._byteBuffer=BufferUtil.allocate(8192); _handler._byteBuffer=BufferUtil.allocate(8192);
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -441,7 +449,7 @@ public class HttpOutputTest
_handler._arrayBuffer=new byte[1]; _handler._arrayBuffer=new byte[1];
_handler._async=true; _handler._async=true;
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -456,7 +464,7 @@ public class HttpOutputTest
_handler._arrayBuffer=new byte[8]; _handler._arrayBuffer=new byte[8];
_handler._async=true; _handler._async=true;
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -471,7 +479,7 @@ public class HttpOutputTest
_handler._arrayBuffer=new byte[4000]; _handler._arrayBuffer=new byte[4000];
_handler._async=true; _handler._async=true;
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -486,7 +494,7 @@ public class HttpOutputTest
_handler._arrayBuffer=new byte[8192]; _handler._arrayBuffer=new byte[8192];
_handler._async=true; _handler._async=true;
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -504,7 +512,7 @@ public class HttpOutputTest
_handler._arrayBuffer=new byte[8192]; _handler._arrayBuffer=new byte[8192];
_handler._async=true; _handler._async=true;
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Content-Length")); assertThat(response,containsString("Content-Length"));
} }
@ -520,7 +528,7 @@ public class HttpOutputTest
_handler._byteBuffer=BufferUtil.allocate(8); _handler._byteBuffer=BufferUtil.allocate(8);
_handler._async=true; _handler._async=true;
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -535,7 +543,7 @@ public class HttpOutputTest
_handler._byteBuffer=BufferUtil.allocate(4000); _handler._byteBuffer=BufferUtil.allocate(4000);
_handler._async=true; _handler._async=true;
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -550,7 +558,7 @@ public class HttpOutputTest
_handler._byteBuffer=BufferUtil.allocate(8192); _handler._byteBuffer=BufferUtil.allocate(8192);
_handler._async=true; _handler._async=true;
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tThis is a big file")); assertThat(response,containsString("400\tThis is a big file"));
@ -566,7 +574,7 @@ public class HttpOutputTest
_handler._async=true; _handler._async=true;
int start=_handler._owp.get(); int start=_handler._owp.get();
String response=_connector.getResponses("HEAD / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("HEAD / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(_handler._owp.get()-start,Matchers.greaterThan(0)); assertThat(_handler._owp.get()-start,Matchers.greaterThan(0));
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
@ -583,7 +591,7 @@ public class HttpOutputTest
_handler._content=BufferUtil.toBuffer(big,false); _handler._content=BufferUtil.toBuffer(big,false);
_handler._arrayBuffer=new byte[4000]; _handler._arrayBuffer=new byte[4000];
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Content-Length: 11")); assertThat(response,containsString("Content-Length: 11"));
assertThat(response,containsString("simple text")); assertThat(response,containsString("simple text"));
@ -600,7 +608,7 @@ public class HttpOutputTest
_handler._arrayBuffer=new byte[4000]; _handler._arrayBuffer=new byte[4000];
int start=_handler._owp.get(); int start=_handler._owp.get();
String response=_connector.getResponses("HEAD / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("HEAD / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(_handler._owp.get()-start,Matchers.equalTo(1)); assertThat(_handler._owp.get()-start,Matchers.equalTo(1));
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("Content-Length: 11")); assertThat(response,containsString("Content-Length: 11"));
@ -644,7 +652,7 @@ public class HttpOutputTest
} }
}; };
String response=_connector.getResponses("GET / HTTP/1.0\nHost: localhost:80\n\n"); String response=_connector.getResponse("GET / HTTP/1.0\nHost: localhost:80\n\n");
assertThat(response,containsString("HTTP/1.1 200 OK")); assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,Matchers.not(containsString("Content-Length"))); assertThat(response,Matchers.not(containsString("Content-Length")));
assertThat(response,containsString("400\tTHIS IS A BIGGER FILE")); assertThat(response,containsString("400\tTHIS IS A BIGGER FILE"));

View File

@ -26,7 +26,9 @@ package org.eclipse.jetty.server;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.util.Date; import java.util.Date;
@ -36,10 +38,12 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.server.LocalConnector.LocalEndPoint;
import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.toolchain.test.AdvancedRunner;
import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.log.StacklessLogging;
import org.hamcrest.Matchers;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@ -121,7 +125,7 @@ public class PartialRFC2616Test
{ {
int offset=0; int offset=0;
// Chunk last // Chunk last
String response = connector.getResponses( String response = connector.getResponse(
"GET /R1 HTTP/1.1\n" + "GET /R1 HTTP/1.1\n" +
"Host: localhost\n" + "Host: localhost\n" +
"Transfer-Encoding: chunked,identity\n" + "Transfer-Encoding: chunked,identity\n" +
@ -136,9 +140,10 @@ public class PartialRFC2616Test
@Test @Test
public void test3_6_b() throws Exception public void test3_6_b() throws Exception
{ {
String response;
int offset=0; int offset=0;
// Chunked // Chunked
String response = connector.getResponses( LocalEndPoint endp=connector.executeRequest(
"GET /R1 HTTP/1.1\n" + "GET /R1 HTTP/1.1\n" +
"Host: localhost\n" + "Host: localhost\n" +
"Transfer-Encoding: chunked\n" + "Transfer-Encoding: chunked\n" +
@ -165,18 +170,25 @@ public class PartialRFC2616Test
"Host: localhost\n" + "Host: localhost\n" +
"Connection: close\n" + "Connection: close\n" +
"\n"); "\n");
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200","3.6.1 Chunking"); offset=checkContains(response,offset,"HTTP/1.1 200","3.6.1 Chunking");
offset=checkContains(response,offset,"12345","3.6.1 Chunking"); offset=checkContains(response,offset,"12345","3.6.1 Chunking");
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200","3.6.1 Chunking"); offset=checkContains(response,offset,"HTTP/1.1 200","3.6.1 Chunking");
offset=checkContains(response,offset,"6789abcde","3.6.1 Chunking"); offset=checkContains(response,offset,"6789abcde","3.6.1 Chunking");
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"/R3","3.6.1 Chunking"); offset=checkContains(response,offset,"/R3","3.6.1 Chunking");
} }
@Test @Test
public void test3_6_c() throws Exception public void test3_6_c() throws Exception
{ {
String response;
int offset=0; int offset=0;
String response = connector.getResponses( LocalEndPoint endp=connector.executeRequest(
"POST /R1 HTTP/1.1\n" + "POST /R1 HTTP/1.1\n" +
"Host: localhost\n" + "Host: localhost\n" +
"Transfer-Encoding: chunked\n" + "Transfer-Encoding: chunked\n" +
@ -203,20 +215,29 @@ public class PartialRFC2616Test
"Host: localhost\n" + "Host: localhost\n" +
"Connection: close\n" + "Connection: close\n" +
"\n"); "\n");
offset=0;
response = endp.getResponse();
checkNotContained(response,"HTTP/1.1 100","3.6.1 Chunking"); checkNotContained(response,"HTTP/1.1 100","3.6.1 Chunking");
offset=checkContains(response,offset,"HTTP/1.1 200","3.6.1 Chunking"); offset=checkContains(response,offset,"HTTP/1.1 200","3.6.1 Chunking");
offset=checkContains(response,offset,"fghIjk","3.6.1 Chunking"); offset=checkContains(response,offset,"fghIjk","3.6.1 Chunking");
offset=0;
response = endp.getResponse();
checkNotContained(response,"HTTP/1.1 100","3.6.1 Chunking");
offset=checkContains(response,offset,"HTTP/1.1 200","3.6.1 Chunking"); offset=checkContains(response,offset,"HTTP/1.1 200","3.6.1 Chunking");
offset=checkContains(response,offset,"lmnoPqrst","3.6.1 Chunking"); offset=checkContains(response,offset,"lmnoPqrst","3.6.1 Chunking");
offset=0;
response = endp.getResponse();
checkNotContained(response,"HTTP/1.1 100","3.6.1 Chunking");
offset=checkContains(response,offset,"/R3","3.6.1 Chunking"); offset=checkContains(response,offset,"/R3","3.6.1 Chunking");
} }
@Test @Test
public void test3_6_d() throws Exception public void test3_6_d() throws Exception
{ {
String response;
int offset=0; int offset=0;
// Chunked and keep alive // Chunked and keep alive
String response = connector.getResponses( LocalEndPoint endp=connector.executeRequest(
"GET /R1 HTTP/1.1\n" + "GET /R1 HTTP/1.1\n" +
"Host: localhost\n" + "Host: localhost\n" +
"Transfer-Encoding: chunked\n" + "Transfer-Encoding: chunked\n" +
@ -233,8 +254,12 @@ public class PartialRFC2616Test
"Host: localhost\n" + "Host: localhost\n" +
"Connection: close\n" + "Connection: close\n" +
"\n"); "\n");
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200","3.6.1 Chunking")+10; offset=checkContains(response,offset,"HTTP/1.1 200","3.6.1 Chunking")+10;
offset=checkContains(response,offset,"123456","3.6.1 Chunking"); offset=checkContains(response,offset,"123456","3.6.1 Chunking");
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"/R2","3.6.1 Chunking")+10; offset=checkContains(response,offset,"/R2","3.6.1 Chunking")+10;
} }
@ -257,9 +282,10 @@ public class PartialRFC2616Test
@Test @Test
public void test4_4_2() throws Exception public void test4_4_2() throws Exception
{ {
String response;
int offset=0; int offset=0;
// If _content length not used, second request will not be read. // If _content length not used, second request will not be read.
String response = connector.getResponses( LocalEndPoint endp=connector.executeRequest(
"GET /R1 HTTP/1.1\n" + "GET /R1 HTTP/1.1\n" +
"Host: localhost\n" + "Host: localhost\n" +
"Transfer-Encoding: identity\n" + "Transfer-Encoding: identity\n" +
@ -273,8 +299,12 @@ public class PartialRFC2616Test
"Transfer-Encoding: other\n" + "Transfer-Encoding: other\n" +
"Connection: close\n" + "Connection: close\n" +
"\n"); "\n");
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200 OK","2. identity")+10; offset=checkContains(response,offset,"HTTP/1.1 200 OK","2. identity")+10;
offset=checkContains(response,offset,"/R1","2. identity")+3; offset=checkContains(response,offset,"/R1","2. identity")+3;
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200 OK","2. identity")+10; offset=checkContains(response,offset,"HTTP/1.1 200 OK","2. identity")+10;
offset=checkContains(response,offset,"/R2","2. identity")+3; offset=checkContains(response,offset,"/R2","2. identity")+3;
} }
@ -285,7 +315,8 @@ public class PartialRFC2616Test
// _content length is ignored, as chunking is used. If it is // _content length is ignored, as chunking is used. If it is
// not ignored, the second request wont be seen. // not ignored, the second request wont be seen.
int offset=0; int offset=0;
String response = connector.getResponses( String response;
LocalEndPoint endp=connector.executeRequest(
"GET /R1 HTTP/1.1\n" + "GET /R1 HTTP/1.1\n" +
"Host: localhost\n" + "Host: localhost\n" +
"Transfer-Encoding: chunked\n" + "Transfer-Encoding: chunked\n" +
@ -306,9 +337,13 @@ public class PartialRFC2616Test
"Content-Length: 6\n" + "Content-Length: 6\n" +
"\n" + "\n" +
"abcdef"); "abcdef");
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200 OK","3. ignore c-l")+1; offset=checkContains(response,offset,"HTTP/1.1 200 OK","3. ignore c-l")+1;
offset=checkContains(response,offset,"/R1","3. ignore c-l")+1; offset=checkContains(response,offset,"/R1","3. ignore c-l")+1;
offset=checkContains(response,offset,"123456","3. ignore c-l")+1; offset=checkContains(response,offset,"123456","3. ignore c-l")+1;
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200 OK","3. ignore c-l")+1; offset=checkContains(response,offset,"HTTP/1.1 200 OK","3. ignore c-l")+1;
offset=checkContains(response,offset,"/R2","3. _content-length")+1; offset=checkContains(response,offset,"/R2","3. _content-length")+1;
offset=checkContains(response,offset,"abcdef","3. _content-length")+1; offset=checkContains(response,offset,"abcdef","3. _content-length")+1;
@ -320,7 +355,7 @@ public class PartialRFC2616Test
// No _content length // No _content length
assertTrue("Skip 411 checks as IE breaks this rule",true); assertTrue("Skip 411 checks as IE breaks this rule",true);
// offset=0; connector.reopen(); // offset=0; connector.reopen();
// response=connector.getResponses("GET /R2 HTTP/1.1\n"+ // response=connector.getResponse("GET /R2 HTTP/1.1\n"+
// "Host: localhost\n"+ // "Host: localhost\n"+
// "Content-Type: text/plain\n"+ // "Content-Type: text/plain\n"+
// "Connection: close\n"+ // "Connection: close\n"+
@ -329,7 +364,7 @@ public class PartialRFC2616Test
// offset=checkContains(response,offset, // offset=checkContains(response,offset,
// "HTTP/1.1 411 ","411 length required")+10; // "HTTP/1.1 411 ","411 length required")+10;
// offset=0; connector.reopen(); // offset=0; connector.reopen();
// response=connector.getResponses("GET /R2 HTTP/1.0\n"+ // response=connector.getResponse("GET /R2 HTTP/1.0\n"+
// "Content-Type: text/plain\n"+ // "Content-Type: text/plain\n"+
// "\n"+ // "\n"+
// "123456"); // "123456");
@ -343,7 +378,7 @@ public class PartialRFC2616Test
{ {
// Default Host // Default Host
int offset=0; int offset=0;
String response = connector.getResponses("GET http://VirtualHost:8888/path/R1 HTTP/1.1\n" + "Host: wronghost\n" + "Connection: close\n" + "\n"); String response = connector.getResponse("GET http://VirtualHost:8888/path/R1 HTTP/1.1\n" + "Host: wronghost\n" + "Connection: close\n" + "\n");
offset=checkContains(response,offset,"HTTP/1.1 200","Virtual host")+1; offset=checkContains(response,offset,"HTTP/1.1 200","Virtual host")+1;
offset=checkContains(response,offset,"Virtual Dump","Virtual host")+1; offset=checkContains(response,offset,"Virtual Dump","Virtual host")+1;
offset=checkContains(response,offset,"pathInfo=/path/R1","Virtual host")+1; offset=checkContains(response,offset,"pathInfo=/path/R1","Virtual host")+1;
@ -355,14 +390,14 @@ public class PartialRFC2616Test
{ {
// Default Host // Default Host
int offset=0; int offset=0;
String response = connector.getResponses("GET /path/R1 HTTP/1.1\n" + "Host: localhost\n" + "Connection: close\n" + "\n"); String response = connector.getResponse("GET /path/R1 HTTP/1.1\n" + "Host: localhost\n" + "Connection: close\n" + "\n");
offset=checkContains(response,offset,"HTTP/1.1 200","Default host")+1; offset=checkContains(response,offset,"HTTP/1.1 200","Default host")+1;
offset=checkContains(response,offset,"Dump HttpHandler","Default host")+1; offset=checkContains(response,offset,"Dump HttpHandler","Default host")+1;
offset=checkContains(response,offset,"pathInfo=/path/R1","Default host")+1; offset=checkContains(response,offset,"pathInfo=/path/R1","Default host")+1;
// Virtual Host // Virtual Host
offset=0; offset=0;
response=connector.getResponses("GET /path/R2 HTTP/1.1\n"+"Host: VirtualHost\n"+"Connection: close\n"+"\n"); response=connector.getResponse("GET /path/R2 HTTP/1.1\n"+"Host: VirtualHost\n"+"Connection: close\n"+"\n");
offset=checkContains(response,offset,"HTTP/1.1 200","Default host")+1; offset=checkContains(response,offset,"HTTP/1.1 200","Default host")+1;
offset=checkContains(response,offset,"Virtual Dump","virtual host")+1; offset=checkContains(response,offset,"Virtual Dump","virtual host")+1;
offset=checkContains(response,offset,"pathInfo=/path/R2","Default host")+1; offset=checkContains(response,offset,"pathInfo=/path/R2","Default host")+1;
@ -373,21 +408,21 @@ public class PartialRFC2616Test
{ {
// Virtual Host // Virtual Host
int offset=0; int offset=0;
String response = connector.getResponses("GET /path/R1 HTTP/1.1\n" + "Host: VirtualHost\n" + "Connection: close\n" + "\n"); String response = connector.getResponse("GET /path/R1 HTTP/1.1\n" + "Host: VirtualHost\n" + "Connection: close\n" + "\n");
offset=checkContains(response,offset,"HTTP/1.1 200","2. virtual host field")+1; offset=checkContains(response,offset,"HTTP/1.1 200","2. virtual host field")+1;
offset=checkContains(response,offset,"Virtual Dump","2. virtual host field")+1; offset=checkContains(response,offset,"Virtual Dump","2. virtual host field")+1;
offset=checkContains(response,offset,"pathInfo=/path/R1","2. virtual host field")+1; offset=checkContains(response,offset,"pathInfo=/path/R1","2. virtual host field")+1;
// Virtual Host case insensitive // Virtual Host case insensitive
offset=0; offset=0;
response=connector.getResponses("GET /path/R1 HTTP/1.1\n"+"Host: ViRtUalhOst\n"+"Connection: close\n"+"\n"); response=connector.getResponse("GET /path/R1 HTTP/1.1\n"+"Host: ViRtUalhOst\n"+"Connection: close\n"+"\n");
offset=checkContains(response,offset,"HTTP/1.1 200","2. virtual host field")+1; offset=checkContains(response,offset,"HTTP/1.1 200","2. virtual host field")+1;
offset=checkContains(response,offset,"Virtual Dump","2. virtual host field")+1; offset=checkContains(response,offset,"Virtual Dump","2. virtual host field")+1;
offset=checkContains(response,offset,"pathInfo=/path/R1","2. virtual host field")+1; offset=checkContains(response,offset,"pathInfo=/path/R1","2. virtual host field")+1;
// Virtual Host // Virtual Host
offset=0; offset=0;
response=connector.getResponses("GET /path/R1 HTTP/1.1\n"+"\n"); response=connector.getResponse("GET /path/R1 HTTP/1.1\n"+"\n");
offset=checkContains(response,offset,"HTTP/1.1 400","3. no host")+1; offset=checkContains(response,offset,"HTTP/1.1 400","3. no host")+1;
} }
@ -395,23 +430,28 @@ public class PartialRFC2616Test
public void test8_1() throws Exception public void test8_1() throws Exception
{ {
int offset=0; int offset=0;
String response = connector.getResponses("GET /R1 HTTP/1.1\n" + "Host: localhost\n" + "\n", 250, TimeUnit.MILLISECONDS); String response = connector.getResponse("GET /R1 HTTP/1.1\n" + "Host: localhost\n" + "\n", 250, TimeUnit.MILLISECONDS);
offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","8.1.2 default")+10; offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","8.1.2 default")+10;
checkContains(response,offset,"Content-Length: ","8.1.2 default"); checkContains(response,offset,"Content-Length: ","8.1.2 default");
offset=0; LocalEndPoint endp=connector.executeRequest("GET /R1 HTTP/1.1\n"+"Host: localhost\n"+"\n"+
response=connector.getResponses("GET /R1 HTTP/1.1\n"+"Host: localhost\n"+"\n"+
"GET /R2 HTTP/1.1\n"+"Host: localhost\n"+"Connection: close\n"+"\n"+ "GET /R2 HTTP/1.1\n"+"Host: localhost\n"+"Connection: close\n"+"\n"+
"GET /R3 HTTP/1.1\n"+"Host: localhost\n"+"Connection: close\n"+"\n"); "GET /R3 HTTP/1.1\n"+"Host: localhost\n"+"Connection: close\n"+"\n");
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","8.1.2 default")+1; offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","8.1.2 default")+1;
offset=checkContains(response,offset,"/R1","8.1.2 default")+1; offset=checkContains(response,offset,"/R1","8.1.2 default")+1;
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","8.1.2.2 pipeline")+11; offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","8.1.2.2 pipeline")+11;
offset=checkContains(response,offset,"Connection: close","8.1.2.2 pipeline")+1; offset=checkContains(response,offset,"Connection: close","8.1.2.2 pipeline")+1;
offset=checkContains(response,offset,"/R2","8.1.2.1 close")+3; offset=checkContains(response,offset,"/R2","8.1.2.1 close")+3;
assertEquals("8.1.2.1 close",-1,response.indexOf("/R3")); offset=0;
response = endp.getResponse();
assertThat(response,nullValue());
} }
@ -420,7 +460,7 @@ public class PartialRFC2616Test
{ {
// Expect Failure // Expect Failure
int offset=0; int offset=0;
String response = connector.getResponses( String response = connector.getResponse(
"GET /R1 HTTP/1.1\n" + "GET /R1 HTTP/1.1\n" +
"Host: localhost\n" + "Host: localhost\n" +
"Expect: unknown\n" + "Expect: unknown\n" +
@ -435,7 +475,7 @@ public class PartialRFC2616Test
{ {
// Expect with body: client sends the content right away, we should not send 100-Continue // Expect with body: client sends the content right away, we should not send 100-Continue
int offset=0; int offset=0;
String response = connector.getResponses( String response = connector.getResponse(
"GET /R1 HTTP/1.1\n" + "GET /R1 HTTP/1.1\n" +
"Host: localhost\n" + "Host: localhost\n" +
"Expect: 100-continue\n" + "Expect: 100-continue\n" +
@ -460,15 +500,13 @@ public class PartialRFC2616Test
"Content-Type: text/plain\n"+ "Content-Type: text/plain\n"+
"Content-Length: 8\n"+ "Content-Length: 8\n"+
"\n"); "\n");
Thread.sleep(200); String infomational= endp.getResponse();
String infomational= endp.takeOutputString();
offset=checkContains(infomational,offset,"HTTP/1.1 100 ","8.2.3 expect 100")+1; offset=checkContains(infomational,offset,"HTTP/1.1 100 ","8.2.3 expect 100")+1;
checkNotContained(infomational,offset,"HTTP/1.1 200","8.2.3 expect 100"); checkNotContained(infomational,offset,"HTTP/1.1 200","8.2.3 expect 100");
endp.addInput("654321\015\012"); endp.addInput("654321\015\012");
Thread.sleep(200); String response= endp.getResponse();
String response= endp.takeOutputString();
offset=0; offset=0;
offset=checkContains(response,offset,"HTTP/1.1 200","8.2.3 expect 100")+1; offset=checkContains(response,offset,"HTTP/1.1 200","8.2.3 expect 100")+1;
offset=checkContains(response,offset,"654321","8.2.3 expect 100")+1; offset=checkContains(response,offset,"654321","8.2.3 expect 100")+1;
@ -479,7 +517,7 @@ public class PartialRFC2616Test
{ {
// Expect 100 not sent // Expect 100 not sent
int offset=0; int offset=0;
String response = connector.getResponses("GET /R1?error=401 HTTP/1.1\n" + String response = connector.getResponse("GET /R1?error=401 HTTP/1.1\n" +
"Host: localhost\n" + "Host: localhost\n" +
"Expect: 100-continue\n" + "Expect: 100-continue\n" +
"Content-Type: text/plain\n" + "Content-Type: text/plain\n" +
@ -495,14 +533,14 @@ public class PartialRFC2616Test
{ {
int offset=0; int offset=0;
String response=connector.getResponses("OPTIONS * HTTP/1.1\n"+ String response=connector.getResponse("OPTIONS * HTTP/1.1\n"+
"Connection: close\n"+ "Connection: close\n"+
"Host: localhost\n"+ "Host: localhost\n"+
"\n"); "\n");
offset=checkContains(response,offset, "HTTP/1.1 200","200")+1; offset=checkContains(response,offset, "HTTP/1.1 200","200")+1;
offset=0; offset=0;
response=connector.getResponses("GET * HTTP/1.1\n"+ response=connector.getResponse("GET * HTTP/1.1\n"+
"Connection: close\n"+ "Connection: close\n"+
"Host: localhost\n"+ "Host: localhost\n"+
"\n"); "\n");
@ -514,13 +552,13 @@ public class PartialRFC2616Test
{ {
try try
{ {
String get=connector.getResponses("GET /R1 HTTP/1.0\n"+"Host: localhost\n"+"\n"); String get=connector.getResponse("GET /R1 HTTP/1.0\n"+"Host: localhost\n"+"\n");
checkContains(get,0,"HTTP/1.1 200","GET"); checkContains(get,0,"HTTP/1.1 200","GET");
checkContains(get,0,"Content-Type: text/html","GET _content"); checkContains(get,0,"Content-Type: text/html","GET _content");
checkContains(get,0,"<html>","GET body"); checkContains(get,0,"<html>","GET body");
String head=connector.getResponses("HEAD /R1 HTTP/1.0\n"+"Host: localhost\n"+"\n"); String head=connector.getResponse("HEAD /R1 HTTP/1.0\n"+"Host: localhost\n"+"\n");
checkContains(head,0,"HTTP/1.1 200","HEAD"); checkContains(head,0,"HTTP/1.1 200","HEAD");
checkContains(head,0,"Content-Type: text/html","HEAD _content"); checkContains(head,0,"Content-Type: text/html","HEAD _content");
assertEquals("HEAD no body",-1,head.indexOf("<html>")); assertEquals("HEAD no body",-1,head.indexOf("<html>"));
@ -540,19 +578,19 @@ public class PartialRFC2616Test
try (StacklessLogging stackless = new StacklessLogging(HttpParser.class)) try (StacklessLogging stackless = new StacklessLogging(HttpParser.class))
{ {
int offset=0; int offset=0;
String response = connector.getResponses("GET /R1 HTTP/1.0\n" + "Connection: close\n" + "\n"); String response = connector.getResponse("GET /R1 HTTP/1.0\n" + "Connection: close\n" + "\n");
offset=checkContains(response,offset,"HTTP/1.1 200","200")+1; offset=checkContains(response,offset,"HTTP/1.1 200","200")+1;
offset=0; offset=0;
response=connector.getResponses("GET /R1 HTTP/1.1\n"+"Connection: close\n"+"\n"); response=connector.getResponse("GET /R1 HTTP/1.1\n"+"Connection: close\n"+"\n");
offset=checkContains(response,offset,"HTTP/1.1 400","400")+1; offset=checkContains(response,offset,"HTTP/1.1 400","400")+1;
offset=0; offset=0;
response=connector.getResponses("GET /R1 HTTP/1.1\n"+"Host: localhost\n"+"Connection: close\n"+"\n"); response=connector.getResponse("GET /R1 HTTP/1.1\n"+"Host: localhost\n"+"Connection: close\n"+"\n");
offset=checkContains(response,offset,"HTTP/1.1 200","200")+1; offset=checkContains(response,offset,"HTTP/1.1 200","200")+1;
offset=0; offset=0;
response=connector.getResponses("GET /R1 HTTP/1.1\n"+"Host:\n"+"Connection: close\n"+"\n"); response=connector.getResponse("GET /R1 HTTP/1.1\n"+"Host:\n"+"Connection: close\n"+"\n");
offset=checkContains(response,offset,"HTTP/1.1 400","400")+1; offset=checkContains(response,offset,"HTTP/1.1 400","400")+1;
} }
} }
@ -563,17 +601,17 @@ public class PartialRFC2616Test
try try
{ {
int offset=0; int offset=0;
String response = connector.getResponses("GET /R1 HTTP/1.0\n" + "\n"); String response = connector.getResponse("GET /R1 HTTP/1.0\n" + "\n");
offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 default close")+10; offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 default close")+10;
checkNotContained(response,offset,"Connection: close","19.6.2 not assumed"); checkNotContained(response,offset,"Connection: close","19.6.2 not assumed");
LocalEndPoint endp=connector.executeRequest(
"GET /R1 HTTP/1.0\n"+"Host: localhost\n"+"Connection: keep-alive\n"+"\n"+
"GET /R2 HTTP/1.0\n"+"Host: localhost\n"+"Connection: close\n"+"\n"+
"GET /R3 HTTP/1.0\n"+"Host: localhost\n"+"Connection: close\n"+"\n");
offset=0; offset=0;
response=connector.getResponses("GET /R1 HTTP/1.0\n"+"Host: localhost\n"+"Connection: keep-alive\n"+"\n"+ response = endp.getResponse();
"GET /R2 HTTP/1.0\n"+"Host: localhost\n"+"Connection: close\n"+"\n"+
"GET /R3 HTTP/1.0\n"+"Host: localhost\n"+"Connection: close\n"+"\n");
offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 1")+1; offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 1")+1;
offset=checkContains(response,offset,"Connection: keep-alive","19.6.2 Keep-alive 1")+1; offset=checkContains(response,offset,"Connection: keep-alive","19.6.2 Keep-alive 1")+1;
@ -581,33 +619,44 @@ public class PartialRFC2616Test
offset=checkContains(response,offset,"/R1","19.6.2 Keep-alive 1")+1; offset=checkContains(response,offset,"/R1","19.6.2 Keep-alive 1")+1;
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 2")+11; offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 2")+11;
offset=checkContains(response,offset,"/R2","19.6.2 Keep-alive close")+3; offset=checkContains(response,offset,"/R2","19.6.2 Keep-alive close")+3;
assertEquals("19.6.2 closed",-1,response.indexOf("/R3")); offset=0;
response = endp.getResponse();
assertThat("19.6.2 closed",response,nullValue());
offset=0; offset=0;
response=connector.getResponses("GET /R1 HTTP/1.0\n"+"Host: localhost\n"+"Connection: keep-alive\n"+"Content-Length: 10\n"+"\n"+"1234567890\n"+ endp=connector.executeRequest(
"GET /R1 HTTP/1.0\n"+"Host: localhost\n"+"Connection: keep-alive\n"+"Content-Length: 10\n"+"\n"+"1234567890\n"+
"GET /RA HTTP/1.0\n"+"Host: localhost\n"+"Connection: keep-alive\n"+"Content-Length: 10\n"+"\n"+"ABCDEFGHIJ\n"+ "GET /RA HTTP/1.0\n"+"Host: localhost\n"+"Connection: keep-alive\n"+"Content-Length: 10\n"+"\n"+"ABCDEFGHIJ\n"+
"GET /R2 HTTP/1.0\n"+"Host: localhost\n"+"Connection: close\n"+"\n"+
"GET /R2 HTTP/1.0\n"+"Host: localhost\n"+"Connection: close\n"+"\n"+ "GET /R3 HTTP/1.0\n"+"Host: localhost\n"+"Connection: close\n"+"\n");
"GET /R3 HTTP/1.0\n"+"Host: localhost\n"+"Connection: close\n"+"\n"); offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 1")+1; offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 1")+1;
offset=checkContains(response,offset,"Connection: keep-alive","19.6.2 Keep-alive 1")+1; offset=checkContains(response,offset,"Connection: keep-alive","19.6.2 Keep-alive 1")+1;
offset=checkContains(response,offset,"<html>","19.6.2 Keep-alive 1")+1; offset=checkContains(response,offset,"<html>","19.6.2 Keep-alive 1")+1;
offset=checkContains(response,offset,"1234567890","19.6.2 Keep-alive 1")+1; offset=checkContains(response,offset,"1234567890","19.6.2 Keep-alive 1")+1;
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 1")+1; offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 1")+1;
offset=checkContains(response,offset,"Connection: keep-alive","19.6.2 Keep-alive 1")+1; offset=checkContains(response,offset,"Connection: keep-alive","19.6.2 Keep-alive 1")+1;
offset=checkContains(response,offset,"<html>","19.6.2 Keep-alive 1")+1; offset=checkContains(response,offset,"<html>","19.6.2 Keep-alive 1")+1;
offset=checkContains(response,offset,"ABCDEFGHIJ","19.6.2 Keep-alive 1")+1; offset=checkContains(response,offset,"ABCDEFGHIJ","19.6.2 Keep-alive 1")+1;
offset=0;
response = endp.getResponse();
offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 2")+11; offset=checkContains(response,offset,"HTTP/1.1 200 OK\015\012","19.6.2 Keep-alive 2")+11;
offset=checkContains(response,offset,"/R2","19.6.2 Keep-alive close")+3; offset=checkContains(response,offset,"/R2","19.6.2 Keep-alive close")+3;
assertEquals("19.6.2 closed",-1,response.indexOf("/R3")); offset=0;
response = endp.getResponse();
assertThat("19.6.2 closed",response,nullValue());
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -56,6 +56,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part; import javax.servlet.http.Part;
import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.LocalConnector.LocalEndPoint;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.handler.ErrorHandler;
@ -128,7 +129,7 @@ public class RequestTest
"Connection: close\n"+ "Connection: close\n"+
"\n"; "\n";
String responses=_connector.getResponses(request); String responses=_connector.getResponse(request);
assertTrue(responses.startsWith("HTTP/1.1 200")); assertTrue(responses.startsWith("HTTP/1.1 200"));
} }
@ -173,7 +174,7 @@ public class RequestTest
"Name: \n"+ "Name: \n"+
"\n"; "\n";
String responses=_connector.getResponses(request); String responses=_connector.getResponse(request);
assertTrue(responses.startsWith("HTTP/1.1 200")); assertTrue(responses.startsWith("HTTP/1.1 200"));
} }
@ -222,7 +223,7 @@ public class RequestTest
"\r\n"+ "\r\n"+
multipart; multipart;
String responses=_connector.getResponses(request); String responses=_connector.getResponse(request);
assertTrue(responses.startsWith("HTTP/1.1 200")); assertTrue(responses.startsWith("HTTP/1.1 200"));
} }
@ -259,7 +260,7 @@ public class RequestTest
"Accept-Language: da, en-gb;q=0.8, en;q=0.7\r\n"+ "Accept-Language: da, en-gb;q=0.8, en;q=0.7\r\n"+
"Accept-Language: XX;q=0, en-au;q=0.9\r\n"+ "Accept-Language: XX;q=0, en-au;q=0.9\r\n"+
"\r\n"; "\r\n";
String response = _connector.getResponses(request); String response = _connector.getResponse(request);
assertThat(response,Matchers.containsString(" 200 OK")); assertThat(response,Matchers.containsString(" 200 OK"));
} }
@ -320,7 +321,7 @@ public class RequestTest
"\r\n"+ "\r\n"+
multipart; multipart;
String responses=_connector.getResponses(request); String responses=_connector.getResponse(request);
// System.err.println(responses); // System.err.println(responses);
assertTrue(responses.startsWith("HTTP/1.1 200")); assertTrue(responses.startsWith("HTTP/1.1 200"));
} }
@ -382,7 +383,7 @@ public class RequestTest
try(StacklessLogging stackless = new StacklessLogging(HttpChannel.class)) try(StacklessLogging stackless = new StacklessLogging(HttpChannel.class))
{ {
String responses=_connector.getResponses(request); String responses=_connector.getResponse(request);
//System.err.println(responses); //System.err.println(responses);
assertTrue(responses.startsWith("HTTP/1.1 500")); assertTrue(responses.startsWith("HTTP/1.1 500"));
} }
@ -411,7 +412,7 @@ public class RequestTest
"\n"; "\n";
LOG.info("Expecting NotUtf8Exception in state 36..."); LOG.info("Expecting NotUtf8Exception in state 36...");
String responses=_connector.getResponses(request); String responses=_connector.getResponse(request);
assertThat(responses,startsWith("HTTP/1.1 200")); assertThat(responses,startsWith("HTTP/1.1 200"));
} }
@ -433,7 +434,7 @@ public class RequestTest
"Connection: close\n"+ "Connection: close\n"+
"\n"; "\n";
String responses=_connector.getResponses(request); String responses=_connector.getResponse(request);
assertThat(responses, Matchers.startsWith("HTTP/1.1 400")); assertThat(responses, Matchers.startsWith("HTTP/1.1 400"));
} }
@ -452,7 +453,7 @@ public class RequestTest
} }
}; };
_connector.getResponses( LocalEndPoint endp = _connector.executeRequest(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"Content-Type: text/test\n"+ "Content-Type: text/test\n"+
@ -475,6 +476,11 @@ public class RequestTest
"\n" "\n"
); );
endp.getResponse();
endp.getResponse();
endp.getResponse();
endp.getResponse();
int i=0; int i=0;
assertEquals("text/test",results.get(i++)); assertEquals("text/test",results.get(i++));
assertEquals(null,results.get(i++)); assertEquals(null,results.get(i++));
@ -507,7 +513,7 @@ public class RequestTest
}; };
results.clear(); results.clear();
String response=_connector.getResponses( String response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: myhost\n"+ "Host: myhost\n"+
"Connection: close\n"+ "Connection: close\n"+
@ -521,7 +527,7 @@ public class RequestTest
results.clear(); results.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: myhost:8888\n"+ "Host: myhost:8888\n"+
"Connection: close\n"+ "Connection: close\n"+
@ -535,7 +541,7 @@ public class RequestTest
results.clear(); results.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET http://myhost:8888/ HTTP/1.0\n"+ "GET http://myhost:8888/ HTTP/1.0\n"+
"\n"); "\n");
i=0; i=0;
@ -546,7 +552,7 @@ public class RequestTest
assertEquals("8888",results.get(i++)); assertEquals("8888",results.get(i++));
results.clear(); results.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET http://myhost:8888/ HTTP/1.1\n"+ "GET http://myhost:8888/ HTTP/1.1\n"+
"Host: wrong:666\n"+ "Host: wrong:666\n"+
"Connection: close\n"+ "Connection: close\n"+
@ -560,7 +566,7 @@ public class RequestTest
results.clear(); results.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: 1.2.3.4\n"+ "Host: 1.2.3.4\n"+
"Connection: close\n"+ "Connection: close\n"+
@ -575,7 +581,7 @@ public class RequestTest
results.clear(); results.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: 1.2.3.4:8888\n"+ "Host: 1.2.3.4:8888\n"+
"Connection: close\n"+ "Connection: close\n"+
@ -589,7 +595,7 @@ public class RequestTest
results.clear(); results.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: [::1]\n"+ "Host: [::1]\n"+
"Connection: close\n"+ "Connection: close\n"+
@ -603,7 +609,7 @@ public class RequestTest
results.clear(); results.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: [::1]:8888\n"+ "Host: [::1]:8888\n"+
"Connection: close\n"+ "Connection: close\n"+
@ -617,7 +623,7 @@ public class RequestTest
results.clear(); results.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: [::1]\n"+ "Host: [::1]\n"+
"x-forwarded-for: remote\n"+ "x-forwarded-for: remote\n"+
@ -633,7 +639,7 @@ public class RequestTest
results.clear(); results.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: [::1]:8888\n"+ "Host: [::1]:8888\n"+
"Connection: close\n"+ "Connection: close\n"+
@ -687,7 +693,7 @@ public class RequestTest
"\r\n"+ "\r\n"+
content; content;
Log.getRootLogger().debug("test l={}",l); Log.getRootLogger().debug("test l={}",l);
String response = _connector.getResponses(request); String response = _connector.getResponse(request);
Log.getRootLogger().debug(response); Log.getRootLogger().debug(response);
assertThat(response, Matchers.containsString(" 200 OK")); assertThat(response, Matchers.containsString(" 200 OK"));
assertEquals(l,length.get()); assertEquals(l,length.get());
@ -717,7 +723,7 @@ public class RequestTest
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"+ "\r\n"+
content; content;
String response = _connector.getResponses(request); String response = _connector.getResponse(request);
assertThat(response,Matchers.containsString(" 200 OK")); assertThat(response,Matchers.containsString(" 200 OK"));
} }
@ -741,7 +747,7 @@ public class RequestTest
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"+ "\r\n"+
content; content;
String response = _connector.getResponses(request); String response = _connector.getResponse(request);
assertThat(response,Matchers.containsString(" 200 OK")); assertThat(response,Matchers.containsString(" 200 OK"));
} }
@ -767,7 +773,7 @@ public class RequestTest
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"+ "\r\n"+
content; content;
String response = _connector.getResponses(request); String response = _connector.getResponse(request);
assertThat(response,Matchers.containsString(" 200 OK")); assertThat(response,Matchers.containsString(" 200 OK"));
} }
@ -795,7 +801,7 @@ public class RequestTest
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"+ "\r\n"+
content; content;
String response = _connector.getResponses(request); String response = _connector.getResponse(request);
assertThat(response,Matchers.containsString(" 200 OK")); assertThat(response,Matchers.containsString(" 200 OK"));
} }
@ -823,7 +829,7 @@ public class RequestTest
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"+ "\r\n"+
content; content;
String response = _connector.getResponses(request); String response = _connector.getResponse(request);
assertThat(response,Matchers.containsString(" 200 OK")); assertThat(response,Matchers.containsString(" 200 OK"));
} }
@ -850,7 +856,7 @@ public class RequestTest
_server.setHandler(handler); _server.setHandler(handler);
_server.start(); _server.start();
String request="GET / HTTP/1.1\r\n"+ String requests="GET / HTTP/1.1\r\n"+
"Host: whatever\r\n"+ "Host: whatever\r\n"+
"Content-Type: text/plane\r\n"+ "Content-Type: text/plane\r\n"+
"Content-Length: "+10+"\r\n"+ "Content-Length: "+10+"\r\n"+
@ -864,12 +870,13 @@ public class RequestTest
"\r\n"+ "\r\n"+
"ABCDEFGHIJ\r\n"; "ABCDEFGHIJ\r\n";
String responses = _connector.getResponses(request); LocalEndPoint endp = _connector.executeRequest(requests);
String response = endp.getResponse()+endp.getResponse();
int index=responses.indexOf("read="+(int)'0'); int index=response.indexOf("read="+(int)'0');
assertTrue(index>0); assertTrue(index>0);
index=responses.indexOf("read="+(int)'A',index+7); index=response.indexOf("read="+(int)'A',index+7);
assertTrue(index>0); assertTrue(index>0);
} }
@ -906,7 +913,7 @@ public class RequestTest
"\r\n"+ "\r\n"+
"param=wrong\r\n"; "param=wrong\r\n";
String responses = _connector.getResponses(request); String responses = _connector.getResponse(request);
assertTrue(responses.indexOf("read='param=wrong' param=right")>0); assertTrue(responses.indexOf("read='param=wrong' param=right")>0);
@ -941,7 +948,7 @@ public class RequestTest
_server.stop(); _server.stop();
_server.setHandler(handler); _server.setHandler(handler);
_server.start(); _server.start();
String response=_connector.getResponses("GET / HTTP/1.1\n"+ String response=_connector.getResponse("GET / HTTP/1.1\n"+
"Host: myhost\n"+ "Host: myhost\n"+
"Connection: close\n"+ "Connection: close\n"+
"\n"); "\n");
@ -971,7 +978,7 @@ public class RequestTest
_server.setHandler(handler); _server.setHandler(handler);
_server.start(); _server.start();
String request="GET / HTTP/1.1\r\n"+ String requests="GET / HTTP/1.1\r\n"+
"Host: whatever\r\n"+ "Host: whatever\r\n"+
"Content-Type: text/plane\r\n"+ "Content-Type: text/plane\r\n"+
"Content-Length: "+10+"\r\n"+ "Content-Length: "+10+"\r\n"+
@ -985,7 +992,8 @@ public class RequestTest
"\r\n"+ "\r\n"+
"ABCDEFGHIJ\r\n"; "ABCDEFGHIJ\r\n";
String responses = _connector.getResponses(request); LocalEndPoint endp = _connector.executeRequest(requests);
String responses = endp.getResponse()+endp.getResponse();
int index=responses.indexOf("read="+(int)'0'); int index=responses.indexOf("read="+(int)'0');
assertTrue(index>0); assertTrue(index>0);
@ -1009,7 +1017,7 @@ public class RequestTest
} }
}; };
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"\n", "\n",
@ -1019,7 +1027,7 @@ public class RequestTest
assertThat(response, Matchers.not(Matchers.containsString("Connection: close"))); assertThat(response, Matchers.not(Matchers.containsString("Connection: close")));
assertThat(response, Matchers.containsString("Hello World")); assertThat(response, Matchers.containsString("Hello World"));
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"Connection: close\n"+ "Connection: close\n"+
@ -1029,7 +1037,7 @@ public class RequestTest
assertThat(response, Matchers.containsString("Connection: close")); assertThat(response, Matchers.containsString("Connection: close"));
assertThat(response, Matchers.containsString("Hello World")); assertThat(response, Matchers.containsString("Hello World"));
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"Connection: Other, close\n"+ "Connection: Other, close\n"+
@ -1040,7 +1048,7 @@ public class RequestTest
assertThat(response, Matchers.containsString("Connection: close")); assertThat(response, Matchers.containsString("Connection: close"));
assertThat(response, Matchers.containsString("Hello World")); assertThat(response, Matchers.containsString("Hello World"));
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.0\n"+ "GET / HTTP/1.0\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"\n" "\n"
@ -1049,7 +1057,7 @@ public class RequestTest
assertThat(response, Matchers.not(Matchers.containsString("Connection: close"))); assertThat(response, Matchers.not(Matchers.containsString("Connection: close")));
assertThat(response, Matchers.containsString("Hello World")); assertThat(response, Matchers.containsString("Hello World"));
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.0\n"+ "GET / HTTP/1.0\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"Connection: Other, close\n"+ "Connection: Other, close\n"+
@ -1058,7 +1066,7 @@ public class RequestTest
assertThat(response, Matchers.containsString("200")); assertThat(response, Matchers.containsString("200"));
assertThat(response, Matchers.containsString("Hello World")); assertThat(response, Matchers.containsString("Hello World"));
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.0\n"+ "GET / HTTP/1.0\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"Connection: Other,,keep-alive\n"+ "Connection: Other,,keep-alive\n"+
@ -1081,7 +1089,7 @@ public class RequestTest
} }
}; };
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"\n", "\n",
@ -1091,7 +1099,7 @@ public class RequestTest
assertThat(response, Matchers.containsString("Connection: TE,Other")); assertThat(response, Matchers.containsString("Connection: TE,Other"));
assertThat(response, Matchers.containsString("Hello World")); assertThat(response, Matchers.containsString("Hello World"));
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"Connection: close\n"+ "Connection: close\n"+
@ -1123,7 +1131,7 @@ public class RequestTest
String response; String response;
cookies.clear(); cookies.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"Connection: close\n"+ "Connection: close\n"+
@ -1134,7 +1142,7 @@ public class RequestTest
cookies.clear(); cookies.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"Cookie: name=quoted=\"\\\"value\\\"\"\n" + "Cookie: name=quoted=\"\\\"value\\\"\"\n" +
@ -1147,7 +1155,7 @@ public class RequestTest
assertEquals("quoted=\"value\"", cookies.get(0).getValue()); assertEquals("quoted=\"value\"", cookies.get(0).getValue());
cookies.clear(); cookies.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET / HTTP/1.1\n"+ "GET / HTTP/1.1\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"Cookie: name=value; other=\"quoted=;value\"\n" + "Cookie: name=value; other=\"quoted=;value\"\n" +
@ -1162,7 +1170,7 @@ public class RequestTest
assertEquals("quoted=;value", cookies.get(1).getValue()); assertEquals("quoted=;value", cookies.get(1).getValue());
cookies.clear(); cookies.clear();
response=_connector.getResponses( LocalEndPoint endp = _connector.executeRequest(
"GET /other HTTP/1.1\n"+ "GET /other HTTP/1.1\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"Other: header\n"+ "Other: header\n"+
@ -1175,8 +1183,11 @@ public class RequestTest
"Connection: close\n"+ "Connection: close\n"+
"\n" "\n"
); );
response = endp.getResponse();
assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK"));
assertThat(response.substring(15), Matchers.containsString("HTTP/1.1 200 OK")); response = endp.getResponse();
assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK"));
assertEquals(4,cookies.size()); assertEquals(4,cookies.size());
assertEquals("name", cookies.get(0).getName()); assertEquals("name", cookies.get(0).getName());
assertEquals("value", cookies.get(0).getValue()); assertEquals("value", cookies.get(0).getValue());
@ -1187,7 +1198,7 @@ public class RequestTest
assertSame(cookies.get(1), cookies.get(3)); assertSame(cookies.get(1), cookies.get(3));
cookies.clear(); cookies.clear();
response=_connector.getResponses( endp = _connector.executeRequest(
"GET /other HTTP/1.1\n"+ "GET /other HTTP/1.1\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"Other: header\n"+ "Other: header\n"+
@ -1200,8 +1211,10 @@ public class RequestTest
"Connection: close\n"+ "Connection: close\n"+
"\n" "\n"
); );
response = endp.getResponse();
assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK"));
response = endp.getResponse();
assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK"));
assertThat(response.substring(15), Matchers.containsString("HTTP/1.1 200 OK"));
assertEquals(4,cookies.size()); assertEquals(4,cookies.size());
assertEquals("name", cookies.get(0).getName()); assertEquals("name", cookies.get(0).getName());
assertEquals("value", cookies.get(0).getValue()); assertEquals("value", cookies.get(0).getValue());
@ -1212,9 +1225,9 @@ public class RequestTest
assertNotSame(cookies.get(1), cookies.get(3)); assertNotSame(cookies.get(1), cookies.get(3));
cookies.clear(); cookies.clear();
//NOTE: the javax.servlet.http.Cookie class sets the system property org.glassfish.web.rfc2109_cookie_names_enforced //NOTE: the javax.servlet.http.Cookie class sets the system property org.glassfish.web.rfc2109_cookie_names_enforced
//to TRUE by default, and rejects all cookie names containing punctuation.Therefore this test cannot use "name2". //to TRUE by default, and rejects all cookie names containing punctuation.Therefore this test cannot use "name2".
response=_connector.getResponses( response=_connector.getResponse(
"POST / HTTP/1.1\r\n"+ "POST / HTTP/1.1\r\n"+
"Host: whatever\r\n"+ "Host: whatever\r\n"+
"Cookie: name0=value0; name1 = value1 ; \"name2\" = \"\\\"value2\\\"\" \n" + "Cookie: name0=value0; name1 = value1 ; \"name2\" = \"\\\"value2\\\"\" \n" +
@ -1245,7 +1258,7 @@ public class RequestTest
assertEquals("value7", cookies.get(7).getValue()); assertEquals("value7", cookies.get(7).getValue());
cookies.clear(); cookies.clear();
response=_connector.getResponses( response=_connector.getResponse(
"GET /other HTTP/1.1\n"+ "GET /other HTTP/1.1\n"+
"Host: whatever\n"+ "Host: whatever\n"+
"Other: header\n"+ "Other: header\n"+
@ -1294,7 +1307,7 @@ public class RequestTest
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"; "\r\n";
_connector.getResponses(request); _connector.getResponse(request);
assertEquals("value",cookie[0]); assertEquals("value",cookie[0]);
assertEquals(null,cookie[1]); assertEquals(null,cookie[1]);
@ -1310,7 +1323,7 @@ public class RequestTest
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"; "\r\n";
_connector.getResponses(request); _connector.getResponse(request);
assertEquals(null,cookie[0]); assertEquals(null,cookie[0]);
assertEquals(null,cookie[1]); assertEquals(null,cookie[1]);
@ -1327,7 +1340,7 @@ public class RequestTest
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"; "\r\n";
_connector.getResponses(request); _connector.getResponse(request);
assertEquals("value",cookie[0]); assertEquals("value",cookie[0]);
assertEquals(null,cookie[1]); assertEquals(null,cookie[1]);
@ -1386,7 +1399,7 @@ public class RequestTest
buf; buf;
long start=System.currentTimeMillis(); long start=System.currentTimeMillis();
String response = _connector.getResponses(request); String response = _connector.getResponse(request);
assertThat(response,Matchers.containsString("IllegalStateException")); assertThat(response,Matchers.containsString("IllegalStateException"));
long now=System.currentTimeMillis(); long now=System.currentTimeMillis();
assertTrue((now-start)<5000); assertTrue((now-start)<5000);
@ -1427,7 +1440,7 @@ public class RequestTest
buf; buf;
long start=System.currentTimeMillis(); long start=System.currentTimeMillis();
String response = _connector.getResponses(request); String response = _connector.getResponse(request);
assertTrue(response.contains("IllegalStateException")); assertTrue(response.contains("IllegalStateException"));
long now=System.currentTimeMillis(); long now=System.currentTimeMillis();
assertTrue((now-start)<5000); assertTrue((now-start)<5000);

View File

@ -0,0 +1,182 @@
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.handler;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeNoException;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystemException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.resource.PathResource;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class AllowSymLinkAliasCheckerTest
{
@Parameterized.Parameters(name = "{0}")
public static List<Object[]> params()
{
List<Object[]> data = new ArrayList<>();
data.add(new Object[]{"/testdir/", 200, "text/html", "Directory: /testdir/"});
data.add(new Object[]{"/testdirlnk/", 200, "text/html", "Directory: /testdirlnk/"});
data.add(new Object[]{"/testdir/testfile.txt", 200, "text/plain", "Hello TestFile"});
data.add(new Object[]{"/testdir/testfilelnk.txt", 200, "text/plain", "Hello TestFile"});
data.add(new Object[]{"/testdirlnk/testfile.txt", 200, "text/plain", "Hello TestFile"});
data.add(new Object[]{"/testdirlnk/testfilelnk.txt", 200, "text/plain", "Hello TestFile"});
return data;
}
private Server server;
private LocalConnector localConnector;
private Path rootPath;
@Before
public void setup() throws Exception
{
setupRoot();
setupServer();
}
@After
public void teardown() throws Exception
{
server.stop();
}
private void setupRoot() throws IOException
{
rootPath = MavenTestingUtils.getTargetTestingPath(AllowSymLinkAliasCheckerTest.class.getSimpleName());
FS.ensureEmpty(rootPath);
Path testdir = rootPath.resolve("testdir");
FS.ensureDirExists(testdir);
try
{
Path testdirlnk = rootPath.resolve("testdirlnk");
// Create a relative symlink testdirlnk -> testdir.
// If we used testdir (Path) from above, this symlink
// would point to an absolute path.
Files.createSymbolicLink(testdirlnk, new File("testdir").toPath());
}
catch (UnsupportedOperationException | FileSystemException e)
{
// If unable to create symlink, no point testing the rest.
// This is the path that Microsoft Windows takes.
assumeNoException(e);
}
Path testfileTxt = testdir.resolve("testfile.txt");
Files.createFile(testfileTxt);
try (OutputStream out = Files.newOutputStream(testfileTxt))
{
out.write("Hello TestFile".getBytes(StandardCharsets.UTF_8));
}
try
{
Path testfileTxtLnk = testdir.resolve("testfilelnk.txt");
// Create a relative symlink testfilelnk.txt -> testfile.txt.
// If we used testfileTxt (Path) from above, this symlink
// would point to an absolute path.
Files.createSymbolicLink(testfileTxtLnk, new File("testfile.txt").toPath());
}
catch (UnsupportedOperationException | FileSystemException e)
{
// If unable to create symlink, no point testing the rest.
// This is the path that Microsoft Windows takes.
assumeNoException(e);
}
}
private void setupServer() throws Exception
{
// Setup server
server = new Server();
localConnector = new LocalConnector(server);
server.addConnector(localConnector);
ResourceHandler fileResourceHandler = new ResourceHandler();
fileResourceHandler.setDirectoriesListed(true);
fileResourceHandler.setWelcomeFiles(new String[]{"index.html"});
fileResourceHandler.setEtags(true);
ContextHandler fileResourceContext = new ContextHandler();
fileResourceContext.setContextPath("/");
fileResourceContext.setAllowNullPathInfo(true);
fileResourceContext.setHandler(fileResourceHandler);
fileResourceContext.setBaseResource(new PathResource(rootPath));
fileResourceContext.clearAliasChecks();
fileResourceContext.addAliasCheck(new AllowSymLinkAliasChecker());
server.setHandler(fileResourceContext);
server.start();
}
@Parameterized.Parameter(0)
public String requestURI;
@Parameterized.Parameter(1)
public int expectedResponseStatus;
@Parameterized.Parameter(2)
public String expectedResponseContentType;
@Parameterized.Parameter(3)
public String expectedResponseContentContains;
public AllowSymLinkAliasCheckerTest()
{
}
@Test(timeout = 5000)
public void testAccess() throws Exception
{
HttpTester.Request request = HttpTester.newRequest();
request.setMethod("GET");
request.setHeader("Host", "tester");
request.setURI(requestURI);
String responseString = localConnector.getResponse(BufferUtil.toString(request.generate()));
assertThat("Response status code", responseString, startsWith("HTTP/1.1 " + expectedResponseStatus + " "));
assertThat("Response Content-Type", responseString, containsString("\nContent-Type: " + expectedResponseContentType));
assertThat("Response", responseString, containsString(expectedResponseContentContains));
}
}

View File

@ -222,7 +222,7 @@ public class ContextHandlerCollectionTest
{ {
// System.err.printf("host=%s in %s%n",host,contextHosts==null?Collections.emptyList():Arrays.asList(contextHosts)); // System.err.printf("host=%s in %s%n",host,contextHosts==null?Collections.emptyList():Arrays.asList(contextHosts));
String response=connector.getResponses("GET / HTTP/1.0\n" + "Host: "+host+"\nConnection:close\n\n"); String response=connector.getResponse("GET / HTTP/1.0\n" + "Host: "+host+"\nConnection:close\n\n");
// System.err.println(response); // System.err.println(response);
if(succeed) if(succeed)
assertTrue("'"+host+"' should have been handled.",handler.isHandled()); assertTrue("'"+host+"' should have been handled.",handler.isHandled());

View File

@ -497,7 +497,7 @@ public class ContextHandlerTest
IsHandledHandler handler = (IsHandledHandler)context.getHandler(); IsHandledHandler handler = (IsHandledHandler)context.getHandler();
for(String host : requestHosts) for(String host : requestHosts)
{ {
connector.getResponses("GET / HTTP/1.1\n" + "Host: "+host+"\nConnection:close\n\n"); connector.getResponse("GET / HTTP/1.1\n" + "Host: "+host+"\nConnection:close\n\n");
if(succeed) if(succeed)
Assert.assertTrue("'" + host + "' should have been handled.", handler.isHandled()); Assert.assertTrue("'" + host + "' should have been handled.", handler.isHandled());
else else

View File

@ -69,7 +69,7 @@ public class AsyncListenerTest
public void test_StartAsync_Throw_OnError_Dispatch() throws Exception public void test_StartAsync_Throw_OnError_Dispatch() throws Exception
{ {
test_StartAsync_Throw_OnError(event -> event.getAsyncContext().dispatch("/dispatch")); test_StartAsync_Throw_OnError(event -> event.getAsyncContext().dispatch("/dispatch"));
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET /ctx/path HTTP/1.1\r\n" + "GET /ctx/path HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +
@ -91,7 +91,7 @@ public class AsyncListenerTest
output.println("COMPLETE"); output.println("COMPLETE");
event.getAsyncContext().complete(); event.getAsyncContext().complete();
}); });
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET /ctx/path HTTP/1.1\r\n" + "GET /ctx/path HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +
@ -108,7 +108,7 @@ public class AsyncListenerTest
{ {
throw new IOException(); throw new IOException();
}); });
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET /ctx/path HTTP/1.1\r\n" + "GET /ctx/path HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +
@ -121,7 +121,7 @@ public class AsyncListenerTest
public void test_StartAsync_Throw_OnError_Nothing() throws Exception public void test_StartAsync_Throw_OnError_Nothing() throws Exception
{ {
test_StartAsync_Throw_OnError(event -> {}); test_StartAsync_Throw_OnError(event -> {});
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET /ctx/path HTTP/1.1\r\n" + "GET /ctx/path HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +
@ -138,7 +138,7 @@ public class AsyncListenerTest
HttpServletResponse response = (HttpServletResponse)event.getAsyncContext().getResponse(); HttpServletResponse response = (HttpServletResponse)event.getAsyncContext().getResponse();
response.sendError(HttpStatus.BAD_GATEWAY_502); response.sendError(HttpStatus.BAD_GATEWAY_502);
}); });
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET /ctx/path HTTP/1.1\r\n" + "GET /ctx/path HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +
@ -169,7 +169,7 @@ public class AsyncListenerTest
}; };
server.setErrorHandler(errorHandler); server.setErrorHandler(errorHandler);
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET /ctx/path HTTP/1.1\r\n" + "GET /ctx/path HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +
@ -224,7 +224,7 @@ public class AsyncListenerTest
public void test_StartAsync_OnTimeout_Dispatch() throws Exception public void test_StartAsync_OnTimeout_Dispatch() throws Exception
{ {
test_StartAsync_OnTimeout(500, event -> event.getAsyncContext().dispatch("/dispatch")); test_StartAsync_OnTimeout(500, event -> event.getAsyncContext().dispatch("/dispatch"));
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET / HTTP/1.1\r\n" + "GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +
@ -244,7 +244,7 @@ public class AsyncListenerTest
event.getAsyncContext().complete(); event.getAsyncContext().complete();
}); });
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET / HTTP/1.1\r\n" + "GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +
@ -260,7 +260,7 @@ public class AsyncListenerTest
{ {
throw new TestRuntimeException(); throw new TestRuntimeException();
}); });
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET / HTTP/1.1\r\n" + "GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +
@ -274,7 +274,7 @@ public class AsyncListenerTest
{ {
test_StartAsync_OnTimeout(500, event -> { test_StartAsync_OnTimeout(500, event -> {
}); });
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET / HTTP/1.1\r\n" + "GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +
@ -290,7 +290,7 @@ public class AsyncListenerTest
HttpServletResponse response = (HttpServletResponse)event.getAsyncContext().getResponse(); HttpServletResponse response = (HttpServletResponse)event.getAsyncContext().getResponse();
response.sendError(HttpStatus.BAD_GATEWAY_502); response.sendError(HttpStatus.BAD_GATEWAY_502);
}); });
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET / HTTP/1.1\r\n" + "GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +
@ -323,7 +323,7 @@ public class AsyncListenerTest
errorHandler.setServer(server); errorHandler.setServer(server);
server.setErrorHandler(errorHandler); server.setErrorHandler(errorHandler);
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET / HTTP/1.1\r\n" + "GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +
@ -398,7 +398,7 @@ public class AsyncListenerTest
startServer(context); startServer(context);
String httpResponse = connector.getResponses("" + String httpResponse = connector.getResponse("" +
"GET / HTTP/1.1\r\n" + "GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" + "Host: localhost\r\n" +
"Connection: close\r\n" + "Connection: close\r\n" +

View File

@ -196,7 +196,7 @@ public class ServletTester extends ContainerLifeCycle
{ {
LOG.debug("Request: {}",request); LOG.debug("Request: {}",request);
} }
return _connector.getResponses(request); return _connector.getResponse(request);
} }
public String getResponses(String request, long idleFor,TimeUnit units) throws Exception public String getResponses(String request, long idleFor,TimeUnit units) throws Exception
@ -205,7 +205,7 @@ public class ServletTester extends ContainerLifeCycle
{ {
LOG.debug("Request: {}",request); LOG.debug("Request: {}",request);
} }
return _connector.getResponses(request, idleFor, units); return _connector.getResponse(request, idleFor, units);
} }
public ByteBuffer getResponses(ByteBuffer request) throws Exception public ByteBuffer getResponses(ByteBuffer request) throws Exception
@ -214,7 +214,7 @@ public class ServletTester extends ContainerLifeCycle
{ {
LOG.debug("Request (Buffer): {}",BufferUtil.toUTF8String(request)); LOG.debug("Request (Buffer): {}",BufferUtil.toUTF8String(request));
} }
return _connector.getResponses(request); return _connector.getResponse(request);
} }
public ByteBuffer getResponses(ByteBuffer requestsBuffer,long idleFor,TimeUnit units) throws Exception public ByteBuffer getResponses(ByteBuffer requestsBuffer,long idleFor,TimeUnit units) throws Exception
@ -223,7 +223,7 @@ public class ServletTester extends ContainerLifeCycle
{ {
LOG.debug("Requests (Buffer): {}",BufferUtil.toUTF8String(requestsBuffer)); LOG.debug("Requests (Buffer): {}",BufferUtil.toUTF8String(requestsBuffer));
} }
return _connector.getResponses(requestsBuffer, idleFor, units); return _connector.getResponse(requestsBuffer, idleFor, units);
} }
/** Create a port based connector. /** Create a port based connector.

View File

@ -48,7 +48,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.ChannelEndPoint; import org.eclipse.jetty.io.ChannelEndPoint;
import org.eclipse.jetty.io.ManagedSelector; import org.eclipse.jetty.io.ManagedSelector;
import org.eclipse.jetty.io.SelectChannelEndPoint; import org.eclipse.jetty.io.SocketChannelEndPoint;
import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
@ -109,7 +109,7 @@ public class ThreadStarvationTest
@Override @Override
protected ChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException protected ChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException
{ {
return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout()) return new SocketChannelEndPoint(channel, selectSet, key, getScheduler())
{ {
@Override @Override
protected void onIncompleteFlush() protected void onIncompleteFlush()
@ -247,7 +247,7 @@ public class ThreadStarvationTest
int acceptors = 0; int acceptors = 0;
int selectors = 1; int selectors = 1;
int maxThreads = 10; int maxThreads = 10;
final int barried=maxThreads-acceptors-selectors; final int barried=maxThreads-acceptors-selectors*2;
final CyclicBarrier barrier = new CyclicBarrier(barried); final CyclicBarrier barrier = new CyclicBarrier(barried);
@ -261,16 +261,14 @@ public class ThreadStarvationTest
@Override @Override
protected ChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException protected ChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException
{ {
return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout()) return new SocketChannelEndPoint(channel, selectSet, key, getScheduler())
{ {
@Override @Override
public boolean flush(ByteBuffer... buffers) throws IOException public boolean flush(ByteBuffer... buffers) throws IOException
{ {
super.flush(buffers[0]); super.flush(buffers[0]);
throw new IOException("TEST FAILURE"); throw new IOException("TEST FAILURE");
} }
}; };
} }
}; };
@ -320,7 +318,6 @@ public class ThreadStarvationTest
output.flush(); output.flush();
} }
byte[] buffer = new byte[48 * 1024]; byte[] buffer = new byte[48 * 1024];
List<Exchanger<Integer>> totals = new ArrayList<>(); List<Exchanger<Integer>> totals = new ArrayList<>();
for (Socket socket : sockets) for (Socket socket : sockets)