phpsymfonyproxysymfony-http-foundationsymfony-http-client

How to forward a Symfony Request to another server using the Http Client (with optional changes)?


How to intercept a request and send it with HttpClient to another server and return the response from that server after some modification?

The original request will contain data and files. I am looking for the least verbose solution, up to copying the original raw body as a string. The part I am stuck with is plugging the Request object to the HttpClient request in the shortest way (without writing code to copy data and headers bit by bit), the rest (handling the response) I will manage.


Solution

  • Symfony's Http Client does not accept an HttpFoundation\Request as a parameter to make new requests.

    You'll need to convert the Request object into the necessary parameters (including converting the path, method, passing appropriate headers, etc) "manually".

    Then, you'd have to create the an HttpFoundation\Response based on the client's response (which, again, cannot simply be sent back in your controller).

    Depending on your specific requirements, it's not particularly onerous. A naive, probably buggy implementation would be something like:

    use Symfony\Component\HttpFoundation;
    use Symfony\Contracts\HttpClient\HttpClientInterface;
    
    class FooProxy
    {
        public function __construct(private HttpClientInterface $client)
        {
        }
    
        public function __invoke(HttpFoundation\Request $request): HttpFoundation\Response
        {
            $options            = [];
            $newServer          = 'https://www.example.com';
            $options['headers'] = $request->headers->all();
            $options['body']    = $request->getContent();
    
            $clientResponse = $this->client->request(
                $request->getMethod(),
                $newServer . $request->getRequestUri(),
                $options
            );
    
            return new HttpFoundation\Response(
                $clientResponse->getContent(false),
                $clientResponse->getStatusCode(),
                $clientResponse->getHeaders(false)
            );
    
        }
    }
    

    Again, this is very naive implementation. You'd need to make sure that you deal with any exceptions and edge cases. Use it as a starting point, and build according to your needs.

    Take into account that PHP is not a great choice of language to build a real HTTP proxy.