- Add Metered and ConvexSol (CoTURN) provider drivers with response validation and caching - Add IceCandidateManager with automatic failover and structured logging - Add IceCandidateProviderInterface and DTOs conforming to RTCIceServer format
69 lines
2.4 KiB
PHP
69 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\IceCandidate\Validators;
|
|
|
|
use RuntimeException;
|
|
|
|
class IceResponseValidator
|
|
{
|
|
/**
|
|
* Validate raw API response payload and normalize into an array of server definitions.
|
|
*
|
|
* @return array<array>
|
|
*
|
|
* @throws RuntimeException
|
|
*/
|
|
public static function validate(mixed $data, string $providerName = 'ICE Provider'): array
|
|
{
|
|
if (! is_array($data)) {
|
|
throw new RuntimeException("{$providerName} API returned an invalid non-array response.");
|
|
}
|
|
|
|
// Support wrapped responses like ['iceServers' => [...]] or ['v' => [...]]
|
|
$servers = isset($data['iceServers']) && is_array($data['iceServers'])
|
|
? $data['iceServers']
|
|
: (isset($data['v']) && is_array($data['v']) ? $data['v'] : $data);
|
|
|
|
if (empty($servers) || ! is_array($servers)) {
|
|
throw new RuntimeException("{$providerName} API returned an empty or invalid list of ICE servers.");
|
|
}
|
|
|
|
$validServers = [];
|
|
$validProtocols = ['stun:', 'stuns:', 'turn:', 'turns:'];
|
|
|
|
foreach ($servers as $index => $server) {
|
|
if (! is_array($server)) {
|
|
throw new RuntimeException("{$providerName} server entry at index [{$index}] must be an object/array.");
|
|
}
|
|
|
|
$rawUrls = $server['urls'] ?? $server['url'] ?? null;
|
|
if (empty($rawUrls)) {
|
|
throw new RuntimeException("{$providerName} server entry at index [{$index}] is missing 'urls'.");
|
|
}
|
|
|
|
$urlList = is_array($rawUrls) ? $rawUrls : [$rawUrls];
|
|
foreach ($urlList as $url) {
|
|
if (! is_string($url) || trim($url) === '') {
|
|
throw new RuntimeException("{$providerName} URL at index [{$index}] must be a non-empty string.");
|
|
}
|
|
|
|
$hasValidProtocol = false;
|
|
foreach ($validProtocols as $protocol) {
|
|
if (str_starts_with(strtolower(trim($url)), $protocol)) {
|
|
$hasValidProtocol = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (! $hasValidProtocol) {
|
|
throw new RuntimeException("{$providerName} invalid ICE URL scheme [{$url}] at index [{$index}].");
|
|
}
|
|
}
|
|
|
|
$validServers[] = $server;
|
|
}
|
|
|
|
return $validServers;
|
|
}
|
|
}
|