Reputation: 47329
My system needs to authenticate with an external service (out of my control in any way), and the authentication requires two HTTP requests in very short sequence (the token I get in the first request expires in 2 seconds and I have to use it to finish the auth process).
So I'm basically doing this:
// create client
$client = HttpClient::create();
$baseUrl = "https://example.com/webservice.php";
$username = "foo";
$token = "foobarbaz";
// first request
$tokenResponse = $client->request( Method::GET, $baseUrl . '?operation=getchallenge&username=' . $username );
$decoded = $tokenResponse->toArray();
// second request
$loginResponse = $client->request( Method::POST, $this->baseUrl, [
'body' => [
'operation' => 'login',
'username' => $username,
'accessKey' => md5( $decoded['result']['token'] . $token ),
],
]
);
$sessionData = $loginResponse->toArray();
Doing this, I get an exception ( TransportExceptionInterface
):
Failed sending data to the peer for "https://example.com/webservice.php"
But, if instead of using the same $client
I instantiate a new one ($client2 = HttpClient::create();
) and I use that one to make the second request, without making any other change to the code, it will work flawlessly.
My guess would be that this is related to the default request concurrency that HTTP Client uses, but I checked the docs and the options available on HttpClientInterface
but I haven't been anyway to change the client behaviour in a way that doesn't require me to create a new instance (nor a way to increase error logging verbosity).
I have the cURL extension installed, so the client being created is CurlHttpClient
and not NativeHttpClient
.
Is there a way around this, without having to create a new client instance?
Upvotes: 2
Views: 5072
Reputation: 645
Here is what docs say.
Even when doing regular synchronous calls, this design allows keeping connections to remote hosts open between requests, improving performance by saving repetitive DNS resolution, SSL negotiation, etc. To leverage all these design benefits, the cURL extension is needed.
In order to use php streams the example says you use NativeClient as follows:
use Symfony\Component\HttpClient\CurlHttpClient;
use Symfony\Component\HttpClient\NativeHttpClient;
// uses native PHP streams
$client = new NativeHttpClient();
// uses the cURL PHP extension
$client = new CurlHttpClient();
This way you can select specific client without framework making you use curl client.
Once you get token, close the connection and create an new one from same client, this will ensure you are using same Client object but initiating new connection requirements, which mimics the behavior server requires in order to authenticate.
It is always good to check server response before parsing body. Please check if server has sent 200 response with token and branch out your logic. Try catch or checking headers is always a bonus and good practice in error handling.
Upvotes: 2