Skip to content

FEATURE: Dynamic resource uri host (baseUri) for CLI #3334

Open
@mhsdesign

Description

@mhsdesign

Building a resource uri with the default configuration will crash on CLI:

No base URI could be provided.
This probably means a call was made outside of an HTTP request and a base
URI was neither configured nor specified as $fallbackRequest.

The entry point ResourceManager::getPublicPackageResourceUri
calls TargetInterface::getPublicStaticResourceUri
which will use the configured target like localWebDirectoryStaticResourcesTarget
which in case of the FileSystemTarget and FileSystemSymlinkTarget
will call the BaseUriProvider::getConfiguredBaseUriOrFallbackToCurrentRequest
which uses $bootstrap->getActiveRequestHandler->getHttpRequest which is not possible on CLI.

Possible workarounds include:

To actually fix this issue we should pass the current base uri to the target:

interface TargetInterface
{
    public function getPublicStaticResourceUri(string $relativePathAndFilename, UriInterface $baseUri): string;

    public function getPublicPersistentResourceUri(PersistentResource $resource, UriInterface $baseUri): string;
    
    // ...
}

The methods are currently only used by the resource manager Neos & Flow.
And there we could allow a backwards compatible nullable parameter which will default to the current request:

class ResourceManager
{
    public function getPublicPackageResourceUri(string $packageKey, string $relativePathAndFilename, ?UriInterface $baseUri = null): string
    {
        $baseUri ??= $this->generateBaseUriFromHttpRequest();
        // ...
    }

    public function getPublicPersistentResourceUri(PersistentResource $resource, ?UriInterface $baseUri = null)
    {
        $baseUri ??= $this->generateBaseUriFromHttpRequest();
        // ...
    }

    private function generateBaseUriFromHttpRequest(): ?UriInterface
    {
        // copied from the base uri provider without `Neos.Flow.http.baseUri` support
        $activeRequestHandler = $this->bootstrap->getActiveRequestHandler();
        if (!$activeRequestHandler instanceof HttpRequestHandlerInterface) {
            return new Uri();
        }
        $request = $activeRequestHandler->getHttpRequest();
        return RequestInformationHelper::generateBaseUri($request);
    }
}

(i left out the demonstration for ResourceManager::getPublicPersistentResourceUriByHash as its unused)

Meaning the resource manager can be used with fixed base uris

$this->resourceManager->getPublicPersistentResourceUri($resource, new Uri('http://localhost'));

or when leaving this parameter out, the previous default behaviour is used:

$this->resourceManager->getPublicPersistentResourceUri($resource);

a little more breaking would be do always enforce to specify the baseUri which would definitely be correct.

In Fusion we could start inside our prototypes to call getPublicPersistentResourceUri with the base uri of the current
request and thus make the life a little easier ;)

Alternative fixes

  1. Add a context switcher like BaseUriProvider::applyBaseUriToClosure($newBaseUri, fn () => $resourcemanger->...(...))
  2. Add an environment variable like FLOW_BASE_URI see FEATURE: Make base URI configuration obsolete #3002
    • (like option 1 but less hacky to the eye, as it could be specified from outside flow ^^)
  3. Use empty base uri (host relative) and dont crash BUGFIX: Prevent getPublicStaticResourceUri from crashing in cli con… #3314

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions