-
Notifications
You must be signed in to change notification settings - Fork 138
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HttpMethodAuthTest moved to maven + HTTP1.0 client supporting custom …
…method - that was originally implemented by the org.apache.tomcat.task.GTest class from Tomcat webserver 3.2 of 2001. Signed-off-by: David Matějček <david.matejcek@omnifish.ee>
- Loading branch information
Showing
11 changed files
with
467 additions
and
370 deletions.
There are no files selected for viewing
165 changes: 165 additions & 0 deletions
165
appserver/itest-tools/src/main/java/org/glassfish/main/itest/tools/HttpClient10.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
/* | ||
* Copyright (c) 2023 Contributors to the Eclipse Foundation. | ||
* | ||
* 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 | ||
*/ | ||
|
||
package org.glassfish.main.itest.tools; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.OutputStreamWriter; | ||
import java.io.PrintWriter; | ||
import java.net.Socket; | ||
import java.net.URL; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.Base64; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import static java.nio.charset.StandardCharsets.UTF_8; | ||
|
||
/** | ||
* HTTP client using the HTTP 1.0 protocol, allowing to break some standards. | ||
* Useful for testing of server reactions to malformed or obsoleted requests. | ||
* <p> | ||
* Example: Request with nonstandard method, prohibited in later HTTP versions. | ||
*/ | ||
public class HttpClient10 { | ||
|
||
private final URL url; | ||
private final String user; | ||
private final String password; | ||
|
||
/** | ||
* @param url target endpoint. | ||
* @param user | ||
* @param password | ||
*/ | ||
public HttpClient10(URL url, String user, String password) { | ||
this.url = url; | ||
this.user = user; | ||
this.password = password; | ||
} | ||
|
||
|
||
/** | ||
* Sends the HTTP 1.0 request and reads the response. | ||
* | ||
* @param method GET/PUT/... or your custom method. | ||
* @param content the body | ||
* @return {@link HttpResponse} | ||
* @throws Exception | ||
*/ | ||
public HttpResponse send(String method, String content) throws Exception { | ||
try (Socket socket = new Socket(url.getHost(), url.getPort())) { | ||
InputStream inputStream = socket.getInputStream(); | ||
socket.setSoLinger(true, 1000); | ||
PrintWriter outputWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); | ||
outputWriter.println(method + " " + url.getPath() + " HTTP/1.0"); | ||
outputWriter.println("Host: " + url.getHost() + ':' + url.getPort()); | ||
if (content != null) { | ||
outputWriter.println("Content-Length: " + content.length()); | ||
} | ||
if (user != null && password != null) { | ||
String basicAuth = Base64.getEncoder().encodeToString((user + ":" + password).getBytes(UTF_8)); | ||
outputWriter.println("Authorization: Basic " + basicAuth); | ||
} | ||
outputWriter.println(""); | ||
if (content != null) { | ||
outputWriter.print(content); | ||
} | ||
outputWriter.flush(); | ||
return HttpResponse.parse(inputStream); | ||
} | ||
} | ||
|
||
/** | ||
* Parsed HTTP response. | ||
*/ | ||
public static class HttpResponse { | ||
|
||
/** | ||
* Example: <code>HTTP/1.0 403 Forbidden</copde> | ||
*/ | ||
public final String responseLine; | ||
/** | ||
* Response headers. | ||
*/ | ||
public final Map<String, String> headers; | ||
/** | ||
* Response body | ||
*/ | ||
public final String body; | ||
|
||
|
||
private HttpResponse(String responseLine, Map<String, String> headers, String body) { | ||
this.responseLine = responseLine; | ||
this.headers = headers; | ||
this.body = body; | ||
} | ||
|
||
|
||
private static HttpResponse parse(InputStream inputStream) throws IOException { | ||
String responseLine = parseResponseLine(inputStream); | ||
Map<String, String> headers = parseHeaders(inputStream); | ||
String body = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8).trim(); | ||
return new HttpResponse(responseLine, headers, body); | ||
} | ||
|
||
|
||
private static Map<String, String> parseHeaders(InputStream is) throws IOException { | ||
Map<String, String> headers = new HashMap<>(); | ||
while (true) { | ||
String line = parseResponseLine(is); | ||
if (line == null || line.isEmpty()) { | ||
break; | ||
} | ||
String[] header = parseHeader(line); | ||
headers.put(header[0], header[1]); | ||
} | ||
return headers; | ||
} | ||
|
||
|
||
private static String[] parseHeader(String line) { | ||
int colon = line.indexOf(':'); | ||
if (colon < 0) { | ||
throw new IllegalStateException("Invalid header: " + line); | ||
} | ||
String name = line.substring(0, colon).trim(); | ||
String value = line.substring(colon + 1).trim(); | ||
return new String[] {name, value}; | ||
} | ||
|
||
|
||
private static String parseResponseLine(InputStream input) throws IOException { | ||
StringBuilder sb = new StringBuilder(); | ||
while (true) { | ||
int ch = input.read(); | ||
if (ch < 0) { | ||
break; | ||
} else if (ch == '\n') { | ||
break; | ||
} | ||
sb.append((char) ch); | ||
} | ||
// Strip any trailing carriage return | ||
int n = sb.length(); | ||
if (n > 0 && sb.charAt(n - 1) == '\r') { | ||
sb.setLength(n - 1); | ||
} | ||
return sb.toString(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
...s/application/src/main/resources/org/glassfish/main/test/app/security/http/method/web.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN' 'http://java.sun.com/j2ee/dtds/web-app_2_2.dtd'> | ||
<!-- | ||
Copyright (c) 2023 Contributors to the Eclipse Foundation. | ||
Copyright (c) 2017, 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 | ||
--> | ||
<web-app> | ||
<display-name>security-httpMethod</display-name> | ||
<distributable></distributable> | ||
<servlet> | ||
<servlet-name>TestServlet</servlet-name> | ||
<servlet-class>org.glassfish.main.test.app.security.http.method.HttpMethodTestServlet</servlet-class> | ||
</servlet> | ||
<servlet> | ||
<servlet-name>TestServlet2</servlet-name> | ||
<servlet-class>org.glassfish.main.test.app.security.http.method.HttpMethodTestServlet</servlet-class> | ||
</servlet> | ||
<servlet-mapping> | ||
<servlet-name>TestServlet</servlet-name> | ||
<url-pattern>/TestServlet</url-pattern> | ||
</servlet-mapping> | ||
<servlet-mapping> | ||
<servlet-name>TestServlet2</servlet-name> | ||
<url-pattern>/TestServlet2</url-pattern> | ||
</servlet-mapping> | ||
|
||
<security-constraint> | ||
<web-resource-collection> | ||
<web-resource-name>secure1</web-resource-name> | ||
<url-pattern>/TestServlet</url-pattern> | ||
<http-method>FOO</http-method> | ||
<http-method>GET</http-method> | ||
</web-resource-collection> | ||
<auth-constraint> | ||
<role-name>manager</role-name> | ||
</auth-constraint> | ||
<user-data-constraint> | ||
<transport-guarantee>NONE</transport-guarantee> | ||
</user-data-constraint> | ||
</security-constraint> | ||
|
||
<security-constraint> | ||
<web-resource-collection> | ||
<web-resource-name>secure2</web-resource-name> | ||
<url-pattern>/TestServlet2</url-pattern> | ||
<http-method>FOO</http-method> | ||
</web-resource-collection> | ||
<auth-constraint> | ||
<role-name>manager</role-name> | ||
</auth-constraint> | ||
<user-data-constraint> | ||
<transport-guarantee>NONE</transport-guarantee> | ||
</user-data-constraint> | ||
</security-constraint> | ||
|
||
<login-config> | ||
<auth-method>BASIC</auth-method> | ||
<realm-name>default</realm-name> | ||
</login-config> | ||
|
||
<security-role> | ||
<role-name>manager</role-name> | ||
</security-role> | ||
</web-app> | ||
|
Oops, something went wrong.