yolenoyer
yolenoyer

Reputation: 9445

How to forward a curl external raw response to a SF Response object?

I need to make a route in a Symfony 3 app (server 1), which has to send a (filtered) request on a server 2, then send back the exact response given by the server 2 (same HTTP status code, headers and body).

With the native curl Php library, you can get the raw response (including headers), by setting the CURLOPT_HEADER option to True.

But the Response object from Symfony HttpFoundation seems to be only configurable by setting separately headers (inside the constructor, or with $response->headers->set()) and body (with $response->setContent(). I didn't find a way to set a raw response (with headers) into the Response object.

Is it possible, or how could it be done otherwise?

Here's my try:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class MyController extends Controller
{
    /**
     * @Route("/get", name="get")
     */
    public function getAction(Request $request)
    {
        // Filter/modify the query string, but keep it quite similar:
        $request->query->remove('some_private_attr');
        $my_query_string = http_build_query($request->query->all());

        // Setup the curl request:
        $curl = curl_init('http://localhost?'.$my_query_string);
        curl_setopt($curl, CURLOPT_HEADER, 1); // Include headers
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // Return data as a string
        curl_setopt($curl, CURLOPT_PORT, 8200);

        // Perform the request, returning the raw response
        // (headers included) as a string:
        $result = curl_exec($curl);

        // Get the response status code:
        $status_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);

        curl_close($curl);

        // Here, how can I pass the raw external response ($result)
        // to a new Response object, without parsing the header
        // and body parts unnecessarily?

        // Of course, the following doesn't send the right headers:
        $response = new Response($result, $status_code);

        return $response;
    }
}

Upvotes: 1

Views: 2035

Answers (2)

chringel21
chringel21

Reputation: 126

I had the exact same issue. I basically wanted to forward the CurlResponse as a Response by the controller.

I implemented this as follows, using the standard Symfony HttpClient:

public function myAction()
    {
        /** @var Request $request */
        $request = $this->container->get('request_stack')->getCurrentRequest();
        $my_query_string = http_build_query($request->query->all());

        $client = HttpClient::create();
        $url = 'http://localhost?'.$my_query_string;
        $response = $client->request('GET', $url);

        $statusCode = $response->getStatusCode();
        $headers = $response->getHeaders();
        $content = $response->getContent();

        return new JsonResponse($content, $statusCode, $headers);
    }

If your content is already Json, add the optional parameter true to JsonResponse.

Upvotes: 0

Alvin Bunk
Alvin Bunk

Reputation: 7764

You should be able to use (for example):

$response->headers->set('Content-Type', 'text/plain');

which is described here: http://symfony.com/doc/current/components/http_foundation.html#response

The Response API also describes each of the methods. I'm not certain what type of header you need to send.

Upvotes: 1

Related Questions