Skip to content

[HttpKernel] "Deprecation" of StreamedResponseListener causes RequestStack to be empty within StreamedResponse callback #46743

Closed
@DaDeather

Description

@DaDeather

Symfony version(s) affected

6.1.*

Description

The change made within #45476 causes the RequestStack to be empty when the StreamedResponse Callback is being called.

In detail:
When using an StreamedResponse, the Callback passed to StreamedResponse is executed AFTER the \Symfony\Component\HttpKernel\Kernel::handle method (which is doing a pop on the RequestStack in \Symfony\Component\HttpKernel\HttpKernel::finishRequest).

Instead it is executed within the \Symfony\Component\HttpFoundation\Response::send method causing the \Symfony\Component\HttpFoundation\RequestStack to be empty and not having any Request object inside it.

We're upgrading our legacy application which is already wrapped with symfony.
This is why we're sadly have to use a construct where we're required to inject the \Symfony\Component\HttpFoundation\RequestStack to get the Request which is not available anymore at that state within a StreamedResponse.

Is this really the expected / wanted behaviour for this change? That when using a StreamedResponse the Request object becomes unavailable or is required to be reinitialized manually? If this is desired it should be announced as a possible BC break.

How to reproduce

./src/Service/TestService.php

<?php

namespace App\Service;

use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

#[Autoconfigure(public: true)]
class TestService
{
    public function __construct(private readonly RequestStack $requestStack)
    {
    }

    public function getRequest(): Request
    {
        return $this->requestStack->getMainRequest();
    }
}

./src/Controller/TestController.php

<?php

namespace App\Controller;

use App\Kernel;
use App\Service\TestService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Annotation\Route;

#[AsController]
class TestController extends AbstractController
{
    #[Route('/')]
    public function test(Kernel $kernel): StreamedResponse
    {
        return new StreamedResponse(function () use ($kernel) {
            /** @var TestService $testService */
            $testService = $kernel->getContainer()->get(TestService::class);

            $mainRequest = $testService->getRequest();

            echo $mainRequest->server->get('HTTP_HOST');
        });
    }
}

When calling the /test url an exception is thrown:

Return value must be of type Symfony\Component\HttpFoundation\Request, null returned

Possible Solution

No response

Additional Context

Behaviour was changed in pull request: #45476

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions