diff --git a/application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java b/application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java index 3cd1e2a6e3..38f37cf35d 100644 --- a/application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java @@ -17,6 +17,7 @@ package org.thingsboard.server.config; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.WebSocketHandler; @@ -40,11 +41,16 @@ public class WebSocketConfiguration implements WebSocketConfigurer { private final WebSocketHandler wsHandler; + @Value("${server.ws.max_text_message_buffer_size:32768}") + private int maxTextMessageBufferSize; + @Value("${server.ws.max_binary_message_buffer_size:32768}") + private int maxBinaryMessageBufferSize; + @Bean public ServletServerContainerFactoryBean createWebSocketContainer() { ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean(); - container.setMaxTextMessageBufferSize(32768); - container.setMaxBinaryMessageBufferSize(32768); + container.setMaxTextMessageBufferSize(maxTextMessageBufferSize); + container.setMaxBinaryMessageBufferSize(maxBinaryMessageBufferSize); return container; } diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index fc23d050a8..2d1fc1b63f 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -78,6 +78,10 @@ server: max_entities_per_data_subscription: "${TB_SERVER_WS_MAX_ENTITIES_PER_DATA_SUBSCRIPTION:10000}" # Maximum number of alarms returned for single alarm subscription. For example, no more than 10,000 alarms on the alarm widget max_entities_per_alarm_subscription: "${TB_SERVER_WS_MAX_ENTITIES_PER_ALARM_SUBSCRIPTION:10000}" + # Maximum size (bytes) of incoming WS text message + max_text_message_buffer_size: "${TB_SERVER_WS_MAX_TEXT_MESSAGE_BUFFER_SIZE:32768}" + # Maximum size (bytes) of incoming WS binary message + max_binary_message_buffer_size: "${TB_SERVER_WS_MAX_BINARY_MESSAGE_BUFFER_SIZE:32768}" # Maximum queue size of the websocket updates per session. This restriction prevents infinite updates of WS max_queue_messages_per_session: "${TB_SERVER_WS_DEFAULT_QUEUE_MESSAGES_PER_SESSION:1000}" # Maximum time between WS session opening and sending auth command diff --git a/common/util/src/test/java/org/thingsboard/common/util/SsrfProtectionValidatorTest.java b/common/util/src/test/java/org/thingsboard/common/util/SsrfProtectionValidatorTest.java index ec6e51db6d..6cb2d21a9a 100644 --- a/common/util/src/test/java/org/thingsboard/common/util/SsrfProtectionValidatorTest.java +++ b/common/util/src/test/java/org/thingsboard/common/util/SsrfProtectionValidatorTest.java @@ -27,12 +27,9 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatThrownBy; +@ResourceLock("SsrfProtectionValidatorTest") // some tests mutate static additional-blocked-hosts public class SsrfProtectionValidatorTest { - // JUnit 5 @ResourceLock ensures that tests modifying SsrfProtectionValidator's static - // additional blocked hosts never run concurrently with each other (parallel execution is enabled). - private static final String SYNC_LOCK = "SsrfProtectionValidatorTest"; - @ParameterizedTest @ValueSource(strings = { "http://example.com", @@ -207,7 +204,6 @@ public class SsrfProtectionValidatorTest { } @Test - @ResourceLock(SYNC_LOCK) void testAdditionalBlockedSingleIp() { try { SsrfProtectionValidator.setAdditionalBlockedHosts(List.of("8.8.8.8")); @@ -222,7 +218,6 @@ public class SsrfProtectionValidatorTest { } @Test - @ResourceLock(SYNC_LOCK) void testAdditionalBlockedCidrSlash10() { try { // Use 44.0.0.0/10 (not blocked by default) to verify CIDR /10 matching @@ -243,7 +238,6 @@ public class SsrfProtectionValidatorTest { } @Test - @ResourceLock(SYNC_LOCK) void testAdditionalBlockedCidrSlash24() { try { SsrfProtectionValidator.setAdditionalBlockedHosts(List.of("198.51.100.0/24")); @@ -261,7 +255,6 @@ public class SsrfProtectionValidatorTest { } @Test - @ResourceLock(SYNC_LOCK) void testAdditionalBlockedHostnameViaValidateUri() { try { SsrfProtectionValidator.setAdditionalBlockedHosts(List.of("evil.corp")); @@ -275,7 +268,6 @@ public class SsrfProtectionValidatorTest { } @Test - @ResourceLock(SYNC_LOCK) void testAdditionalBlockedHostnameCaseInsensitive() { try { SsrfProtectionValidator.setAdditionalBlockedHosts(List.of("My-Service.Corp")); @@ -289,7 +281,6 @@ public class SsrfProtectionValidatorTest { } @Test - @ResourceLock(SYNC_LOCK) void testSetAdditionalBlockedHostsEmptyAndNull() { // Should not throw SsrfProtectionValidator.setAdditionalBlockedHosts(Collections.emptyList()); @@ -307,7 +298,6 @@ public class SsrfProtectionValidatorTest { } @Test - @ResourceLock(SYNC_LOCK) void testAdditionalBlockedCidrViaValidateUri() { // 203.0.113.0/24 (TEST-NET-3) is not blocked by default URI uri = URI.create("http://203.0.113.1"); @@ -323,7 +313,6 @@ public class SsrfProtectionValidatorTest { } @Test - @ResourceLock(SYNC_LOCK) void testAdditionalBlockedMixedConfig() { try { SsrfProtectionValidator.setAdditionalBlockedHosts(List.of("203.0.113.0/24", "evil.corp", "8.8.8.8"));