Author: rjung
Date: Sun Dec 14 18:32:42 2014
New Revision: 1645488
URL: http://svn.apache.org/r1645488
Log:
Add more thorough tests for AJP.
Unfortunately request attributes as sent
by mod_jk JkEnvVars can not be tested,
because request.getAttributeNames() does
not return the names of Coyote request
attributes. Only getAttribute(String)
checks Coyote request attributes.
Modified:
tomcat/trunk/test/org/apache/coyote/ajp/SimpleAjpClient.java
tomcat/trunk/test/org/apache/coyote/ajp/TestAbstractAjpProcessor.java
tomcat/trunk/test/org/apache/coyote/ajp/TesterAjpMessage.java
Modified: tomcat/trunk/test/org/apache/coyote/ajp/SimpleAjpClient.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/ajp/SimpleAjpClient.java?rev=1645488&r1=1645487&r2=1645488&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/ajp/SimpleAjpClient.java (original)
+++ tomcat/trunk/test/org/apache/coyote/ajp/SimpleAjpClient.java Sun Dec 14
18:32:42 2014
@@ -44,6 +44,15 @@ public class SimpleAjpClient {
private String host = "localhost";
private int port = -1;
+ /* GET == 2 */
+ private int method = 2;
+ private String protocol = "http";
+ private String uri = "/";
+ private String remoteAddr = "192.168.0.1";
+ private String remoteHost = "client.example.com";
+ private String serverName = "www.example.com";
+ private int serverPort = 80;
+ private boolean ssl = false;
private Socket socket = null;
public void setPort(int port) {
@@ -54,6 +63,212 @@ public class SimpleAjpClient {
return port;
}
+ public void setMethod(String method) {
+ method = method.toUpperCase();
+ switch (method) {
+ case "OPTIONS":
+ this.method = 1;
+ break;
+ case "GET":
+ this.method = 2;
+ break;
+ case "HEAD":
+ this.method = 3;
+ break;
+ case "POST":
+ this.method = 4;
+ break;
+ case "PUT":
+ this.method = 5;
+ break;
+ case "DELETE":
+ this.method = 6;
+ break;
+ case "TRACE":
+ this.method = 7;
+ break;
+ case "PROPFIND":
+ this.method = 8;
+ break;
+ case "PROPPATCH":
+ this.method = 9;
+ break;
+ case "MKCOL":
+ this.method = 10;
+ break;
+ case "COPY":
+ this.method = 11;
+ break;
+ case "MOVE":
+ this.method = 12;
+ break;
+ case "LOCK":
+ this.method = 13;
+ break;
+ case "UNLOCK":
+ this.method = 14;
+ break;
+ case "ACL":
+ this.method = 15;
+ break;
+ case "REPORT":
+ this.method = 16;
+ break;
+ case "VERSION-CONTROL":
+ this.method = 17;
+ break;
+ case "CHECKIN":
+ this.method = 18;
+ break;
+ case "CHECKOUT":
+ this.method = 19;
+ break;
+ case "UNCHECKOUT":
+ this.method = 20;
+ break;
+ case "SEARCH":
+ this.method = 21;
+ break;
+ case "MKWORKSPACE":
+ this.method = 22;
+ break;
+ case "UPDATE":
+ this.method = 23;
+ break;
+ case "LABEL":
+ this.method = 24;
+ break;
+ case "MERGE":
+ this.method = 25;
+ break;
+ case "BASELINE-CONTROL":
+ this.method = 26;
+ break;
+ case "MKACTIVITY":
+ this.method = 27;
+ break;
+ default:
+ this.method = 99;
+ }
+ }
+
+ public String getMethod() {
+ switch (method) {
+ case 1:
+ return "OPTIONS";
+ case 2:
+ return "GET";
+ case 3:
+ return "HEAD";
+ case 4:
+ return "POST";
+ case 5:
+ return "PUT";
+ case 6:
+ return "DELETE";
+ case 7:
+ return "TRACE";
+ case 8:
+ return "PROPFIND";
+ case 9:
+ return "PROPPATCH";
+ case 10:
+ return "MKCOL";
+ case 11:
+ return "COPY";
+ case 12:
+ return "MOVE";
+ case 13:
+ return "LOCK";
+ case 14:
+ return "UNLOCK";
+ case 15:
+ return "ACL";
+ case 16:
+ return "REPORT";
+ case 17:
+ return "VERSION-CONTROL";
+ case 18:
+ return "CHECKIN";
+ case 19:
+ return "CHECKOUT";
+ case 20:
+ return "UNCHECKOUT";
+ case 21:
+ return "SEARCH";
+ case 22:
+ return "MKWORKSPACE";
+ case 23:
+ return "UPDATE";
+ case 24:
+ return "LABEL";
+ case 25:
+ return "MERGE";
+ case 26:
+ return "BASELINE-CONTROL";
+ case 27:
+ return "MKACTIVITY";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+
+ public void setRemoteAddr(String remoteAddr) {
+ this.remoteAddr = remoteAddr;
+ }
+
+ public String getRemoteAddr() {
+ return remoteAddr;
+ }
+
+ public void setRemoteHost(String remoteHost) {
+ this.remoteHost = remoteHost;
+ }
+
+ public String getRemoteHost() {
+ return remoteHost;
+ }
+
+ public void setServerName(String serverName) {
+ this.serverName = serverName;
+ }
+
+ public String getServerName() {
+ return serverName;
+ }
+
+ public void setServerPort(int serverPort) {
+ this.serverPort = serverPort;
+ }
+
+ public int getServerPort() {
+ return serverPort;
+ }
+
+ public void setSsl(boolean ssl) {
+ this.ssl = ssl;
+ }
+
+ public boolean isSsl() {
+ return ssl;
+ }
+
public void connect() throws IOException {
socket = SocketFactory.getDefault().createSocket(host, port);
}
@@ -66,11 +281,7 @@ public class SimpleAjpClient {
/*
* Create a message to request the given URL.
*/
- public TesterAjpMessage createForwardMessage(String url) {
- return createForwardMessage(url, 2);
- }
-
- public TesterAjpMessage createForwardMessage(String url, int method) {
+ public TesterAjpMessage createForwardMessage() {
TesterAjpMessage message = new TesterAjpMessage(AJP_PACKET_SIZE);
message.reset();
@@ -86,30 +297,29 @@ public class SimpleAjpClient {
message.appendByte(method);
// Protocol
- message.appendString("http");
+ message.appendString(protocol);
// Request URI
- message.appendString(url);
+ message.appendString(uri);
- // Remote address
- message.appendString("10.0.0.1");
+ // Client address
+ message.appendString(remoteAddr);
- // Remote host
- message.appendString("client.dev.local");
+ // Client host
+ message.appendString(remoteHost);
// Server name
- message.appendString(host);
+ message.appendString(serverName);
- // Port
- message.appendInt(port);
+ // Server port
+ message.appendInt(serverPort);
// Is ssl
- message.appendByte(0x00);
+ message.appendByte(ssl ? 0x01 : 0x00);
return message;
}
-
public TesterAjpMessage createBodyMessage(byte[] data) {
TesterAjpMessage message = new TesterAjpMessage(AJP_PACKET_SIZE);
Modified: tomcat/trunk/test/org/apache/coyote/ajp/TestAbstractAjpProcessor.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/ajp/TestAbstractAjpProcessor.java?rev=1645488&r1=1645487&r2=1645488&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/ajp/TestAbstractAjpProcessor.java
(original)
+++ tomcat/trunk/test/org/apache/coyote/ajp/TestAbstractAjpProcessor.java Sun
Dec 14 18:32:42 2014
@@ -20,9 +20,11 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
@@ -60,6 +62,387 @@ public class TestAbstractAjpProcessor ex
return protocol;
}
+ private void doSnoopTest(RequestDescriptor desc) throws Exception {
+
+ HashMap<String, String> requestInfo = desc.getRequestInfo();
+ HashMap<String, String> contextInitParameters =
desc.getContextInitParameters();
+ HashMap<String, String> contextAttributes =
desc.getContextAttributes();
+ HashMap<String, String> headers = desc.getHeaders();
+ HashMap<String, String> attributes = desc.getAttributes();
+ HashMap<String, String> params = desc.getParams();
+
+ Tomcat tomcat = getTomcatInstance();
+
+ // No file system docBase required
+ Context ctx = tomcat.addContext("", null);
+
+ Tomcat.addServlet(ctx, "snoop", new SnoopServlet());
+ ctx.addServletMapping("/", "snoop");
+
+ SimpleAjpClient ajpClient = new SimpleAjpClient();
+
+ if (requestInfo.get("REQUEST-QUERY-STRING") != null &&
+ params.size() > 0) {
+ throw(new IllegalArgumentException("Request setting " +
+ "'REQUEST-QUERY-STRING' and explicit params not allowed " +
+ "together"));
+ }
+
+ String value;
+ HashMap<String, String> savedRequestInfo = new HashMap<String,
String>();
+ for (String name: requestInfo.keySet()) {
+ value = requestInfo.get(name);
+ switch (name) {
+ case "REQUEST-METHOD":
+ ajpClient.setMethod(value);
+ break;
+ case "REQUEST-PROTOCOL":
+ ajpClient.setProtocol(value);
+ break;
+ case "REQUEST-URI":
+ ajpClient.setUri(value);
+ break;
+ case "REQUEST-REMOTE-HOST":
+ /* request.getRemoteHost() will default to
+ * request.getRemoteAddr() unless enableLookups is set. */
+ tomcat.getConnector().setEnableLookups(true);
+ ajpClient.setRemoteHost(value);
+ break;
+ case "REQUEST-REMOTE-ADDR":
+ ajpClient.setRemoteAddr(value);
+ break;
+ case "REQUEST-SERVER-NAME":
+ ajpClient.setServerName(value);
+ break;
+ case "REQUEST-SERVER-PORT":
+ ajpClient.setServerPort(Integer.valueOf(value));
+ break;
+ case "REQUEST-IS-SECURE":
+ ajpClient.setSsl(Boolean.parseBoolean(value));
+ break;
+ case "REQUEST-LOCAL-ADDR":
+ savedRequestInfo.put(name, value);
+ break;
+ case "REQUEST-REMOTE-PORT":
+ savedRequestInfo.put(name, value);
+ break;
+ case "REQUEST-REMOTE-USER":
+ case "REQUEST-ROUTE":
+ case "REQUEST-SECRET":
+ case "REQUEST-AUTH-TYPE":
+ case "REQUEST-QUERY-STRING":
+ savedRequestInfo.put(name, value);
+ break;
+ case "REQUEST-CONTENT-LENGTH":
+ headers.put("CONTENT-LENGTH", value);
+ break;
+ case "REQUEST-CONTENT-TYPE":
+ headers.put("CONTENT-TYPE", value);
+ break;
+ /* Not yet implemented or not (easily) possible to implement */
+ case "REQUEST-LOCAL-NAME": //request.getLocalName()
+ case "REQUEST-LOCAL-PORT": //request.getLocalPort()
+ case "REQUEST-SCHEME": //request.getScheme()
+ case "REQUEST-URL": //request.getRequestURL()
+ case "REQUEST-CONTEXT-PATH": //request.getContextPath()
+ case "REQUEST-SERVLET-PATH": //request.getServletPath()
+ case "REQUEST-PATH-INFO": //request.getPathInfo()
+ case "REQUEST-PATH-TRANSLATED":
//request.getPathTranslated()
+ case "REQUEST-USER-PRINCIPAL":
//request.getUserPrincipal()
+ case "REQUEST-CHARACTER-ENCODING":
//request.getCharacterEncoding()
+ case "REQUEST-LOCALE": //request.getLocale()
+ case "SESSION-REQUESTED-ID":
//request.getRequestedSessionId()
+ case "SESSION-REQUESTED-ID-COOKIE":
//request.isRequestedSessionIdFromCookie()
+ case "SESSION-REQUESTED-ID-URL":
//request.isRequestedSessionIdFromUrl()
+ case "SESSION-REQUESTED-ID-VALID":
//request.isRequestedSessionIdValid()
+ default:
+ throw(new IllegalArgumentException("Request setting '" +
name + "' not supported"));
+ }
+ }
+
+ ServletContext sc = ctx.getServletContext();
+ for (String name: contextInitParameters.keySet()) {
+ sc.setInitParameter(name, contextInitParameters.get(name));
+ }
+ for (String name: contextAttributes.keySet()) {
+ sc.setAttribute(name, contextAttributes.get(name));
+ }
+
+ /* Basic request properties must be set before this call */
+ TesterAjpMessage forwardMessage = ajpClient.createForwardMessage();
+
+ for (String name: savedRequestInfo.keySet()) {
+ value = savedRequestInfo.get(name);
+ switch (name) {
+ case "REQUEST-LOCAL-ADDR":
+ forwardMessage.addAttribute("AJP_LOCAL_ADDR", value);
+ break;
+ case "REQUEST-REMOTE-PORT":
+ forwardMessage.addAttribute("AJP_REMOTE_PORT", value);
+ break;
+ case "REQUEST-REMOTE-USER":
+ /* request.getRemoteUser() will not trust the AJP
+ * info if tomcatAuthentication is set. */
+ tomcat.getConnector().setProperty("tomcatAuthentication",
"false");
+ forwardMessage.addAttribute(0x03, value);
+ break;
+ case "REQUEST-AUTH-TYPE":
+ /* request.getAuthType() will not trust the AJP
+ * info if tomcatAuthentication is set. */
+ tomcat.getConnector().setProperty("tomcatAuthentication",
"false");
+ forwardMessage.addAttribute(0x04, value);
+ break;
+ case "REQUEST-QUERY-STRING":
+ forwardMessage.addAttribute(0x05, value);
+ break;
+ case "REQUEST-ROUTE":
+ forwardMessage.addAttribute(0x06, value);
+ break;
+ case "REQUEST-SECRET":
+ forwardMessage.addAttribute(0x0C, value);
+ break;
+ default:
+ throw(new IllegalArgumentException("Request setting '" +
name + "' not supported"));
+ }
+ }
+
+ if (params.size() > 0) {
+ StringBuilder query = new StringBuilder();
+ boolean sep = false;
+ for (String name: params.keySet()) {
+ if (sep) {
+ query.append("&");
+ } else {
+ sep = true;
+ }
+ query.append(name);
+ query.append("=");
+ query.append(params.get(name));
+ }
+ forwardMessage.addAttribute(0x05, query.toString());
+ }
+
+ for (String name: headers.keySet()) {
+ value = headers.get(name);
+ name = name.toUpperCase();
+ switch (name) {
+ case "ACCEPT":
+ forwardMessage.addHeader(0xA001, value);
+ break;
+ case "ACCEPT-CHARSET":
+ forwardMessage.addHeader(0xA002, value);
+ break;
+ case "ACCEPT-ENCODING":
+ forwardMessage.addHeader(0xA003, value);
+ break;
+ case "ACCEPT-LANGUAGE":
+ forwardMessage.addHeader(0xA004, value);
+ break;
+ case "AUTHORIZATION":
+ forwardMessage.addHeader(0xA005, value);
+ break;
+ case "CONNECTION":
+ forwardMessage.addHeader(0xA006, value);
+ break;
+ case "CONTENT-TYPE":
+ forwardMessage.addHeader(0xA007, value);
+ break;
+ case "CONTENT-LENGTH":
+ forwardMessage.addHeader(0xA008, value);
+ break;
+ case "COOKIE":
+ forwardMessage.addHeader(0xA009, value);
+ break;
+ case "COOKIE2":
+ forwardMessage.addHeader(0xA00A, value);
+ break;
+ case "HOST":
+ forwardMessage.addHeader(0xA00B, value);
+ break;
+ case "PRAGMA":
+ forwardMessage.addHeader(0xA00C, value);
+ break;
+ case "REFERER":
+ forwardMessage.addHeader(0xA00D, value);
+ break;
+ case "USER-AGENT":
+ forwardMessage.addHeader(0xA00E, value);
+ break;
+ default:
+ forwardMessage.addHeader(name, value);
+ break;
+ }
+ }
+ for (String name: attributes.keySet()) {
+ value = attributes.get(name);
+ forwardMessage.addAttribute(name, value);
+ }
+ // Complete the message
+ forwardMessage.end();
+
+ tomcat.start();
+ ajpClient.setPort(getPort());
+ ajpClient.connect();
+
+ // Expect 3 packets: headers, body, end
+ TesterAjpMessage responseHeaders =
ajpClient.sendMessage(forwardMessage);
+ validateResponseHeaders(responseHeaders, 200, "OK");
+
+ String body = extractResponseBody(ajpClient.readMessage());
+ RequestDescriptor result = SnoopResult.parse(body);
+
+ /* AJP attributes result in Coyote Request attributes, which are
+ * not listed by request.getAttributeNames(), so SnoopServlet
+ * does not see them. Delete attributes before result comparison. */
+ desc.getAttributes().clear();
+
+ result.compare(desc);
+
+ validateResponseEnd(ajpClient.readMessage(), true);
+ }
+
+ @Test
+ public void testServerName() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-SERVER-NAME", "MYSERVER");
+ desc.putRequestInfo("REQUEST-URI", "/testServerName");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testServerPort() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-SERVER-PORT", "8888");
+ desc.putRequestInfo("REQUEST-URI", "/testServerPort");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testLocalAddr() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-LOCAL-ADDR", "10.3.2.1");
+ desc.putRequestInfo("REQUEST-URI", "/testLocalAddr");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testRemoteHost() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-REMOTE-HOST", "MYCLIENT");
+ desc.putRequestInfo("REQUEST-URI", "/testRemoteHost");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testRemoteAddr() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-REMOTE-ADDR", "10.1.2.3");
+ desc.putRequestInfo("REQUEST-URI", "/testRemoteAddr");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testRemotePort() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-REMOTE-PORT", "34567");
+ desc.putRequestInfo("REQUEST-URI", "/testRemotePort");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testMethod() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-METHOD", "LOCK");
+ desc.putRequestInfo("REQUEST-URI", "/testMethod");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testUri() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-URI", "/a/b/c");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testProtocol() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-PROTOCOL", "HTTP/1.x");
+ desc.putRequestInfo("REQUEST-URI", "/testProtocol");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testSecure() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-IS-SECURE", "true");
+ desc.putRequestInfo("REQUEST-URI", "/testSecure");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testQueryString() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-QUERY-STRING", "p1=1&p2=12&p3=123");
+ desc.putRequestInfo("REQUEST-URI", "/testQueryString");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testRemoteUser() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-REMOTE-USER", "MYUSER");
+ desc.putRequestInfo("REQUEST-URI", "/testRemoteUser");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testAuthType() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-AUTH-TYPE", "MyAuth");
+ desc.putRequestInfo("REQUEST-URI", "/testAuthType");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testOneHeader() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putHeader("MYHEADER", "MYHEADER-VALUE");
+ desc.putRequestInfo("REQUEST-URI", "/testOneHeader");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testOneAttribute() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putAttribute("MYATTRIBUTE", "MYATTRIBUTE-VALUE");
+ desc.putRequestInfo("REQUEST-URI", "/testOneAttribute");
+ doSnoopTest(desc);
+ }
+
+ @Test
+ public void testMulti() throws Exception {
+ RequestDescriptor desc = new RequestDescriptor();
+ desc.putRequestInfo("REQUEST-SERVER-NAME", "MYSERVER");
+ desc.putRequestInfo("REQUEST-SERVER-PORT", "8888");
+ desc.putRequestInfo("REQUEST-LOCAL-ADDR", "10.3.2.1");
+ desc.putRequestInfo("REQUEST-REMOTE-HOST", "MYCLIENT");
+ desc.putRequestInfo("REQUEST-REMOTE-ADDR", "10.1.2.3");
+ desc.putRequestInfo("REQUEST-REMOTE-PORT", "34567");
+ desc.putRequestInfo("REQUEST-METHOD", "LOCK");
+ desc.putRequestInfo("REQUEST-URI", "/a/b/c");
+ desc.putRequestInfo("REQUEST-PROTOCOL", "HTTP/1.x");
+ desc.putRequestInfo("REQUEST-IS-SECURE", "true");
+ desc.putRequestInfo("REQUEST-QUERY-STRING", "p1=1&p2=12&p3=123");
+ desc.putRequestInfo("REQUEST-REMOTE-USER", "MYUSER");
+ desc.putRequestInfo("REQUEST-AUTH-TYPE", "MyAuth");
+ desc.putHeader("MYHEADER1", "MYHEADER1-VALUE");
+ desc.putHeader("MYHEADER2", "MYHEADER2-VALUE");
+ desc.putAttribute("MYATTRIBUTE1", "MYATTRIBUTE-VALUE1");
+ desc.putAttribute("MYATTRIBUTE2", "MYATTRIBUTE-VALUE2");
+ doSnoopTest(desc);
+ }
+
@Test
public void testKeepAlive() throws Exception {
Tomcat tomcat = getTomcatInstance();
@@ -80,7 +463,8 @@ public class TestAbstractAjpProcessor ex
validateCpong(ajpClient.cping());
- TesterAjpMessage forwardMessage = ajpClient.createForwardMessage("/");
+ TesterAjpMessage forwardMessage = ajpClient.createForwardMessage();
+ forwardMessage.addHeader("X-DUMMY-HEADER", "IGNORE");
// Complete the message - no extra headers required.
forwardMessage.end();
@@ -88,7 +472,7 @@ public class TestAbstractAjpProcessor ex
for (int i = 0; i < 2; i++) {
TesterAjpMessage responseHeaders =
ajpClient.sendMessage(forwardMessage);
// Expect 3 packets: headers, body, end
- validateResponseHeaders(responseHeaders, 200);
+ validateResponseHeaders(responseHeaders, 200, "OK");
TesterAjpMessage responseBody = ajpClient.readMessage();
validateResponseBody(responseBody,
HelloWorldServlet.RESPONSE_TEXT);
validateResponseEnd(ajpClient.readMessage(), true);
@@ -105,18 +489,19 @@ public class TestAbstractAjpProcessor ex
@Test
public void testPost() throws Exception {
- doTestPost(false, HttpServletResponse.SC_OK);
+ doTestPost(false, HttpServletResponse.SC_OK, "OK");
}
@Test
public void testPostMultipleContentLength() throws Exception {
// Multiple content lengths
- doTestPost(true, HttpServletResponse.SC_BAD_REQUEST);
+ doTestPost(true, HttpServletResponse.SC_BAD_REQUEST, "Bad Request");
}
- public void doTestPost(boolean multipleCL, int expectedStatus) throws
Exception {
+ public void doTestPost(boolean multipleCL, int expectedStatus,
+ String expectedMessage) throws Exception {
getTomcatInstanceTestWebapp(false, true);
@@ -126,8 +511,9 @@ public class TestAbstractAjpProcessor ex
validateCpong(ajpClient.cping());
- TesterAjpMessage forwardMessage =
- ajpClient.createForwardMessage("/test/echo-params.jsp", 4);
+ ajpClient.setUri("/test/echo-params.jsp");
+ ajpClient.setMethod("POST");
+ TesterAjpMessage forwardMessage = ajpClient.createForwardMessage();
forwardMessage.addHeader(0xA008, "9");
if (multipleCL) {
forwardMessage.addHeader(0xA008, "99");
@@ -141,7 +527,7 @@ public class TestAbstractAjpProcessor ex
TesterAjpMessage responseHeaders =
ajpClient.sendMessage(forwardMessage, bodyMessage);
- validateResponseHeaders(responseHeaders, expectedStatus);
+ validateResponseHeaders(responseHeaders, expectedStatus,
expectedMessage);
if (expectedStatus == HttpServletResponse.SC_OK) {
// Expect 3 messages: headers, body, end for a valid request
TesterAjpMessage responseBody = ajpClient.readMessage();
@@ -182,14 +568,14 @@ public class TestAbstractAjpProcessor ex
validateCpong(ajpClient.cping());
- TesterAjpMessage forwardMessage = ajpClient.createForwardMessage("/");
+ TesterAjpMessage forwardMessage = ajpClient.createForwardMessage();
forwardMessage.end();
TesterAjpMessage responseHeaders =
ajpClient.sendMessage(forwardMessage, null);
// Expect 2 messages: headers, end
- validateResponseHeaders(responseHeaders, 304);
+ validateResponseHeaders(responseHeaders, 304, "Not Modified");
validateResponseEnd(ajpClient.readMessage(), true);
// Double check the connection is still open
@@ -201,25 +587,25 @@ public class TestAbstractAjpProcessor ex
@Test
public void testZeroLengthRequestBodyGetA() throws Exception {
- doTestZeroLengthRequestBody(2, true);
+ doTestZeroLengthRequestBody("GET", true);
}
@Test
public void testZeroLengthRequestBodyGetB() throws Exception {
- doTestZeroLengthRequestBody(2, false);
+ doTestZeroLengthRequestBody("GET", false);
}
@Test
public void testZeroLengthRequestBodyPostA() throws Exception {
- doTestZeroLengthRequestBody(4, true);
+ doTestZeroLengthRequestBody("POST", true);
}
@Test
public void testZeroLengthRequestBodyPostB() throws Exception {
- doTestZeroLengthRequestBody(4, false);
+ doTestZeroLengthRequestBody("POST", false);
}
- private void doTestZeroLengthRequestBody(int method, boolean callAvailable)
+ private void doTestZeroLengthRequestBody(String method, boolean
callAvailable)
throws Exception {
Tomcat tomcat = getTomcatInstance();
@@ -239,7 +625,8 @@ public class TestAbstractAjpProcessor ex
validateCpong(ajpClient.cping());
- TesterAjpMessage forwardMessage = ajpClient.createForwardMessage("/",
method);
+ ajpClient.setMethod(method);
+ TesterAjpMessage forwardMessage = ajpClient.createForwardMessage();
forwardMessage.addHeader(0xA008, "0");
forwardMessage.end();
@@ -247,7 +634,7 @@ public class TestAbstractAjpProcessor ex
ajpClient.sendMessage(forwardMessage, null);
// Expect 3 messages: headers, body, end
- validateResponseHeaders(responseHeaders, 200);
+ validateResponseHeaders(responseHeaders, 200, "OK");
validateResponseBody(ajpClient.readMessage(),
"Request Body length in bytes: 0");
validateResponseEnd(ajpClient.readMessage(), true);
@@ -277,7 +664,7 @@ public class TestAbstractAjpProcessor ex
* ignored.
*/
private void validateResponseHeaders(TesterAjpMessage message,
- int expectedStatus) throws Exception {
+ int expectedStatus, String expectedMessage) throws Exception {
// First two bytes should always be AB
Assert.assertEquals((byte) 'A', message.buf[0]);
Assert.assertEquals((byte) 'B', message.buf[1]);
@@ -294,8 +681,8 @@ public class TestAbstractAjpProcessor ex
// Check status
Assert.assertEquals(expectedStatus, message.readInt());
- // Read the status message
- message.readString();
+ // Check the reason phrase
+ Assert.assertEquals(expectedMessage, message.readString());
// Get the number of headers
int headerCount = message.readInt();
@@ -309,11 +696,10 @@ public class TestAbstractAjpProcessor ex
}
/**
- * Validates that the response message is valid and contains the expected
- * content.
+ * Extract the content from a response message.
*/
- private void validateResponseBody(TesterAjpMessage message,
- String expectedBody) throws Exception {
+ private String extractResponseBody(TesterAjpMessage message)
+ throws Exception {
Assert.assertEquals((byte) 'A', message.buf[0]);
Assert.assertEquals((byte) 'B', message.buf[1]);
@@ -326,8 +712,17 @@ public class TestAbstractAjpProcessor ex
int len = message.readInt();
Assert.assertTrue(len > 0);
- String body = message.readString(len);
+ return message.readString(len);
+ }
+
+ /**
+ * Validates that the response message is valid and contains the expected
+ * content.
+ */
+ private void validateResponseBody(TesterAjpMessage message,
+ String expectedBody) throws Exception {
+ String body = extractResponseBody(message);
Assert.assertTrue(body.contains(expectedBody));
}
Modified: tomcat/trunk/test/org/apache/coyote/ajp/TesterAjpMessage.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/ajp/TesterAjpMessage.java?rev=1645488&r1=1645487&r2=1645488&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/ajp/TesterAjpMessage.java (original)
+++ tomcat/trunk/test/org/apache/coyote/ajp/TesterAjpMessage.java Sun Dec 14
18:32:42 2014
@@ -29,6 +29,7 @@ import java.util.List;
public class TesterAjpMessage extends AjpMessage {
private final List<Header> headers = new ArrayList<>();
+ private final List<Attribute> attributes = new ArrayList<>();
public TesterAjpMessage(int packetSize) {
@@ -86,6 +87,16 @@ public class TesterAjpMessage extends Aj
}
+ public void addAttribute(int code, String value) {
+ attributes.add(new Attribute(code, value));
+ }
+
+
+ public void addAttribute(String name, String value) {
+ attributes.add(new Attribute(name, value));
+ }
+
+
@Override
public void end() {
// Add the header count
@@ -95,6 +106,10 @@ public class TesterAjpMessage extends Aj
header.append(this);
}
+ for (Attribute attribute : attributes) {
+ attribute.append(this);
+ }
+
// Terminator
appendByte(0xFF);
@@ -121,7 +136,6 @@ public class TesterAjpMessage extends Aj
}
-
private static class Header {
private final int code;
private final String name;
@@ -147,5 +161,34 @@ public class TesterAjpMessage extends Aj
}
message.appendString(value);
}
+ }
+
+
+ private static class Attribute {
+ private final int code;
+ private final String name;
+ private final String value;
+
+ public Attribute(int code, String value) {
+ this.code = code;
+ this.name = null;
+ this.value = value;
+ }
+
+ public Attribute(String name, String value) {
+ this.code = 0;
+ this.name = name;
+ this.value = value;
+ }
+
+ public void append(TesterAjpMessage message) {
+ if (code == 0) {
+ message.appendByte(0x0A);
+ message.appendString(name);
+ } else {
+ message.appendByte(code);
+ }
+ message.appendString(value);
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]