diff --git a/nima/http/encoding/encoding/pom.xml b/nima/http/encoding/encoding/pom.xml
index ab933198509..fd26e3721f7 100644
--- a/nima/http/encoding/encoding/pom.xml
+++ b/nima/http/encoding/encoding/pom.xml
@@ -1,6 +1,6 @@
+
+ helidon-nima-http-encoding-gzip
+ io.helidon.nima.http.encoding
+ test
+
org.junit.jupiter
junit-jupiter-api
diff --git a/nima/webserver/webserver/src/main/java/io/helidon/nima/webserver/WebServer.java b/nima/webserver/webserver/src/main/java/io/helidon/nima/webserver/WebServer.java
index fdc69a22053..47349aeb1a6 100644
--- a/nima/webserver/webserver/src/main/java/io/helidon/nima/webserver/WebServer.java
+++ b/nima/webserver/webserver/src/main/java/io/helidon/nima/webserver/WebServer.java
@@ -250,9 +250,12 @@ public Builder config(Config config) {
connConfig.get("tcp-no-delay").asBoolean().ifPresent(socketOptionsBuilder::tcpNoDelay);
});
});
+ // Configure content encoding
+ config.get("content-encoding")
+ .as(ContentEncodingContext::create)
+ .ifPresent(this::contentEncodingContext);
// Store providers config node for later usage.
providersConfig = config.get("connection-providers");
-
return this;
}
@@ -503,6 +506,7 @@ Map routers() {
}
List connectionProviders() {
+ providersConfig.get("discover-services").asBoolean().ifPresent(connectionProviders::useSystemServiceLoader);
List providers = connectionProviders.build().asList();
// Send configuration nodes to providers
return providers.stream()
diff --git a/nima/webserver/webserver/src/main/java/io/helidon/nima/webserver/http1/Http1Connection.java b/nima/webserver/webserver/src/main/java/io/helidon/nima/webserver/http1/Http1Connection.java
index 48003ab8848..666d411cb0d 100644
--- a/nima/webserver/webserver/src/main/java/io/helidon/nima/webserver/http1/Http1Connection.java
+++ b/nima/webserver/webserver/src/main/java/io/helidon/nima/webserver/http1/Http1Connection.java
@@ -68,8 +68,7 @@ public class Http1Connection implements ServerConnection, InterruptableTask providers = wsBuilder.connectionProviders();
+ // Providers shall be loaded with ServiceLoader.
+ assertThat(providers, notNullValue());
+ assertThat(providers, is(not(empty())));
+ }
+
+ @Test
+ void testConnectionProvidersDisabled() {
+ // This will pick up application.yaml from the classpath as default configuration file
+ Config config = Config.create();
+ WebServer.Builder wsBuilder = WebServer.builder().config(config.get("server2"));
+ List providers = wsBuilder.connectionProviders();
+ // No providers shall be loaded with ServiceLoader disabled for connection providers.
+ assertThat(providers, notNullValue());
+ assertThat(providers, is(empty()));
+ }
+
+ // Check that WebServer ContentEncodingContext is disabled when disable is present in config
+ @Test
+ void testContentEncodingConfig() {
+ // This will pick up application.yaml from the classpath as default configuration file
+ Config config = Config.create();
+ WebServer.Builder wsBuilder = WebServer.builder().config(config.get("server"));
+ ContentEncodingContext contentEncodingContext = wsBuilder.contentEncodingContext();
+ assertThat(contentEncodingContext.contentEncodingEnabled(), is(true));
+ assertThat(contentEncodingContext.contentDecodingEnabled(), is(true));
+ failsWith(() -> contentEncodingContext.decoder("gzip"), NoSuchElementException.class);
+ failsWith(() -> contentEncodingContext.decoder("gzip"), NoSuchElementException.class);
+ failsWith(() -> contentEncodingContext.encoder("gzip"), NoSuchElementException.class);
+ failsWith(() -> contentEncodingContext.decoder("x-gzip"), NoSuchElementException.class);
+ failsWith(() -> contentEncodingContext.encoder("x-gzip"), NoSuchElementException.class);
+ }
+
+ // Verify that provided task throws an exception
+ private static void failsWith(Runnable task, Class extends Exception> exception) {
+ try {
+ task.run();
+ // Fail the test when no Exception was thrown
+ fail(String.format("Exception %s was not thrown", exception.getName()));
+ } catch (Exception ex) {
+ if (!exception.isAssignableFrom(ex.getClass())) {
+ throw ex;
+ }
+ }
+ }
+
+}
diff --git a/nima/webserver/webserver/src/test/java/io/helidon/nima/webserver/http1/ConnectionConfigTest.java b/nima/webserver/webserver/src/test/java/io/helidon/nima/webserver/http1/ConnectionConfigTest.java
index 63fee771eb3..90580b7440d 100644
--- a/nima/webserver/webserver/src/test/java/io/helidon/nima/webserver/http1/ConnectionConfigTest.java
+++ b/nima/webserver/webserver/src/test/java/io/helidon/nima/webserver/http1/ConnectionConfigTest.java
@@ -16,187 +16,61 @@
package io.helidon.nima.webserver.http1;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.List;
-import java.util.concurrent.ExecutorService;
+import java.util.function.Function;
+
+import org.junit.jupiter.api.Test;
-import io.helidon.common.buffers.BufferData;
-import io.helidon.common.buffers.DataReader;
-import io.helidon.common.buffers.DataWriter;
-import io.helidon.common.socket.HelidonSocket;
-import io.helidon.common.socket.PeerInfo;
import io.helidon.config.Config;
-import io.helidon.nima.webserver.ConnectionContext;
-import io.helidon.nima.webserver.Router;
-import io.helidon.nima.webserver.Routing;
-import io.helidon.nima.webserver.spi.ServerConnectionSelector;
-import io.helidon.nima.webserver.ServerContext;
import io.helidon.nima.webserver.WebServer;
-import io.helidon.nima.webserver.http.DirectHandlers;
-
-import org.junit.jupiter.api.Test;
+import io.helidon.nima.webserver.spi.ServerConnectionProvider;
+import io.helidon.nima.webserver.spi.ServerConnectionSelector;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
public class ConnectionConfigTest {
- // ConnectionContext mockup
- private static class TestContext implements ConnectionContext {
-
- @Override
- public PeerInfo remotePeer() {
- return null;
- }
-
- @Override
- public PeerInfo localPeer() {
- return null;
- }
+ @Test
+ void testConnectionConfig() {
+ // This will pick up application.yaml from the classpath as default configuration file
+ Config config = Config.create();
+ TestProvider provider = new TestProvider();
+ WebServer.builder().config(config.get("server")).addConnectionProvider(provider).build();
+ assertThat(provider.isConfig(), is(true));
+ Http1Config http1Config = provider.config();
+ assertThat(http1Config.maxPrologueLength(), is(4096));
+ assertThat(http1Config.maxHeadersSize(), is(8192));
+ assertThat(http1Config.validatePath(), is(false));
+ assertThat(http1Config.validateHeaders(), is(false));
+ }
- @Override
- public boolean isSecure() {
- return false;
- }
+ private static class TestProvider implements ServerConnectionProvider {
- @Override
- public String socketId() {
- return null;
- }
+ private Http1Config http1Config = null;
+ private Config config = null;
@Override
- public String childSocketId() {
- return null;
+ public Iterable configKeys() {
+ return List.of("http_1_1");
}
@Override
- public ServerContext serverContext() {
- return null;
+ public ServerConnectionSelector create(Function configs) {
+ config = configs.apply("http_1_1");
+ http1Config = DefaultHttp1Config.toBuilder(config).build();
+ return mock(ServerConnectionSelector.class);
}
- @Override
- public ExecutorService sharedExecutor() {
- return null;
+ private Http1Config config() {
+ return http1Config;
}
- @Override
- public DataWriter dataWriter() {
- return null;
+ private boolean isConfig() {
+ return http1Config != null;
}
- @Override
- public DataReader dataReader() {
- return new DataReader(new HelidonSocket() {
- @Override
- public void close() {
- }
-
- @Override
- public int read(BufferData buffer) {
- return 0;
- }
-
- @Override
- public void write(BufferData buffer) {
- }
-
- @Override
- public PeerInfo remotePeer() {
- return null;
- }
-
- @Override
- public PeerInfo localPeer() {
- return null;
- }
-
- @Override
- public boolean isSecure() {
- return false;
- }
-
- @Override
- public String socketId() {
- return null;
- }
-
- @Override
- public String childSocketId() {
- return null;
- }
-
- @Override
- public byte[] get() {
- return new byte[0];
- }
- });
- }
-
- @Override
- public Router router() {
- return new Router() {
- @Override
- public T routing(Class routingType, T defaultValue) {
- return null;
- }
-
- @Override
- public void afterStop() {
- }
-
- @Override
- public void beforeStart() {
- }
- };
- }
-
- @Override
- public long maxPayloadSize() {
- return 0;
- }
-
- @Override
- public DirectHandlers directHandlers() {
- return null;
- }
-
- }
-
- @Test
- void testConnectionConfig()
- throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
-
- // This will pick up application.yaml from the classpath as default configuration file
- Config config = Config.create();
-
- // Builds LoomServer instance including connectionProviders list.
- WebServer.Builder wsBuilder = WebServer.builder()
- .config(config.get("server"));
-
- // Call wsBuilder.connectionProviders() trough reflection
- Method connectionProviders
- = WebServer.Builder.class.getDeclaredMethod("connectionProviders", (Class>[]) null);
- connectionProviders.setAccessible(true);
- @SuppressWarnings("unchecked")
- List providers
- = (List) connectionProviders.invoke(wsBuilder, (Object[]) null);
-
- // Check whether at least one Http2ConnectionProvider was found
- boolean haveHttp1Provider = false;
-
- for (ServerConnectionSelector provider : providers) {
- if (provider instanceof Http1ConnectionSelector) {
- haveHttp1Provider = true;
- Http1Connection conn = (Http1Connection) provider.connection(new TestContext());
- // Verify values to be updated from configuration file
- assertThat(conn.config().maxPrologueLength(), is(4096));
- assertThat(conn.config().maxHeadersSize(), is(8192));
- assertThat(conn.config().validatePath(), is(false));
- assertThat(conn.config().validateHeaders(), is(false));
- }
- }
- assertThat("No Http12ConnectionProvider was found", haveHttp1Provider, is(true));
}
}
diff --git a/nima/webserver/webserver/src/test/resources/application.yaml b/nima/webserver/webserver/src/test/resources/application.yaml
index 366919bc37f..02025644349 100644
--- a/nima/webserver/webserver/src/test/resources/application.yaml
+++ b/nima/webserver/webserver/src/test/resources/application.yaml
@@ -24,3 +24,13 @@ server:
max-headers-size: 8192
validate-headers: false
validate-path: false
+
+ content-encoding:
+ discover-services: false
+
+server2:
+ port: 8079
+ host: 127.0.0.1
+
+ connection-providers:
+ discover-services: false
diff --git a/nima/websocket/webserver/pom.xml b/nima/websocket/webserver/pom.xml
index c1e5b19ead6..1d9b18b0c3e 100644
--- a/nima/websocket/webserver/pom.xml
+++ b/nima/websocket/webserver/pom.xml
@@ -56,6 +56,11 @@
junit-jupiter-api
test
+
+ mockito-core
+ org.mockito
+ test
+
org.hamcrest
hamcrest-all
diff --git a/nima/websocket/webserver/src/test/java/io/helidon/nima/websocket/webserver/WsUpgradeProviderConfigTest.java b/nima/websocket/webserver/src/test/java/io/helidon/nima/websocket/webserver/WsUpgradeProviderConfigTest.java
index 06447de699a..535739934ef 100644
--- a/nima/websocket/webserver/src/test/java/io/helidon/nima/websocket/webserver/WsUpgradeProviderConfigTest.java
+++ b/nima/websocket/webserver/src/test/java/io/helidon/nima/websocket/webserver/WsUpgradeProviderConfigTest.java
@@ -22,109 +22,28 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ExecutorService;
+
+import org.junit.jupiter.api.Test;
import io.helidon.common.buffers.DataReader;
-import io.helidon.common.buffers.DataWriter;
-import io.helidon.common.socket.PeerInfo;
import io.helidon.config.Config;
import io.helidon.nima.webserver.ConnectionContext;
import io.helidon.nima.webserver.Router;
-import io.helidon.nima.webserver.Routing;
-import io.helidon.nima.webserver.spi.ServerConnectionSelector;
import io.helidon.nima.webserver.ServerContext;
import io.helidon.nima.webserver.WebServer;
-import io.helidon.nima.webserver.http.DirectHandlers;
import io.helidon.nima.webserver.http1.Http1Connection;
import io.helidon.nima.webserver.http1.Http1ConnectionSelector;
import io.helidon.nima.webserver.http1.spi.Http1Upgrader;
-
-import org.junit.jupiter.api.Test;
+import io.helidon.nima.webserver.spi.ServerConnectionSelector;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class WsUpgradeProviderConfigTest {
- // ConnectionContext mockup
- private static class TestContext implements ConnectionContext {
-
- @Override
- public PeerInfo remotePeer() {
- return null;
- }
-
- @Override
- public PeerInfo localPeer() {
- return null;
- }
-
- @Override
- public boolean isSecure() {
- return false;
- }
-
- @Override
- public String socketId() {
- return null;
- }
-
- @Override
- public String childSocketId() {
- return null;
- }
-
- @Override
- public ServerContext serverContext() {
- return null;
- }
-
- @Override
- public ExecutorService sharedExecutor() {
- return null;
- }
-
- @Override
- public DataWriter dataWriter() {
- return null;
- }
-
- @Override
- public DataReader dataReader() {
- return new DataReader(() -> new byte[0]);
- }
-
- @Override
- public Router router() {
- return new Router() {
- @Override
- public T routing(Class routingType, T defaultValue) {
- return null;
- }
-
- @Override
- public void afterStop() {
- }
-
- @Override
- public void beforeStart() {
- }
- };
- }
-
- @Override
- public long maxPayloadSize() {
- return 0;
- }
-
- @Override
- public DirectHandlers directHandlers() {
- return null;
- }
-
- }
-
// Verify that WsUpgrader is properly configured from config file
@Test
void testConnectionConfig()
@@ -147,7 +66,7 @@ void testConnectionConfig()
for (ServerConnectionSelector provider : providers) {
if (provider instanceof Http1ConnectionSelector) {
- Http1Connection conn = (Http1Connection) provider.connection(new TestContext());
+ Http1Connection conn = (Http1Connection) provider.connection(mockContext());
assertThat(conn, notNullValue());
// Retrieve private upgradeProviderMap from Http1Connection trough reflection
@@ -177,4 +96,12 @@ void testUpgraderConfigBuilder() {
assertThat(origins, containsInAnyOrder("bOrigin1", "bOrigin2"));
}
+ private static ConnectionContext mockContext() {
+ ConnectionContext ctx = mock(ConnectionContext.class);
+ when(ctx.dataReader()).thenReturn(mock(DataReader.class));
+ when(ctx.router()).thenReturn(Router.empty());
+ when(ctx.serverContext()).thenReturn(mock(ServerContext.class));
+ return ctx;
+ }
+
}