Slim-Psr7
Slim-Psr7 copied to clipboard
Construction of Uri via UriFactory fails for non-HTTP-related URIs
URIs are universal. I assumed that the implementation of Uri
object would be too.
TLDR; The following snippet produces InvalidArgumentException: Uri scheme must be one of: "", "http", "https"
exception because of scheme filtering in Uri::filterScheme
.
use Slim\Psr7\Factory\UriFactory;
(new UriFactory())->createUri('smtp://smtp.dakujem.dev:25');
Reasoning
I tried using Slim/Psr7 for handling generic URIs that I'm using for DSN-style configuration variables.
There are plenty of valid schemes, so setting Uri::SUPPORTED_SCHEMES
is impractical for this purpose.
Now, Guzzle handles this correctly, as does the native parse_url
function.
use GuzzleHttp\Psr7\Uri;
use Slim\Psr7\Factory\UriFactory;
$uri = 'smtp://smtp.dakujem.dev:25';
// tel:+1-816-555-1212
// ftp://ftp.is.co.za/rfc/rfc1808.txt
// ldap://[2001:db8::7]/c=GB?objectClass?one
(string)(new Uri($uri));
// InvalidArgumentException: Uri scheme must be one of: "", "http", "https"
(string)(new UriFactory())->createUri($uri); // exception here
Suggested solution
I suggest using opt-in approach: keep Slim/Psr7 universal and activate the filter when booting Slim framework.
public const SUPPORTED_SCHEMES = null; // initialize the class constant with null
// within filterScheme method
if (static::SUPPORTED_SCHEMES !== null && !key_exists($scheme, static::SUPPORTED_SCHEMES)) {
throw new InvalidArgumentException( ... );
}
// and somewhere in Slim bootstrapping phase
Uri::SUPPORTED_SCHEMES = ['', 'http', 'https'];
I believe you get the idea.
This might be related to other parts of the Uri object, in particular the other
filter*
methods.