Skip to content

Commit

Permalink
Updated HTTP server to completely use blocking IO and Java 21 virtual…
Browse files Browse the repository at this point in the history
… threads.
  • Loading branch information
voidmain committed Sep 6, 2024
1 parent 3cc242b commit fcee646
Show file tree
Hide file tree
Showing 69 changed files with 2,942 additions and 20,992 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
java-version: 21
- name: Install Savant Build
run: |
mkdir -p ~/dev/savant
Expand All @@ -28,7 +28,7 @@ jobs:
ln -s savant-2.0.0-RC.7 current
rm savant.tar.gz
cat <<EOF > ~/.savant/plugins/org.savantbuild.plugin.java.properties
17=${JAVA_HOME_17_X64}
21=${JAVA_HOME_21_X64}
EOF
shell: bash
- name: Run the build
Expand Down
6 changes: 3 additions & 3 deletions build.savant
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jackson5Version = "3.0.1"
restifyVersion = "4.2.1"
testngVersion = "7.10.2"

project(group: "io.fusionauth", name: "java-http", version: "0.3.5", licenses: ["ApacheV2_0"]) {
project(group: "io.fusionauth", name: "java-http", version: "0.4.0-RC.1", licenses: ["ApacheV2_0"]) {
workflow {
fetch {
// Dependency resolution order:
Expand Down Expand Up @@ -61,9 +61,9 @@ idea = loadPlugin(id: "org.savantbuild.plugin:idea:2.0.0-RC.7")
release = loadPlugin(id: "org.savantbuild.plugin:release-git:2.0.0-RC.6")
pom = loadPlugin(id: "org.savantbuild.plugin:pom:2.0.0-RC.6")

java.settings.javaVersion = "17"
java.settings.javaVersion = "21"
java.settings.compilerArguments = "--add-exports java.base/sun.security.x509=ALL-UNNAMED --add-exports java.base/sun.security.util=ALL-UNNAMED -XDignore.symbol.file"
javaTestNG.settings.javaVersion = "17"
javaTestNG.settings.javaVersion = "21"
javaTestNG.settings.jvmArguments = "--add-exports java.base/sun.security.x509=ALL-UNNAMED --add-exports java.base/sun.security.util=ALL-UNNAMED"
javaTestNG.settings.testngArguments = "-listener io.fusionauth.http.BaseTest\$TestListener"

Expand Down
10 changes: 5 additions & 5 deletions java-http.iml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MODULE_DIR$/.savant/cache/com/fasterxml/jackson/core/jackson-databind/2.15.4/jackson-databind-2.15.4-src.jar!/" />
<root url="jar://$MODULE_DIR$/.savant/cache/com/fasterxml/jackson/core/jackson-databind/2.15.4/jackson-databind-2.15.4-sources.jar!/" />
</SOURCES>
</library>
</orderEntry>
Expand All @@ -54,7 +54,7 @@
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MODULE_DIR$/.savant/cache/com/fasterxml/jackson/core/jackson-annotations/2.15.4/jackson-annotations-2.15.4-src.jar!/" />
<root url="jar://$MODULE_DIR$/.savant/cache/com/fasterxml/jackson/core/jackson-annotations/2.15.4/jackson-annotations-2.15.4-sources.jar!/" />
</SOURCES>
</library>
</orderEntry>
Expand All @@ -65,7 +65,7 @@
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MODULE_DIR$/.savant/cache/com/fasterxml/jackson/core/jackson-core/2.15.4/jackson-core-2.15.4-src.jar!/" />
<root url="jar://$MODULE_DIR$/.savant/cache/com/fasterxml/jackson/core/jackson-core/2.15.4/jackson-core-2.15.4-sources.jar!/" />
</SOURCES>
</library>
</orderEntry>
Expand All @@ -76,7 +76,7 @@
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MODULE_DIR$/.savant/cache/org/testng/testng/7.10.2/testng-7.10.2-src.jar!/" />
<root url="jar://$MODULE_DIR$/.savant/cache/org/testng/testng/7.10.2/testng-7.10.2-sources.jar!/" />
</SOURCES>
</library>
</orderEntry>
Expand Down Expand Up @@ -109,7 +109,7 @@
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MODULE_DIR$/.savant/cache/org/webjars/jquery/3.7.1/jquery-3.7.1-src.jar!/" />
<root url="jar://$MODULE_DIR$/.savant/cache/org/webjars/jquery/3.7.1/jquery-3.7.1-sources.jar!/" />
</SOURCES>
</library>
</orderEntry>
Expand Down
13 changes: 12 additions & 1 deletion java-http.ipr
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="HttpUrlsUsage" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="NullableProblems" enabled="true" level="WARNING" enabled_by_default="true">
<option name="REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE" value="true" />
<option name="REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOT_ANNOTATED_GETTER" value="true" />
<option name="IGNORE_EXTERNAL_SUPER_NOTNULL" value="true" />
<option name="REPORT_NOT_ANNOTATED_SETTER_PARAMETER" value="true" />
<option name="REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS" value="true" />
<option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" />
</inspection_tool>
<inspection_tool class="SizeReplaceableByIsEmpty" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredTypes">
<set>
Expand Down Expand Up @@ -1391,7 +1402,7 @@
<module fileurl="file://$PROJECT_DIR$/load-tests/tomcat/tomcat.iml" filepath="$PROJECT_DIR$/load-tests/tomcat/tomcat.iml" />
</modules>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="Java 17" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="Java 21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="VcsDirectoryMappings">
Expand Down
13 changes: 5 additions & 8 deletions load-tests/self/build.savant
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ import java.nio.file.Paths
* either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
restifyVersion = "4.1.2"
testngVersion = "7.6.1"

project(group: "io.fusionauth", name: "self", version: "0.1.0", licenses: ["Apache-2.0"]) {
workflow {
fetch {
Expand All @@ -35,7 +32,7 @@ project(group: "io.fusionauth", name: "self", version: "0.1.0", licenses: ["Apac

dependencies {
group(name: "compile") {
dependency(id: "io.fusionauth:java-http:0.1.8")
dependency(id: "io.fusionauth:java-http:0.4.0-{integration}")
}
}

Expand All @@ -52,7 +49,7 @@ idea = loadPlugin(id: "org.savantbuild.plugin:idea:2.0.0-RC.4")
tomcat = loadPlugin(id: "org.savantbuild.plugin:tomcat:2.0.0-RC.4")
webapp = loadPlugin(id: "org.savantbuild.plugin:webapp:2.0.0-RC.5.{integration}")

java.settings.javaVersion = "17"
java.settings.javaVersion = "21"
java.settings.compilerArguments = "--add-exports java.base/sun.security.x509=ALL-UNNAMED --add-exports java.base/sun.security.util=ALL-UNNAMED -XDignore.symbol.file"
tomcat.settings.buildDirectory = Paths.get("build/dist/tomcat")
tomcat.settings.buildWebDirectory = Paths.get("build/dist/tomcat/web")
Expand All @@ -72,15 +69,15 @@ target(name: "jar", description: "Builds the project JARs", dependsOn: ["compile

target(name: "app", description: "Builds the app", dependsOn: ["jar"]) {
// Copy all compile dependencies to be able to run command line
dependency.copy(to: "build/lib") {
dependency.copy(to: "build/dist/lib") {
dependencies(group: "compile", transitive: true, fetchSource: false)
}

file.copy(to: "build/lib") {
file.copy(to: "build/dist/lib") {
fileSet(dir: "build/jars")
}

file.copy(to: "build") {
file.copy(to: "build/dist") {
fileSet(dir: "src/main/script")
}
}
Expand Down
4 changes: 2 additions & 2 deletions load-tests/self/self.iml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$USER_HOME$/.savant/cache/io/fusionauth/java-http/0.1.8/java-http-0.1.8.jar!/" />
<root url="jar://$USER_HOME$/.savant/cache/io/fusionauth/java-http/0.4.0-{integration}/java-http-0.4.0-{integration}.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.savant/cache/io/fusionauth/java-http/0.1.8/java-http-0.1.8-src.jar!/" />
<root url="jar://$USER_HOME$/.savant/cache/io/fusionauth/java-http/0.4.0-{integration}/java-http-0.4.0-{integration}-src.jar!/" />
</SOURCES>
</library>
</orderEntry>
Expand Down
21 changes: 19 additions & 2 deletions load-tests/self/src/main/java/io/fusionauth/http/load/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,35 @@
*/
package io.fusionauth.http.load;

import java.time.Duration;

import io.fusionauth.http.log.Level;
import io.fusionauth.http.log.SystemOutLoggerFactory;
import io.fusionauth.http.server.CountingInstrumenter;
import io.fusionauth.http.server.HTTPListenerConfiguration;
import io.fusionauth.http.server.HTTPServer;

public class Main {
public static void main(String[] args) throws Exception {
SystemOutLoggerFactory.FACTORY.getLogger(Object.class).setLevel(Level.Debug);

System.out.println("Starting java-http server");
CountingInstrumenter instrumenter = new CountingInstrumenter();
try (HTTPServer ignore = new HTTPServer().withHandler(new LoadHandler())
.withClientTimeout(Duration.ofSeconds(100L))
.withCompressByDefault(false)
.withInstrumenter(instrumenter)
.withListener(new HTTPListenerConfiguration(8080))
.withNumberOfWorkerThreads(200)
.withLoggerFactory(SystemOutLoggerFactory.FACTORY)
.start()) {
Thread.sleep(1_000_000);

for (int i = 0; i < 1_000; i++) {
Thread.sleep(10_000);
System.out.printf("Current stats. Bad requests [%s]. Bytes read [%s]. Bytes written [%s]. Chunked requests [%s]. Chunked responses [%s]. Closed connections [%s]. Connections [%s]. Started [%s].\n",
instrumenter.getBadRequests(), instrumenter.getBytesRead(), instrumenter.getBytesWritten(), instrumenter.getChunkedRequests(),
instrumenter.getChunkedResponses(), instrumenter.getClosedConnections(), instrumenter.getConnections(), instrumenter.getStartedCount());
}

System.out.println("Shutting down java-http server");
}
}
Expand Down
2 changes: 1 addition & 1 deletion load-tests/self/src/main/script/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ if [[ $# -gt 1 && $1 == "--suspend" ]]; then
shift
fi

~/dev/java/current17/bin/java ${suspend} -cp "${CLASSPATH}" io.fusionauth.http.load.Main
~/dev/java/current21/bin/java ${suspend} -cp "${CLASSPATH}" io.fusionauth.http.load.Main
31 changes: 0 additions & 31 deletions src/main/java/io/fusionauth/http/ClientSSLHandshakeException.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,9 @@
package io.fusionauth.http;

/**
* An exception thrown when the server determines the request is too slow, has timed out or something like that.
* An exception thrown when the client closes the socket and the server should handle it gracefully.
*
* @author Daniel DeGroff
*/
public class ConnectionClosedException extends RuntimeException {
public ConnectionClosedException(Throwable cause) {
super(cause);
}
}
61 changes: 48 additions & 13 deletions src/main/java/io/fusionauth/http/Cookie.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,25 @@
import java.util.List;
import java.util.Objects;

import io.fusionauth.http.HTTPValues.CookieAttributes;
import io.fusionauth.http.util.DateTools;

@SuppressWarnings("unused")
public class Cookie implements Buildable<Cookie> {
public static final String DomainPrefix = "; " + CookieAttributes.Domain + "=";

public static final String ExpiresPrefix = "; " + CookieAttributes.Expires + "=";

public static final String HTTPOnlyPrefix = "; " + CookieAttributes.HttpOnly;

public static final String MaxAgePrefix = "; " + CookieAttributes.MaxAge + "=";

public static final String PathPrefix = "; " + CookieAttributes.Path + "=";

public static final String SameSitePrefix = "; " + CookieAttributes.SameSite + "=";

public static final String SecurePrefix = "; " + CookieAttributes.Secure;

public String domain;

public ZonedDateTime expires;
Expand Down Expand Up @@ -93,7 +109,7 @@ public static List<Cookie> fromRequestHeader(String header) {
start = i + 1;
} else if (c == ';' && inValue) {
value = new String(chars, start, i - start);
if (name.trim().length() > 0 && value.trim().length() > 0) {
if (!name.trim().isEmpty() && !value.trim().isEmpty()) {
cookies.add(new Cookie(name, value));
}

Expand All @@ -116,7 +132,7 @@ public static List<Cookie> fromRequestHeader(String header) {
value = header.substring(start);
}

if (name != null && value != null && name.trim().length() > 0 && value.trim().length() > 0) {
if (name != null && value != null && !name.trim().isEmpty() && !value.trim().isEmpty()) {
cookies.add(new Cookie(name, value));
}

Expand Down Expand Up @@ -208,7 +224,7 @@ public static Cookie fromResponseHeader(String header) {
if (inAttributes) {
cookie.addAttribute(name, value);
} else {
if (name == null || value == null || name.trim().length() == 0) {
if (name == null || value == null || name.trim().isEmpty()) {
return null;
}

Expand Down Expand Up @@ -261,10 +277,9 @@ public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Cookie)) {
if (!(o instanceof Cookie cookie)) {
return false;
}
Cookie cookie = (Cookie) o;
return httpOnly == cookie.httpOnly &&
secure == cookie.secure &&
Objects.equals(domain, cookie.domain) &&
Expand Down Expand Up @@ -357,14 +372,34 @@ public String toRequestHeader() {
}

public String toResponseHeader() {
return name + "=" + value
+ (domain != null ? ("; " + HTTPValues.CookieAttributes.Domain + "=" + domain) : "")
+ (expires != null ? ("; " + HTTPValues.CookieAttributes.Expires + "=" + DateTools.format(expires)) : "")
+ (httpOnly ? ("; " + HTTPValues.CookieAttributes.HttpOnly) : "")
+ (maxAge != null ? ("; " + HTTPValues.CookieAttributes.MaxAge + "=" + maxAge) : "")
+ (path != null ? ("; " + HTTPValues.CookieAttributes.Path + "=" + path) : "")
+ (sameSite != null ? ("; " + HTTPValues.CookieAttributes.SameSite + "=" + sameSite.name()) : "")
+ (secure ? ("; " + HTTPValues.CookieAttributes.Secure) : "");
var build = new StringBuilder();
build.append(name).append("=");
if (value != null) {
build.append(value);
}
if (domain != null) {
build.append(DomainPrefix).append(domain);
}
if (expires != null) {
build.append(ExpiresPrefix).append(DateTools.format(expires));
}
if (httpOnly) {
build.append(HTTPOnlyPrefix);
}
if (maxAge != null) {
build.append(MaxAgePrefix).append(maxAge);
}
if (path != null) {
build.append(PathPrefix).append(path);
}
if (sameSite != null) {
build.append(SameSitePrefix).append(sameSite.name());
}
if (secure) {
build.append(SecurePrefix);
}

return build.toString();
}

public enum SameSite {
Expand Down
Loading

0 comments on commit fcee646

Please sign in to comment.