* FYI: Rewrite some HttpURLConnection tests.
@ 2006-08-11 20:05 David Daney
0 siblings, 0 replies; only message in thread
From: David Daney @ 2006-08-11 20:05 UTC (permalink / raw)
To: Mauve Patch List
[-- Attachment #1: Type: text/plain, Size: 820 bytes --]
I just committed this change to the TestHttpServer to make it a bit more
flexable. The two tests that use it were changed so that they work with
the changed version. All this in preperation for a new test to be
committed real soon now.
2006-08-11 David Daney <ddaney@avtrex.com>
* gnu/testlet/java/net/HttpURLConnection/TestHttpServer.java: Rewrote.
* gnu/testlet/java/net/HttpURLConnection/responseCodeTest.java (test):
Rewrote to use new TestHttpServer.
(Factory): New inner class.
(Handler): New inner class.
(test_ResponseCode): Use new server.
* gnu/testlet/java/net/HttpURLConnection/responseHeadersTest.java
(test): Rewrote to use new TestHttpServer.
(Factory): New inner class.
(Handler): New inner class.
(test_MultiHeaders): Use new server.
(test_LowerUpperCaseHeaders): Use new server.
[-- Attachment #2: mauve.d --]
[-- Type: text/plain, Size: 20835 bytes --]
Index: gnu/testlet/java/net/HttpURLConnection/TestHttpServer.java
===================================================================
RCS file: /cvs/mauve/mauve/gnu/testlet/java/net/HttpURLConnection/TestHttpServer.java,v
retrieving revision 1.1
diff -u -p -r1.1 TestHttpServer.java
--- gnu/testlet/java/net/HttpURLConnection/TestHttpServer.java 6 Mar 2006 18:48:44 -0000 1.1
+++ gnu/testlet/java/net/HttpURLConnection/TestHttpServer.java 11 Aug 2006 19:40:20 -0000
@@ -22,7 +22,6 @@
package gnu.testlet.java.net.HttpURLConnection;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -30,6 +29,8 @@ import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
@@ -46,108 +47,95 @@ import java.util.List;
*/
public final class TestHttpServer implements Runnable
{
- /**
- * The interface to be implemented if checking
- * of the serverside received headers and body
- * is desired.
- */
- interface CheckReceivedRequest
+
+ public interface ConnectionHandlerFactory
{
- /**
- * Will be called with a List of headers in
- * the sequence received by the test server.
- *
- * @param headers List of headers
- */
- public void checkHeaders(List headers);
-
- /**
- * Will be called with the body if one was
- * received.
- *
- * @param body the body
- */
- public void checkBody(byte[] body);
+ ConnectionHandler newConnectionHandler(Socket s) throws IOException;
}
/**
- * The actual request handler.
- * It always returns what is set in the TestHttpServer
- * for the response headers and response body.
+ * The request handler skeleton.
*/
- class TestHttpRequestHandler implements Runnable
+ public static abstract class ConnectionHandler implements Runnable
{
- Socket socket;
- OutputStream output;
- InputStream input;
-
- public TestHttpRequestHandler(Socket socket) throws Exception
+ protected Socket socket;
+ protected OutputStream output;
+ protected InputStream input;
+
+ ConnectionHandler(Socket socket) throws IOException
{
this.socket = socket;
output = socket.getOutputStream();
input = socket.getInputStream();
}
-
+
+ /**
+ * Process one request on the connection.
+ *
+ * @param headers
+ * @param body
+ * @return true if another request should be read from the connection.
+ * @throws IOException
+ */
+ protected abstract boolean processConnection(List headers, byte[] body)
+ throws IOException;
+
public void run()
{
try
{
- // Read the whole request into a byte array
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-
- byte[] b = new byte[1024];
- int bytes = 0 ;
- while ((bytes = input.read(b)) != -1)
- {
- buffer.write(b, 0, bytes);
- if (bytes < 1024)
- break;
- }
-
- byte[] request = buffer.toByteArray();
-
- // Parse the request headers from the byte array
- List headerList = new ArrayList();
-
- ByteArrayOutputStream line;
- int i = 0;
- line = new ByteArrayOutputStream();
- for (; i < request.length; i++)
+ List headerList;
+ int contentLength = -1;
+ byte[] body;
+ do
{
- if (request[i] != (byte) 0x0a) // LF
- line.write(request[i]);
- else
+ headerList = new ArrayList();
+
+ ByteArrayOutputStream line;
+ line = new ByteArrayOutputStream();
+ for (;;)
{
- byte[] array = line.toByteArray();
- if (array.length == 1) // the last is only a LF
- break;
-
- String headerLine = new String(array);
- headerList.add(headerLine);
- line = new ByteArrayOutputStream();
+ int ch = input.read();
+ if (-1 == ch)
+ break; // EOF
+
+ if (ch != 0x0a) // LF
+ line.write(ch);
+ else
+ {
+ byte[] array = line.toByteArray();
+ if (array.length == 1) // the last is only a LF
+ break;
+
+ String headerLine = new String(array);
+ if (headerLine.length() > 15 &&
+ "Content-Length:".equalsIgnoreCase(headerLine.substring(0,15)))
+ {
+ contentLength = Integer.parseInt(headerLine.substring(15).trim());
+ }
+ headerList.add(headerLine);
+ line = new ByteArrayOutputStream();
+ }
}
- }
- // Put the remaining bytes into the request body
- byte[] body = new byte[(request.length - (i + 1))];
- System.arraycopy(request, i + 1, body, 0, body.length);
-
- // Check everything
- if (check != null)
- {
- check.checkHeaders(headerList);
- if (body.length > 0)
- check.checkBody(body);
- }
-
- // Response writing
- // write the response headers
- output.write(responseHeader);
-
- // write the body
- if (responseBody != null)
- output.write(responseBody);
-
+ if (contentLength > 0)
+ {
+ body = new byte[contentLength];
+ int pos = 0;
+ while (pos < contentLength)
+ {
+ int nr = input.read(body, pos, body.length - pos);
+ if (-1 == nr)
+ break;
+ pos += nr;
+ }
+ }
+ else
+ body = null;
+ contentLength = -1;
+ // Check everything
+ } while (processConnection(headerList, body));
+
// Clean up
output.close();
input.close();
@@ -158,52 +146,46 @@ public final class TestHttpServer implem
// ignore
}
}
+
+ protected void forceClosed()
+ {
+ try
+ {
+ socket.close();
+ }
+ catch (IOException ioe)
+ {
+ // Ignore.
+ }
+ }
}
- int port;
- byte[] responseHeader;
- byte[] responseBody;
- CheckReceivedRequest check;
boolean kill = false;
ServerSocket serverSocket;
-
- /**
- * Create a TestHttpServer on given port
- * @param port the port to use.
- */
- public TestHttpServer(int port)
- {
- this.port = port;
- }
+ ConnectionHandlerFactory connectionHandlerFactory;
/**
- * An object implementing the CheckReceivedRequest
- * interface. The methods will be called to enable
- * checks of the serverside received request.
- *
- * @param responseBody the byte[] of the body
+ * Create a TestHttpServer on an unused port.
*/
- public void setCheckReceivedRequest(CheckReceivedRequest object)
+ public TestHttpServer() throws IOException
{
- this.check = object;
+ serverSocket = new ServerSocket(0);
+ Thread t = new Thread(this, "TestHttpServer");
+ t.start();
}
/**
- * The bytes which should be sent as the response body.
- * @param responseBody the byte[] of the body
+ * The local port on which the test server is listening for connections.
+ * @return the port
*/
- public void setResponseBody(byte[] responseBody)
+ public int getPort()
{
- this.responseBody = responseBody;
+ return serverSocket.getLocalPort();
}
- /**
- * The bytes which should be sent as the response headers.
- * @param responseHeaders the byte[] of the headers
- */
- public void setResponseHeaders(byte[] responseHeaders)
+ public synchronized void setConnectionHandlerFactory(ConnectionHandlerFactory f)
{
- this.responseHeader = responseHeaders;
+ connectionHandlerFactory = f;
}
/**
@@ -213,6 +195,7 @@ public final class TestHttpServer implem
public void killTestServer()
{
kill = true;
+ closeAllConnections();
try
{
serverSocket.close();
@@ -223,6 +206,8 @@ public final class TestHttpServer implem
}
}
+ private List activeConnections = new LinkedList();
+
/**
* Listens on the port and creates a Handler for
* incoming connections.
@@ -231,17 +216,23 @@ public final class TestHttpServer implem
{
try
{
- serverSocket = new ServerSocket(port);
while (! kill)
{
Socket socket = serverSocket.accept();
try
{
- TestHttpRequestHandler request =
- new TestHttpRequestHandler(socket);
+ ConnectionHandlerFactory f;
+ synchronized(this)
+ {
+ f = connectionHandlerFactory;
+ }
+ ConnectionHandler request = f.newConnectionHandler(socket);
Thread thread = new Thread(request);
-
thread.start();
+ synchronized(activeConnections)
+ {
+ activeConnections.add(request);
+ }
}
catch (Exception e)
{
@@ -254,4 +245,18 @@ public final class TestHttpServer implem
// ignore
}
}
+
+ public void closeAllConnections()
+ {
+ synchronized (activeConnections)
+ {
+ Iterator it = activeConnections.iterator();
+ while (it.hasNext())
+ {
+ ConnectionHandler request = (ConnectionHandler)it.next();
+ request.forceClosed();
+ it.remove();
+ }
+ }
+ }
}
Index: gnu/testlet/java/net/HttpURLConnection/responseCodeTest.java
===================================================================
RCS file: /cvs/mauve/mauve/gnu/testlet/java/net/HttpURLConnection/responseCodeTest.java,v
retrieving revision 1.1
diff -u -p -r1.1 responseCodeTest.java
--- gnu/testlet/java/net/HttpURLConnection/responseCodeTest.java 6 Mar 2006 18:48:44 -0000 1.1
+++ gnu/testlet/java/net/HttpURLConnection/responseCodeTest.java 11 Aug 2006 19:40:20 -0000
@@ -25,12 +25,16 @@ package gnu.testlet.java.net.HttpURLConn
import gnu.testlet.TestHarness;
import gnu.testlet.Testlet;
-import java.io.ByteArrayOutputStream;
+
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
import java.net.HttpURLConnection;
+import java.net.Socket;
import java.net.URL;
+import java.util.List;
/**
* Tests correct behaviour of getInputStream(), getErrorStream()
@@ -39,7 +43,7 @@ import java.net.URL;
public class responseCodeTest implements Testlet
{
/**
- * Starts an HTTP server on port 8080 and calls
+ * Starts an HTTP server and calls
* the test_ResponseCode for the error codes.
*/
public void test(TestHarness h)
@@ -47,18 +51,17 @@ public class responseCodeTest implements
TestHttpServer server = null;
try
{
- server = new TestHttpServer(8080);
- Thread thread = new Thread(server);
- thread.start();
- try
- {
-// SUN JDK needs some time to open sockets
- Thread.sleep(100);
- }
- catch (InterruptedException e1)
- {
- }
-
+ try
+ {
+ server = new TestHttpServer();
+ }
+ catch (IOException ioe)
+ {
+ h.debug(ioe);
+ h.fail("Could not start server");
+ return;
+ }
+
for (int i=400; i < 418; i++)
test_ResponseCode(i, h, server);
@@ -67,30 +70,60 @@ public class responseCodeTest implements
}
finally
{
- server.killTestServer();
- }
+ if (server != null)
+ server.killTestServer();
+ }
+ }
+
+ static class Factory implements TestHttpServer.ConnectionHandlerFactory
+ {
+ private int responseCode;
+ Factory(int responseCode)
+ {
+ this.responseCode = responseCode;
+ }
+
+ public TestHttpServer.ConnectionHandler newConnectionHandler(Socket s)
+ throws IOException
+ {
+ return new Handler(s, responseCode);
+ }
+ }
+
+ static class Handler extends TestHttpServer.ConnectionHandler
+ {
+ private int responseCode;
+ private Writer sink;
+
+ Handler(Socket socket, int responseCode) throws IOException
+ {
+ super(socket);
+ this.responseCode = responseCode;
+ sink = new OutputStreamWriter(output,"US-ASCII");
+ }
+
+ protected boolean processConnection(List headers, byte[] body)
+ throws IOException
+ {
+ sink.write("HTTP/1.0 " + responseCode + " OK\r\n");
+ sink.write("Server: TestServer\r\n\r\n");
+ sink.close();
+ return false;
+ }
}
public void test_ResponseCode(int responseCode,
TestHarness h, TestHttpServer server)
{
try
- {
- URL url = new URL("http://localhost:8080/");
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ {
+ server.setConnectionHandlerFactory(new Factory(responseCode));
+ URL url = new URL("http://localhost:" + server.getPort() + "/");
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
h.checkPoint("Test " + responseCode + " response");
- // construct what should be returned by the test server as headers
- ByteArrayOutputStream headers = new ByteArrayOutputStream();
-
- // status line (the responsecode encoded for the test)
- headers.write(new String("HTTP/1.0 " + responseCode + " OK\r\n").getBytes());
- headers.write("Server: TestServer\r\n\r\n".getBytes());
-
- server.setResponseHeaders(headers.toByteArray());
-
// test the responsecode
int code = conn.getResponseCode();
h.check(code == responseCode);
Index: gnu/testlet/java/net/HttpURLConnection/responseHeadersTest.java
===================================================================
RCS file: /cvs/mauve/mauve/gnu/testlet/java/net/HttpURLConnection/responseHeadersTest.java,v
retrieving revision 1.1
diff -u -p -r1.1 responseHeadersTest.java
--- gnu/testlet/java/net/HttpURLConnection/responseHeadersTest.java 6 Mar 2006 18:48:44 -0000 1.1
+++ gnu/testlet/java/net/HttpURLConnection/responseHeadersTest.java 11 Aug 2006 19:40:20 -0000
@@ -26,65 +26,100 @@ package gnu.testlet.java.net.HttpURLConn
import gnu.testlet.TestHarness;
import gnu.testlet.Testlet;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
import java.net.HttpURLConnection;
+import java.net.Socket;
import java.net.URL;
import java.util.List;
import java.util.Map;
public class responseHeadersTest implements Testlet
{
-
public void test(TestHarness harness)
{
TestHttpServer server = null;
try
{
- server = new TestHttpServer(8080);
- Thread thread = new Thread(server);
- thread.start();
- try
- {
- // SUN JDK needs some time to open sockets
- Thread.sleep(100);
- }
- catch (InterruptedException e1)
- {
- }
-
+ try
+ {
+ server = new TestHttpServer();
+ }
+ catch (IOException ioe)
+ {
+ harness.debug(ioe);
+ harness.fail("Could not start server");
+ return;
+ }
test_MultiHeaders(harness, server);
test_LowerUpperCaseHeaders(harness, server);
}
finally
{
server.killTestServer();
- }
+ }
}
-
+
+ static class Factory implements TestHttpServer.ConnectionHandlerFactory
+ {
+ private String headers;
+ Factory(String headers)
+ {
+ this.headers = headers;
+ }
+
+ public TestHttpServer.ConnectionHandler newConnectionHandler(Socket s)
+ throws IOException
+ {
+ return new Handler(s, headers);
+ }
+ }
+
+ static class Handler extends TestHttpServer.ConnectionHandler
+ {
+ private String responseHeaders;
+ private Writer sink;
+
+ Handler(Socket socket, String headers) throws IOException
+ {
+ super(socket);
+ this.responseHeaders = headers;
+ sink = new OutputStreamWriter(output,"US-ASCII");
+ }
+
+ protected boolean processConnection(List headers, byte[] body)
+ throws IOException
+ {
+ sink.write(responseHeaders);
+ sink.close();
+ return false;
+ }
+ }
+
public void test_MultiHeaders(TestHarness h, TestHttpServer server)
{
try
- {
- URL url = new URL("http://localhost:8080/");
+ {
+ Factory f = new Factory(
+ "HTTP/1.0 200 OK\r\n" +
+ "Server: TestServer\r\n" +
+ "Key1: value, value2\r\n" +
+ // set the header a second time with different values
+ // these values must be prepended to key1
+ "Key1: value3\r\n" +
+ "IntHeader: 1234\r\n" +
+ "IntHeaderMalformed: 1234XY\r\n" +
+ "DateHeader: Thu, 02 Mar 2006 14:34:55 +0000\r\n" +
+ "DateHeaderMalformed: Thu, 02 Mar 2006V 14:13:07 +0000\r\n\r\n"
+ );
+
+ server.setConnectionHandlerFactory(f);
+
+ URL url = new URL("http://localhost:" + server.getPort() + "/");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
- // construct what should be returned by the test server as headers
- ByteArrayOutputStream headers = new ByteArrayOutputStream();
- headers.write("HTTP/1.0 200 OK\r\n".getBytes());
- headers.write("Server: TestServer\r\n".getBytes());
- headers.write("Key1: value, value2\r\n".getBytes());
- // set the header a second time with different values
- // these values must be prepended to key1
- headers.write("Key1: value3\r\n".getBytes());
- headers.write("IntHeader: 1234\r\n".getBytes());
- headers.write("IntHeaderMalformed: 1234XY\r\n".getBytes());
- headers.write("DateHeader: Thu, 02 Mar 2006 14:34:55 +0000\r\n".getBytes());
- headers.write("DateHeaderMalformed: Thu, 02 Mar 2006V 14:13:07 +0000\r\n\r\n".getBytes());
-
- server.setResponseHeaders(headers.toByteArray());
-
h.checkPoint("getHeaderFields()");
Map fields = conn.getHeaderFields();
@@ -226,23 +261,22 @@ public class responseHeadersTest impleme
public void test_LowerUpperCaseHeaders(TestHarness h, TestHttpServer server)
{
try
- {
- URL url = new URL("http://localhost:8080/");
+ {
+ Factory f = new Factory(
+ "HTTP/1.0 200 OK\r\n" +
+ "Server: TestServer\r\n" +
+ "AnotherKey: value\r\n" +
+ "Key: value\r\n" +
+ "Key: value1\r\n" +
+ "key: value2\r\n" +
+ "key: value3\r\n\r\n"
+ );
+ server.setConnectionHandlerFactory(f);
+
+ URL url = new URL("http://localhost:" + server.getPort() + "/");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
- // construct what should be returned by the test server as headers
- ByteArrayOutputStream headers = new ByteArrayOutputStream();
- headers.write("HTTP/1.0 200 OK\r\n".getBytes());
- headers.write("Server: TestServer\r\n".getBytes());
- headers.write("AnotherKey: value\r\n".getBytes());
- headers.write("Key: value\r\n".getBytes());
- headers.write("Key: value1\r\n".getBytes());
- headers.write("key: value2\r\n".getBytes());
- headers.write("key: value3\r\n\r\n".getBytes());
-
- server.setResponseHeaders(headers.toByteArray());
-
h.checkPoint("LowerUpperCase header fields tests");
Map fields = conn.getHeaderFields();
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2006-08-11 20:05 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-08-11 20:05 FYI: Rewrite some HttpURLConnection tests David Daney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).