diff --git a/openvidu-java-client/pom.xml b/openvidu-java-client/pom.xml
index 81ce7b9b6..d7a40b715 100644
--- a/openvidu-java-client/pom.xml
+++ b/openvidu-java-client/pom.xml
@@ -86,17 +86,17 @@
the same as in the parent pom.xml nonetheless -->
2.0.17
-
- org.junit.jupiter
- junit-jupiter-api
- 5.11.4
- test
-
commons-validator
commons-validator
1.10.0
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.14.1
+ test
+
diff --git a/openvidu-java-client/src/main/java/io/openvidu/java/client/TokenOptions.java b/openvidu-java-client/src/main/java/io/openvidu/java/client/TokenOptions.java
index 253074142..edb050a28 100644
--- a/openvidu-java-client/src/main/java/io/openvidu/java/client/TokenOptions.java
+++ b/openvidu-java-client/src/main/java/io/openvidu/java/client/TokenOptions.java
@@ -24,6 +24,7 @@ import com.google.gson.JsonObject;
* @deprecated Use {@link io.openvidu.java.client.ConnectionProperties
* ConnectionProperties} instead
*/
+@Deprecated
public class TokenOptions {
private OpenViduRole role;
@@ -34,6 +35,7 @@ public class TokenOptions {
* @deprecated Use {@link io.openvidu.java.client.ConnectionProperties.Builder
* ConnectionProperties.Builder} instead
*/
+ @Deprecated
public static class Builder {
private OpenViduRole role = OpenViduRole.PUBLISHER;
diff --git a/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java b/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java
index b2d1bf93a..77ce4b67e 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java
@@ -22,19 +22,16 @@ import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
-import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
-import java.net.URL;
import java.net.UnknownHostException;
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -678,8 +675,9 @@ public class OpenviduConfig {
if (coturnIp == null || this.coturnIp.isEmpty()) {
try {
- this.coturnIp = new URL(this.getFinalUrl()).getHost();
- } catch (MalformedURLException e) {
+ URI finalUri = new URI(this.getFinalUrl());
+ this.coturnIp = finalUri.getHost();
+ } catch (URISyntaxException e) {
log.error("Can't get Domain name from OpenVidu public Url: " + e.getMessage());
}
}
@@ -945,7 +943,8 @@ public class OpenviduConfig {
}
}
- protected Integer asOptionalIntegerBetweenRanges(String property, Range... ranges) {
+ @SafeVarargs
+ protected final Integer asOptionalIntegerBetweenRanges(String property, Range... ranges) {
try {
String value = getValue(property);
if (value == null || value.isEmpty()) {
@@ -1087,12 +1086,17 @@ public class OpenviduConfig {
public URI checkWebsocketUri(String uri) throws Exception {
try {
- if (!StringUtils.startsWithAny(uri, "ws://", "wss://")) {
+ if (!(uri.startsWith("ws://") || uri.startsWith("wss://"))) {
throw new Exception("WebSocket protocol not found");
}
String parsedUri = uri.replaceAll("^ws://", "http://").replaceAll("^wss://", "https://");
- return new URL(parsedUri).toURI();
- } catch (Exception e) {
+ URI parsed = new URI(parsedUri);
+ String scheme = parsed.getScheme();
+ if (!"http".equalsIgnoreCase(scheme) && !"https".equalsIgnoreCase(scheme)) {
+ throw new Exception("Unsupported protocol " + scheme);
+ }
+ return parsed;
+ } catch (URISyntaxException e) {
throw new RuntimeException(
"URI '" + uri + "' has not a valid WebSocket endpoint format: " + e.getMessage());
}
@@ -1100,8 +1104,14 @@ public class OpenviduConfig {
protected void checkUrl(String url) throws Exception {
try {
- new URL(url).toURI();
- } catch (MalformedURLException | URISyntaxException e) {
+ URI uri = new URI(url);
+ if (uri.getScheme() == null || uri.getScheme().isEmpty()) {
+ throw new Exception("Missing URL scheme");
+ }
+ if (uri.getHost() == null || uri.getHost().isEmpty()) {
+ throw new Exception("Missing URL host");
+ }
+ } catch (URISyntaxException e) {
throw new Exception("String '" + url + "' has not a valid URL format: " + e.getMessage());
}
}
@@ -1283,30 +1293,37 @@ public class OpenviduConfig {
if (RecordingLayout.CUSTOM.equals(recordingProperties.recordingLayout())) {
String layout = recordingProperties.customLayout();
if (!layout.isEmpty()) {
+ URI layoutUri = null;
try {
- URL url = new URL(layout);
- log.info("\"customLayout\" property has a URL format ({}). Using it to connect to custom layout",
- url.toString());
- return processCustomLayoutUrlFormat(url, sessionId);
- } catch (MalformedURLException e) {
- String layoutPath = this.getOpenviduRecordingCustomLayout() + layout;
- layoutPath = layoutPath.endsWith("/") ? layoutPath : (layoutPath + "/");
+ layoutUri = new URI(layout);
+ } catch (URISyntaxException e) {
+ layoutUri = null;
+ }
+ boolean layoutIsAbsoluteUrl = layoutUri != null && layoutUri.getScheme() != null
+ && layoutUri.getHost() != null;
+ if (layoutIsAbsoluteUrl) {
log.info(
- "\"customLayout\" property is defined as \"{}\". Using a different custom layout than the default one. Expected path: {}",
- layout, layoutPath + "index.html");
- try {
- final File indexHtml = new File(layoutPath + "index.html");
- if (!indexHtml.exists()) {
- throw new IOException();
- }
- log.info("Custom layout path \"{}\" is valid. Found file {}", layout,
- indexHtml.getAbsolutePath());
- } catch (IOException e1) {
- final String error = "Custom layout path " + layout + " is not valid. Expected file "
- + layoutPath + "index.html to exist and be readable";
- log.error(error);
- throw new OpenViduException(Code.RECORDING_PATH_NOT_VALID, error);
+ "\"customLayout\" property has a URL format ({}). Using it to connect to custom layout",
+ layoutUri.toString());
+ return processCustomLayoutUrlFormat(layoutUri, sessionId);
+ }
+ String layoutPath = this.getOpenviduRecordingCustomLayout() + layout;
+ layoutPath = layoutPath.endsWith("/") ? layoutPath : (layoutPath + "/");
+ log.info(
+ "\"customLayout\" property is defined as \"{}\". Using a different custom layout than the default one. Expected path: {}",
+ layout, layoutPath + "index.html");
+ try {
+ final File indexHtml = new File(layoutPath + "index.html");
+ if (!indexHtml.exists()) {
+ throw new IOException();
}
+ log.info("Custom layout path \"{}\" is valid. Found file {}", layout,
+ indexHtml.getAbsolutePath());
+ } catch (IOException e1) {
+ final String error = "Custom layout path " + layout + " is not valid. Expected file "
+ + layoutPath + "index.html to exist and be readable";
+ log.error(error);
+ throw new OpenViduException(Code.RECORDING_PATH_NOT_VALID, error);
}
}
}
@@ -1340,8 +1357,12 @@ public class OpenviduConfig {
layout = recordingProperties.recordingLayout().name().toLowerCase().replaceAll("_", "-");
int port = startsWithHttp ? 80 : 443;
try {
- port = new URL(this.getFinalUrl()).getPort();
- } catch (MalformedURLException e) {
+ URI finalUri = new URI(this.getFinalUrl());
+ int uriPort = finalUri.getPort();
+ if (uriPort != -1) {
+ port = uriPort;
+ }
+ } catch (URISyntaxException e) {
log.error(e.getMessage());
}
String defaultPathForDefaultLayout = recordingComposedUrlDefined ? ""
@@ -1354,53 +1375,63 @@ public class OpenviduConfig {
return finalUrl;
}
- private String processCustomLayoutUrlFormat(URL url, String shortSessionId) {
- String finalUrl = url.getProtocol() + "://" + url.getAuthority();
- if (!url.getPath().isEmpty()) {
- finalUrl += url.getPath();
+ private String processCustomLayoutUrlFormat(URI url, String shortSessionId) {
+ StringBuilder finalUrl = new StringBuilder();
+ String scheme = url.getScheme();
+ if (scheme != null && !scheme.isEmpty()) {
+ finalUrl.append(scheme).append("://");
}
- finalUrl = finalUrl.endsWith("/") ? finalUrl.substring(0, finalUrl.length() - 1) : finalUrl;
- if (url.getQuery() != null) {
- URI uri;
- try {
- uri = url.toURI();
- finalUrl += "?";
- } catch (URISyntaxException e) {
- String error = "\"customLayout\" property has URL format and query params (" + url.toString()
- + "), but does not comply with RFC2396 URI format";
- log.error(error);
- throw new OpenViduException(Code.RECORDING_PATH_NOT_VALID, error);
- }
- List params = URLEncodedUtils.parse(uri, Charset.forName("UTF-8"));
- Iterator it = params.iterator();
+ String authority = url.getRawAuthority();
+ if (authority != null) {
+ finalUrl.append(authority);
+ }
+ String path = url.getRawPath();
+ if (path != null && !path.isEmpty()) {
+ finalUrl.append(path);
+ }
+ int length = finalUrl.length();
+ if (length > 0 && finalUrl.charAt(length - 1) == '/') {
+ finalUrl.deleteCharAt(length - 1);
+ }
+ String query = url.getRawQuery();
+ if (query != null) {
+ finalUrl.append('?');
+ List params = URLEncodedUtils.parse(url, StandardCharsets.UTF_8);
boolean hasSessionId = false;
boolean hasSecret = false;
- while (it.hasNext()) {
- NameValuePair param = it.next();
- finalUrl += param.getName() + "=" + param.getValue();
- if (it.hasNext()) {
- finalUrl += "&";
+ for (int i = 0; i < params.size(); i++) {
+ NameValuePair param = params.get(i);
+ finalUrl.append(param.getName()).append('=').append(param.getValue());
+ if (i < params.size() - 1) {
+ finalUrl.append('&');
}
- if (!hasSessionId) {
- hasSessionId = param.getName().equals("sessionId");
+ if (!hasSessionId && "sessionId".equals(param.getName())) {
+ hasSessionId = true;
}
- if (!hasSecret) {
- hasSecret = param.getName().equals("secret");
+ if (!hasSecret && "secret".equals(param.getName())) {
+ hasSecret = true;
}
}
+ boolean hasAppendedParams = !params.isEmpty();
if (!hasSessionId) {
- finalUrl += "&sessionId=" + shortSessionId;
+ if (hasAppendedParams) {
+ finalUrl.append('&');
+ }
+ finalUrl.append("sessionId=").append(shortSessionId);
+ hasAppendedParams = true;
}
if (!hasSecret) {
- finalUrl += "&secret=" + this.getOpenViduSecret();
+ if (hasAppendedParams) {
+ finalUrl.append('&');
+ }
+ finalUrl.append("secret=").append(this.getOpenViduSecret());
}
}
-
- if (url.getRef() != null) {
- finalUrl += "#" + url.getRef();
+ String fragment = url.getRawFragment();
+ if (fragment != null) {
+ finalUrl.append('#').append(fragment);
}
-
- return finalUrl;
+ return finalUrl.toString();
}
}
diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/Token.java b/openvidu-server/src/main/java/io/openvidu/server/core/Token.java
index 37aa9b523..52b27f169 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/core/Token.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/core/Token.java
@@ -20,8 +20,6 @@ package io.openvidu.server.core;
import java.net.MalformedURLException;
import java.util.List;
-import org.apache.commons.lang3.RandomStringUtils;
-
import com.google.gson.JsonArray;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
@@ -33,6 +31,7 @@ import io.openvidu.java.client.KurentoOptions;
import io.openvidu.java.client.OpenViduRole;
import io.openvidu.server.core.Participant.ParticipantStatus;
import io.openvidu.server.coturn.TurnCredentials;
+import io.openvidu.server.utils.RandomIdGenerator;
public class Token {
@@ -43,7 +42,7 @@ public class Token {
private TurnCredentials turnCredentials;
private String connectionId = IdentifierPrefixes.PARTICIPANT_PUBLIC_ID
- + RandomStringUtils.randomAlphabetic(1).toUpperCase() + RandomStringUtils.randomAlphanumeric(9);
+ + RandomIdGenerator.alphabetic(1).toUpperCase() + RandomIdGenerator.alphanumeric(9);
public Token(String token, String sessionId, ConnectionProperties connectionProperties,
TurnCredentials turnCredentials) {
diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/TokenGenerator.java b/openvidu-server/src/main/java/io/openvidu/server/core/TokenGenerator.java
index ef615a7b5..c5ed6a3a2 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/core/TokenGenerator.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/core/TokenGenerator.java
@@ -17,7 +17,6 @@
package io.openvidu.server.core;
-import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import io.openvidu.java.client.ConnectionProperties;
@@ -30,6 +29,7 @@ import io.openvidu.server.config.OpenviduBuildInfo;
import io.openvidu.server.config.OpenviduConfig;
import io.openvidu.server.coturn.CoturnCredentialsService;
import io.openvidu.server.coturn.TurnCredentials;
+import io.openvidu.server.utils.RandomIdGenerator;
import java.util.List;
@@ -48,8 +48,8 @@ public class TokenGenerator {
KurentoOptions kurentoOptions, List customIceServers) throws Exception {
String token = OpenViduServer.wsUrl;
token += "?sessionId=" + sessionId;
- token += "&token=" + IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
- + RandomStringUtils.randomAlphanumeric(15);
+ token += "&token=" + IdentifierPrefixes.TOKEN_ID + RandomIdGenerator.alphabetic(1).toUpperCase()
+ + RandomIdGenerator.alphanumeric(15);
TurnCredentials turnCredentials = coturnCredentialsService.createUser();
ConnectionProperties.Builder connectionPropertiesBuilder = new ConnectionProperties.Builder()
.type(ConnectionType.WEBRTC).data(serverMetadata).record(record).role(role)
diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java
index add645eb3..5e84ea282 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoParticipant.java
@@ -27,7 +27,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.function.Function;
-import org.apache.commons.lang3.RandomStringUtils;
import org.kurento.client.Continuation;
import org.kurento.client.Endpoint;
import org.kurento.client.ErrorEvent;
@@ -57,6 +56,7 @@ import io.openvidu.server.kurento.endpoint.MediaEndpoint;
import io.openvidu.server.kurento.endpoint.PublisherEndpoint;
import io.openvidu.server.kurento.endpoint.SubscriberEndpoint;
import io.openvidu.server.recording.service.RecordingManager;
+import io.openvidu.server.utils.RandomIdGenerator;
import io.openvidu.server.utils.RemoteOperationUtils;
public class KurentoParticipant extends Participant {
@@ -436,7 +436,7 @@ public class KurentoParticipant extends Participant {
public String generateStreamId(MediaOptions mediaOptions) {
String type = mediaOptions.hasVideo() ? mediaOptions.getTypeOfVideo() : "MICRO";
return IdentifierPrefixes.STREAM_ID + type.substring(0, Math.min(type.length(), 3)) + "_"
- + RandomStringUtils.randomAlphabetic(1).toUpperCase() + RandomStringUtils.randomAlphanumeric(3) + "_"
+ + RandomIdGenerator.alphabetic(1).toUpperCase() + RandomIdGenerator.alphanumeric(3) + "_"
+ this.getParticipantPublicId();
}
diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java
index 49efaefbe..d979e8219 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java
@@ -30,7 +30,6 @@ import java.util.concurrent.TimeUnit;
import jakarta.annotation.PreDestroy;
-import org.apache.commons.lang3.RandomStringUtils;
import org.kurento.client.GenericMediaElement;
import org.kurento.client.GenericMediaEvent;
import org.kurento.client.IceCandidate;
@@ -77,6 +76,7 @@ import io.openvidu.server.kurento.kms.KmsManager;
import io.openvidu.server.rpc.RpcHandler;
import io.openvidu.server.utils.GeoLocation;
import io.openvidu.server.utils.JsonUtils;
+import io.openvidu.server.utils.RandomIdGenerator;
import io.openvidu.server.utils.RecordingUtils;
import io.openvidu.server.utils.SDPMunging;
@@ -1169,15 +1169,15 @@ public class KurentoSessionManager extends SessionManager {
}
String rtspConnectionId = kMediaOptions.getTypeOfVideo() + "_" + protocol + "_"
- + RandomStringUtils.randomAlphanumeric(4).toUpperCase() + "_" + uri.getHost()
+ + RandomIdGenerator.alphanumeric(4).toUpperCase() + "_" + uri.getHost()
+ (uri.getPort() != -1 ? (":" + uri.getPort()) : "") + uri.getPath();
rtspConnectionId = rtspConnectionId.replace("/", "_").replace("-", "").replace(".", "_").replace(":", "_");
rtspConnectionId = IdentifierPrefixes.IPCAM_ID + rtspConnectionId;
// Store a "fake" participant for the IpCam connection
this.newInsecureParticipant(rtspConnectionId);
- String token = IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
- + RandomStringUtils.randomAlphanumeric(15);
+ String token = IdentifierPrefixes.TOKEN_ID + RandomIdGenerator.alphabetic(1).toUpperCase()
+ + RandomIdGenerator.alphanumeric(15);
this.newTokenForInsecureUser(session, token, connectionProperties, null);
final Token tokenObj = session.consumeToken(token);
diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/Kms.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/Kms.java
index 74825a532..3c42f9aa6 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/Kms.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/Kms.java
@@ -17,8 +17,8 @@
package io.openvidu.server.kurento.kms;
-import java.net.MalformedURLException;
-import java.net.URL;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
@@ -82,13 +82,13 @@ public class Kms {
this.uri = props.getUri();
String parsedUri = uri.replaceAll("^ws://", "http://").replaceAll("^wss://", "https://");
- URL url = null;
try {
- url = new URL(parsedUri);
- } catch (MalformedURLException e) {
+ URI url = new URI(parsedUri);
+ this.ip = url.getHost();
+ } catch (URISyntaxException e) {
log.error(e.getMessage());
+ this.ip = null;
}
- this.ip = url.getHost();
this.loadManager = loadManager;
this.kmsManager = kmsManager;
diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/KmsManager.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/KmsManager.java
index 572c3435b..619e948a9 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/KmsManager.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/KmsManager.java
@@ -32,7 +32,6 @@ import java.util.stream.Collectors;
import jakarta.annotation.PostConstruct;
-import org.apache.commons.lang3.RandomStringUtils;
import org.kurento.client.KurentoClient;
import org.kurento.commons.exception.KurentoException;
import org.kurento.jsonrpc.JsonRpcClientClosedException;
@@ -53,6 +52,7 @@ import io.openvidu.server.core.SessionEventsHandler;
import io.openvidu.server.core.SessionManager;
import io.openvidu.server.kurento.core.KurentoSession;
import io.openvidu.server.utils.MediaNodeManager;
+import io.openvidu.server.utils.RandomIdGenerator;
import io.openvidu.server.utils.RemoteOperationUtils;
import io.openvidu.server.utils.UpdatableTimerTask;
@@ -408,8 +408,8 @@ public abstract class KmsManager {
}
public static String generateKmsId() {
- return IdentifierPrefixes.MEDIA_NODE_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
- + RandomStringUtils.randomAlphanumeric(7);
+ return IdentifierPrefixes.MEDIA_NODE_ID + RandomIdGenerator.alphabetic(1).toUpperCase()
+ + RandomIdGenerator.alphanumeric(7);
}
public void nodeCrashedHandler(Kms kms, boolean mustRemoveMediaNode) {
diff --git a/openvidu-server/src/main/java/io/openvidu/server/recording/RecorderEndpointWrapper.java b/openvidu-server/src/main/java/io/openvidu/server/recording/RecorderEndpointWrapper.java
index 76b7c5240..04259f47c 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/recording/RecorderEndpointWrapper.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/recording/RecorderEndpointWrapper.java
@@ -17,7 +17,6 @@
package io.openvidu.server.recording;
-import org.apache.commons.lang3.StringUtils;
import org.kurento.client.RecorderEndpoint;
import com.google.gson.JsonObject;
@@ -61,8 +60,12 @@ public class RecorderEndpointWrapper {
public RecorderEndpointWrapper(JsonObject json, String fileExtension) {
String nameAux = json.get("name").getAsString();
- // If the name includes the extension, remove it
- this.name = StringUtils.removeEnd(nameAux, fileExtension);
+ // If the name includes the extension, remove it without relying on deprecated helpers
+ if (fileExtension != null && !fileExtension.isEmpty() && nameAux.endsWith(fileExtension)) {
+ this.name = nameAux.substring(0, nameAux.length() - fileExtension.length());
+ } else {
+ this.name = nameAux;
+ }
this.fileExtension = fileExtension;
this.connectionId = json.get("connectionId").getAsString();
this.streamId = json.get("streamId").getAsString();
diff --git a/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java b/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java
index b9f3653ec..a72b2b1ab 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java
@@ -28,7 +28,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;
-import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -70,6 +69,7 @@ import io.openvidu.server.core.Token;
import io.openvidu.server.kurento.core.KurentoMediaOptions;
import io.openvidu.server.recording.Recording;
import io.openvidu.server.recording.service.RecordingManager;
+import io.openvidu.server.utils.RandomIdGenerator;
import io.openvidu.server.utils.RestUtils;
/**
@@ -149,8 +149,8 @@ public class SessionRestController {
}
}
} else {
- sessionId = IdentifierPrefixes.SESSION_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
- + RandomStringUtils.randomAlphanumeric(9);
+ sessionId = IdentifierPrefixes.SESSION_ID + RandomIdGenerator.alphabetic(1).toUpperCase()
+ + RandomIdGenerator.alphanumeric(9);
}
Session sessionNotActive = sessionManager.storeSessionNotActive(sessionId, sessionProperties);
@@ -288,13 +288,13 @@ public class SessionRestController {
HttpStatus.BAD_REQUEST);
}
switch (connectionProperties.getType()) {
- case WEBRTC:
- return this.newWebrtcConnection(session, connectionProperties);
- case IPCAM:
- return this.newIpcamConnection(session, connectionProperties);
- default:
- return SessionRestController.generateErrorResponse("Wrong type parameter",
- "/sessions/" + sessionId + "/connection", HttpStatus.BAD_REQUEST);
+ case WEBRTC:
+ return this.newWebrtcConnection(session, connectionProperties);
+ case IPCAM:
+ return this.newIpcamConnection(session, connectionProperties);
+ default:
+ return SessionRestController.generateErrorResponse("Wrong type parameter",
+ "/sessions/" + sessionId + "/connection", HttpStatus.BAD_REQUEST);
}
}
@@ -652,11 +652,26 @@ public class SessionRestController {
String sessionId;
String type;
- ArrayList to;
+ List to = null;
String data;
try {
sessionId = (String) params.get("session");
- to = (ArrayList) params.get("to");
+ Object toParam = params.get("to");
+ if (toParam instanceof List> rawList) {
+ List target = new ArrayList<>(rawList.size());
+ for (Object element : rawList) {
+ if (element == null) {
+ target.add(null);
+ } else if (element instanceof String stringValue) {
+ target.add(stringValue);
+ } else {
+ throw new ClassCastException("Expected String elements in 'to' parameter");
+ }
+ }
+ to = target;
+ } else if (toParam != null) {
+ throw new ClassCastException("Expected 'to' parameter to be a list");
+ }
type = (String) params.get("type");
data = (String) params.get("data");
} catch (ClassCastException e) {
@@ -814,13 +829,13 @@ public class SessionRestController {
builder = builder.forcedVideoCodec(forcedVideoCodec);
if (forcedVideoCodec == VideoCodec.MEDIA_SERVER_PREFERRED) {
switch (openviduConfig.getMediaServer()) {
- case mediasoup:
- builder = builder.forcedVideoCodecResolved(VideoCodec.NONE);
- break;
- case kurento:
- default:
- builder = builder.forcedVideoCodecResolved(VideoCodec.VP8);
- break;
+ case mediasoup:
+ builder = builder.forcedVideoCodecResolved(VideoCodec.NONE);
+ break;
+ case kurento:
+ default:
+ builder = builder.forcedVideoCodecResolved(VideoCodec.VP8);
+ break;
}
} else {
builder = builder.forcedVideoCodecResolved(forcedVideoCodec);
diff --git a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java
index c3165880b..3a0c3ebf9 100644
--- a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java
+++ b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java
@@ -27,7 +27,6 @@ import java.util.concurrent.ConcurrentMap;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpSession;
-import org.apache.commons.lang3.RandomStringUtils;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.kurento.jsonrpc.DefaultJsonRpcHandler;
import org.kurento.jsonrpc.Session;
@@ -60,6 +59,7 @@ import io.openvidu.server.core.SessionManager;
import io.openvidu.server.core.Token;
import io.openvidu.server.utils.GeoLocation;
import io.openvidu.server.utils.GeoLocationByIp;
+import io.openvidu.server.utils.RandomIdGenerator;
import io.openvidu.server.utils.VersionComparator;
import io.openvidu.server.utils.VersionComparator.VersionMismatchException;
@@ -283,8 +283,8 @@ public class RpcHandler extends DefaultJsonRpcHandler {
sessionManager.newInsecureParticipant(participantPrivateId);
- token = IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
- + RandomStringUtils.randomAlphanumeric(15);
+ token = IdentifierPrefixes.TOKEN_ID + RandomIdGenerator.alphabetic(1).toUpperCase()
+ + RandomIdGenerator.alphanumeric(15);
ConnectionProperties connectionProperties = new ConnectionProperties.Builder().type(ConnectionType.WEBRTC)
.role(OpenViduRole.SUBSCRIBER).build();
diff --git a/openvidu-server/src/main/java/io/openvidu/server/utils/RandomIdGenerator.java b/openvidu-server/src/main/java/io/openvidu/server/utils/RandomIdGenerator.java
new file mode 100644
index 000000000..0c05ca59f
--- /dev/null
+++ b/openvidu-server/src/main/java/io/openvidu/server/utils/RandomIdGenerator.java
@@ -0,0 +1,36 @@
+package io.openvidu.server.utils;
+
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * Utility methods for generating short random identifiers without relying on
+ * deprecated Apache Commons Lang helpers.
+ */
+public final class RandomIdGenerator {
+
+ private static final char[] ALPHABETIC = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
+ private static final char[] ALPHANUMERIC = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
+
+ private RandomIdGenerator() {
+ }
+
+ public static String alphabetic(int length) {
+ return generate(length, ALPHABETIC);
+ }
+
+ public static String alphanumeric(int length) {
+ return generate(length, ALPHANUMERIC);
+ }
+
+ private static String generate(int length, char[] alphabet) {
+ if (length < 0) {
+ throw new IllegalArgumentException("Length must be non-negative");
+ }
+ char[] result = new char[length];
+ ThreadLocalRandom random = ThreadLocalRandom.current();
+ for (int i = 0; i < length; i++) {
+ result[i] = alphabet[random.nextInt(alphabet.length)];
+ }
+ return new String(result);
+ }
+}
diff --git a/openvidu-server/src/test/java/io/openvidu/server/test/integration/OpenViduServerPublicRecordingsSecurityIntegrationTest.java b/openvidu-server/src/test/java/io/openvidu/server/test/integration/OpenViduServerPublicRecordingsSecurityIntegrationTest.java
index c0594fe64..f656a4179 100644
--- a/openvidu-server/src/test/java/io/openvidu/server/test/integration/OpenViduServerPublicRecordingsSecurityIntegrationTest.java
+++ b/openvidu-server/src/test/java/io/openvidu/server/test/integration/OpenViduServerPublicRecordingsSecurityIntegrationTest.java
@@ -32,13 +32,13 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import io.openvidu.server.core.SessionManager;
import io.openvidu.server.recording.service.RecordingManager;
@@ -57,10 +57,10 @@ class OpenViduServerPublicRecordingsSecurityIntegrationTest {
@Autowired
private MockMvc mockMvc;
- @MockBean
+ @MockitoBean
private SessionManager sessionManager;
- @MockBean
+ @MockitoBean
private RecordingManager recordingManager;
@BeforeEach
diff --git a/openvidu-server/src/test/java/io/openvidu/server/test/integration/OpenViduServerSecurityIntegrationTest.java b/openvidu-server/src/test/java/io/openvidu/server/test/integration/OpenViduServerSecurityIntegrationTest.java
index 2cf1f8a9d..023cbf324 100644
--- a/openvidu-server/src/test/java/io/openvidu/server/test/integration/OpenViduServerSecurityIntegrationTest.java
+++ b/openvidu-server/src/test/java/io/openvidu/server/test/integration/OpenViduServerSecurityIntegrationTest.java
@@ -37,7 +37,6 @@ import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
@@ -47,6 +46,7 @@ import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import io.openvidu.server.core.SessionManager;
import io.openvidu.server.recording.service.RecordingManager;
@@ -65,10 +65,10 @@ class OpenViduServerSecurityIntegrationTest {
@Autowired
private MockMvc mockMvc;
- @MockBean
+ @MockitoBean
private SessionManager sessionManager;
- @MockBean
+ @MockitoBean
private RecordingManager recordingManager;
@BeforeEach