blob: c968f7c58634eee6b941f117ef8ad92d33dfc4b9 [file] [log] [blame]
/*
* Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
import java.io.*;
import java.net.*;
import com.sun.ejte.ccl.reporter.*;
import org.apache.catalina.startup.SimpleHttpClient;
/*
* Unit test for https://issues.apache.org/bugzilla/show_bug.cgi?id=49779
* 501 Method not implemented with successive POST requests
*/
public class WebTest {
private static final String TEST_NAME =
"test-form-authenticator";
private static final SimpleReporterAdapter stat =
new SimpleReporterAdapter("appserv-tests");
private String host;
private int port;
private String contextRoot;
private String adminUser;
private String adminPassword;
public WebTest(String[] args) {
host = args[0];
port = Integer.parseInt(args[1]);
contextRoot = args[2];
adminUser = args[3];
adminPassword = args[4];
}
public static void main(String[] args) {
stat.addDescription("Unit test for Tomcat bug 49779");
WebTest webTest = new WebTest(args);
try {
webTest.run();
stat.addStatus(TEST_NAME, stat.PASS);
} catch( Exception ex) {
ex.printStackTrace();
stat.addStatus(TEST_NAME, stat.FAIL);
}
stat.printSummary();
}
public void run() throws Exception {
testGet();
testPostNoContinue();
testPostWithContinue();
testPostNoContinuePostRedirect();
testPostWithContinuePostRedirect();
}
public void testGet() throws Exception {
doTest("GET", "GET", false);
}
public void testPostNoContinue() throws Exception {
doTest("POST", "GET", false);
}
public void testPostWithContinue() throws Exception {
doTest("POST", "GET", true);
}
// Bugzilla Bug 49779
public void testPostNoContinuePostRedirect() throws Exception {
doTest("POST", "POST", false);
}
// Bugzilla Bug 49779
public void testPostWithContinuePostRedirect() throws Exception {
doTest("POST", "POST", true);
}
public void doTest(String resourceMethod, String redirectMethod,
boolean useContinue) throws Exception {
FormAuthClient client = new FormAuthClient();
// First request for authenticated resource
client.setUseContinue(useContinue);
client.doResourceRequest(resourceMethod);
assertTrue(client.isResponse200());
assertTrue(client.isResponseBodyOK());
client.reset();
// Second request for the login page
client.setUseContinue(useContinue);
client.doLoginRequest();
assertTrue(client.isResponse302());
assertTrue(client.isResponseBodyOK());
client.reset();
// Third request - follow the redirect
client.doResourceRequest(redirectMethod);
if ("POST".equals(redirectMethod)) {
client.setUseContinue(useContinue);
}
assertTrue(client.isResponse200());
assertTrue(client.isResponseBodyOK());
client.reset();
// Subsequent requests - direct to the resource
for (int i = 0; i < 5; i++) {
client.setUseContinue(useContinue);
client.doResourceRequest(resourceMethod);
assertTrue(client.isResponse200());
assertTrue(client.isResponseBodyOK());
client.reset();
}
}
private static void assertTrue(boolean status) {
if (!status) {
throw new RuntimeException();
}
}
private final class FormAuthClient extends SimpleHttpClient {
private static final String LOGIN_PAGE = "j_security_check";
private String protectedPage = "index.jsp";
private String protectedLocation = contextRoot;
private int requestCount = 0;
private String sessionId = null;
private FormAuthClient() {
setHost(host);
setPort(port);
}
private void doResourceRequest(String method) throws Exception {
StringBuilder requestHead = new StringBuilder(128);
String requestTail;
requestHead.append(method).append(" ").append(protectedLocation)
.append("/").append(protectedPage);
if ("GET".equals(method)) {
requestHead.append("?role=bar");
}
requestHead.append(" HTTP/1.1").append(CRLF);
requestHead.append("Host: " + host).append(CRLF);
requestHead.append("Connection: close").append(CRLF);
if (getUseContinue()) {
requestHead.append("Expect: 100-continue").append(CRLF);
}
if (sessionId != null) {
requestHead.append("Cookie: JSESSIONID=").append(sessionId)
.append(CRLF);
}
if ("POST".equals(method)) {
requestHead.append(
"Content-Type: application/x-www-form-urlencoded")
.append(CRLF);
requestHead.append("Content-length: 8").append(CRLF);
requestHead.append(CRLF);
requestTail = "role=bar";
} else {
requestTail = CRLF;
}
String request[] = new String[2];
request[0] = requestHead.toString();
request[1] = requestTail;
doRequest(request);
}
private void doLoginRequest() throws Exception {
StringBuilder requestHead = new StringBuilder(128);
requestHead.append("POST ").append(protectedLocation)
.append("/").append(LOGIN_PAGE).append(" HTTP/1.1").append(CRLF);
requestHead.append("Host: " + host).append(CRLF);
requestHead.append("Connection: close").append(CRLF);
if (getUseContinue()) {
requestHead.append("Expect: 100-continue").append(CRLF);
}
if (sessionId != null) {
requestHead.append("Cookie: JSESSIONID=").append(sessionId)
.append(CRLF);
}
requestHead.append(
"Content-Type: application/x-www-form-urlencoded").append(
CRLF);
requestHead.append("Content-length: 35").append(CRLF);
requestHead.append(CRLF);
String request[] = new String[2];
request[0] = requestHead.toString();
request[1] = "j_username=" + adminUser + "&j_password=" + adminPassword;
doRequest(request);
}
private void doRequest(String request[]) throws Exception {
setRequest(request);
try {
connect();
processRequest();
String newSessionId = getSessionId();
if (newSessionId != null) {
sessionId = newSessionId;
}
} finally {
disconnect();
}
requestCount++;
}
@Override
public boolean isResponseBodyOK() {
if (requestCount == 1) {
// First request should result in the login page
assertContains(getResponseBody(), "A JSP Login Page");
return true;
} else if (requestCount == 2) {
// Second request should result in a redirect
return true;
} else {
// Subsequent requests should result in the protected page
// The role parameter should have reached the page
String body = getResponseBody();
assertContains(body, "Hello javaee, bar");
/*
assertContains(body,
"<input type=\"text\" name=\"role\" value=\"bar\"");
*/
return true;
}
}
private void assertContains(String body, String expected) {
if (!body.contains(expected)) {
throw new RuntimeException("Response body check failure.\n"
+ "Expected to contain substring: [" + expected
+ "]\nActual: [" + body + "]");
}
}
}
}