Improve logging on Malformed URI errors.

This commit is contained in:
Buster "Silver Eagle" Neece 2022-06-14 15:18:17 -05:00
parent 0ac9405256
commit 910b8161a2
No known key found for this signature in database
GPG Key ID: F1D2E64A0005E80E
12 changed files with 126 additions and 29 deletions

View File

@ -10,9 +10,9 @@ use App\Http\Factory\ResponseFactory;
use App\Http\Factory\ServerRequestFactory;
use DI;
use Monolog\ErrorHandler;
use Monolog\Logger;
use Monolog\Registry;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Log\LoggerInterface;
use Slim\App;
use Slim\Factory\ServerRequestCreatorFactory;
use Slim\Handlers\Strategies\RequestResponseNamedArgs;
@ -102,7 +102,7 @@ class AppFactory
$di = $containerBuilder->build();
// Monolog setup
$logger = $di->get(LoggerInterface::class);
$logger = $di->get(Logger::class);
$errorHandler = new ErrorHandler($logger);
$errorHandler->registerFatalHandler();

View File

@ -9,10 +9,10 @@ use App\Doctrine\Repository;
use App\Entity;
use App\Service\DeviceDetector;
use App\Service\IpGeolocation;
use App\Utilities\Logger;
use Carbon\CarbonImmutable;
use DateTimeInterface;
use Doctrine\DBAL\Connection;
use Monolog\Registry;
use NowPlaying\Result\Client;
use Throwable;
@ -185,7 +185,7 @@ final class ListenerRepository extends Repository
$record['device_browser_family'] = $this->truncateNullableString($browserResult->browserFamily, 150);
$record['device_os_family'] = $this->truncateNullableString($browserResult->osFamily, 150);
} catch (Throwable $e) {
Registry::getInstance('app')->error('Device Detector error: ' . $e->getMessage(), [
Logger::getInstance()->error('Device Detector error: ' . $e->getMessage(), [
'user_agent' => $userAgent,
'exception' => $e,
]);
@ -208,7 +208,7 @@ final class ListenerRepository extends Repository
$record['location_lat'] = $ipInfo->lat;
$record['location_lon'] = $ipInfo->lon;
} catch (Throwable $e) {
Registry::getInstance('app')->error('IP Geolocation error: ' . $e->getMessage(), [
Logger::getInstance()->error('IP Geolocation error: ' . $e->getMessage(), [
'ip' => $ip,
'exception' => $e,
]);

View File

@ -13,11 +13,11 @@ use App\Media\AlbumArt;
use App\Media\MetadataManager;
use App\Media\RemoteAlbumArt;
use App\Service\AudioWaveform;
use App\Utilities\Logger;
use Azura\Files\ExtendedFilesystemInterface;
use Exception;
use Generator;
use League\Flysystem\FilesystemException;
use Monolog\Registry;
use const JSON_PRETTY_PRINT;
use const JSON_THROW_ON_ERROR;
@ -292,7 +292,7 @@ final class StationMediaRepository extends Repository
try {
$this->writeAlbumArt($media, $artwork, $fs);
} catch (Exception $exception) {
Registry::getInstance('app')->error(
Logger::getInstance()->error(
sprintf(
'Album Artwork for "%s" could not be processed: "%s"',
$filePath,

View File

@ -76,18 +76,25 @@ class Settings implements Stringable
public function getBaseUrlAsUri(): ?UriInterface
{
return Urls::getUri($this->base_url);
return Urls::tryParseUserUrl(
$this->base_url,
'System Base URL',
);
}
public function setBaseUrl(?string $baseUrl): void
{
if (null === $baseUrl) {
if (empty($baseUrl)) {
$this->base_url = null;
return;
}
// Filter the base URL to avoid trailing slashes and other problems.
$baseUri = new Uri($baseUrl);
$baseUri = Urls::parseUserUrl(
$baseUrl,
'System Base URL'
);
if ('' === $baseUri->getScheme()) {
$baseUri = $baseUri->withScheme('http');
}
@ -375,7 +382,10 @@ class Settings implements Stringable
public function getHomepageRedirectUrlAsUri(): ?UriInterface
{
return Urls::getUri($this->homepage_redirect_url);
return Urls::tryParseUserUrl(
$this->homepage_redirect_url,
'Homepage Redirect URL',
);
}
public function setHomepageRedirectUrl(?string $homepageRedirectUrl): void
@ -397,7 +407,10 @@ class Settings implements Stringable
public function getDefaultAlbumArtUrlAsUri(): ?UriInterface
{
return Urls::getUri($this->default_album_art_url);
return Urls::tryParseUserUrl(
$this->default_album_art_url,
'Default Album Art URL',
);
}
public function setDefaultAlbumArtUrl(?string $defaultAlbumArtUrl): void

View File

@ -921,7 +921,10 @@ class Station implements Stringable, IdentifiableEntityInterface
public function getDefaultAlbumArtUrlAsUri(): ?UriInterface
{
return Urls::getUri($this->default_album_art_url);
return Urls::tryParseUserUrl(
$this->default_album_art_url,
'Station ' . $this->__toString() . ' Default Album Art URL'
);
}
/**

View File

@ -240,7 +240,10 @@ class StationMount implements
public function getRelayUrlAsUri(): ?UriInterface
{
return Urls::getUri($this->relay_url);
return Urls::tryParseUserUrl(
$this->relay_url,
'Mount Point ' . $this->__toString() . ' Relay URL'
);
}
public function setRelayUrl(?string $relay_url = null): void
@ -312,7 +315,10 @@ class StationMount implements
public function getCustomListenUrlAsUri(): ?UriInterface
{
return Urls::getUri($this->custom_listen_url);
return Urls::tryParseUserUrl(
$this->custom_listen_url,
'Mount Point ' . $this->__toString() . ' Listen URL'
);
}
public function setCustomListenUrl(?string $custom_listen_url = null): void

View File

@ -11,7 +11,6 @@ use App\Radio\Enums\StreamProtocols;
use App\Radio\Remote\AbstractRemote;
use App\Utilities;
use Doctrine\ORM\Mapping as ORM;
use GuzzleHttp\Psr7\Uri;
use InvalidArgumentException;
use Psr\Http\Message\UriInterface;
use Stringable;
@ -297,17 +296,24 @@ class StationRemote implements
public function getUrlAsUri(): UriInterface
{
return new Uri($this->url);
return Utilities\Urls::parseUserUrl(
$this->url,
'Remote Relay ' . $this->__toString() . ' URL'
);
}
public function setUrl(string $url): void
{
if (!empty($url) && !str_starts_with($url, 'http')) {
/** @noinspection HttpUrlsUsage */
$url = 'http://' . $url;
}
if (empty($url)) {
$this->url = '';
} else {
$uri = Utilities\Urls::parseUserUrl(
$url,
'Remote Relay URL'
);
$this->url = $this->truncateString($url);
$this->url = $this->truncateString((string)$uri);
}
}
/*

View File

@ -71,7 +71,10 @@ class Api
$origins = [];
foreach ($rawOrigins as $rawOrigin) {
$uri = Urls::getUri($rawOrigin);
$uri = Urls::tryParseUserUrl(
$rawOrigin,
'System Setting Access-Control-Allowo-Origin'
);
if (null !== $uri) {
if (empty($uri->getScheme())) {
$origins[] = (string)($uri->withScheme('http'));

View File

@ -109,10 +109,8 @@ class Icecast extends AbstractFrontend
$frontendConfig = $station->getFrontendConfig();
$configDir = $station->getRadioConfigDir();
$settings = $this->settingsRepo->readSettings();
$settingsBaseUrl = $settings->getBaseUrl() ?: '';
$baseUrl = Utilities\Urls::getUri($settingsBaseUrl) ?? new Uri('http://localhost');
$settingsBaseUrl = $this->settingsRepo->readSettings()->getBaseUrlAsUri();
$baseUrl = $settingsBaseUrl ?? new Uri('http://localhost');
[$certPath, $certKey] = Acme::getCertificatePaths();

16
src/Utilities/Logger.php Normal file
View File

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace App\Utilities;
use Monolog\Logger as MonologLogger;
use Monolog\Registry;
final class Logger
{
public static function getInstance(): MonologLogger
{
return Registry::getInstance('app');
}
}

View File

@ -28,4 +28,52 @@ class Urls
return null;
}
public static function parseUserUrl(
?string $url,
string $context
): UriInterface {
try {
if (empty($url)) {
throw new \LogicException('No URL specified.');
}
$url = trim($url);
try {
return new Uri($url);
} catch (MalformedUriException $ex) {
if (!str_starts_with($url, 'http')) {
/** @noinspection HttpUrlsUsage */
return new Uri('http://' . $url);
}
throw $ex;
}
} catch (\Exception $e) {
throw new \LogicException(
message: sprintf('Could not parse %s URL "%s": %s', $context, $url, $e->getMessage()),
previous: $e
);
}
}
public static function tryParseUserUrl(
?string $url,
string $context
): ?UriInterface {
if (empty($url)) {
return null;
}
try {
return self::parseUserUrl($url, $context);
} catch (\Exception $e) {
Logger::getInstance()->error(
sprintf('Could not parse %s URL "%s": %s', $context, $url, $e->getMessage()),
[
'exception' => $e,
]
);
return null;
}
}
}

View File

@ -7,10 +7,10 @@ namespace App\Webhook\Connector;
use App\Entity;
use App\Http\RouterInterface;
use App\Radio\Adapters;
use App\Utilities\Urls;
use Doctrine\ORM\EntityManagerInterface;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\TransferException;
use GuzzleHttp\Psr7\Uri;
use Monolog\Logger;
use Psr\Http\Message\UriInterface;
@ -67,7 +67,11 @@ class MatomoAnalytics extends AbstractConnector
}
// Build Matomo URI
$apiUrl = (new Uri($config['matomo_url']))->withPath('/matomo.php');
$apiUrl = Urls::parseUserUrl(
$config['matomo_url'],
'Matomo Analytics URL',
)->withPath('/matomo.php');
$apiToken = $config['token'] ?? null;
$stationName = $station->getName();