Slim-Psr7 icon indicating copy to clipboard operation
Slim-Psr7 copied to clipboard

Construction of Uri via UriFactory fails for non-HTTP-related URIs

Open dakujem opened this issue 1 year ago • 5 comments

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.

dakujem avatar Mar 10 '23 10:03 dakujem