Search code examples
phpapicurllumenguzzle

Same request on cURL and GuzzleHTTP. Different responses


I am fighting with GuzzleHTTP inside my API. I am using Lumen to develop API for communication with HashiCorp Vault API. To do this I installed GuzzleHTTP to make API calls.

For example I am trying to generate credentials for database user based on specific role. In the commandline cURL request responses to me with credentials for new user. While using Guzzle doesn't give me anything related to new created user.

I am new into Guzzle so I will be glad for any advice.

cURL request looks like this:

curl -X GET \
    --header "X-Vault-Token: $VAULT_TOKEN" \
    http://192.168.1.3:8200/v1/database/creds/my-role | json_pp

And the response gives me credentials I want:

{
   "request_id" : "3eacc89b57b-2e2e-af6f-849f-868bdbfd2dc5e1",
   "wrap_info" : null,
   "renewable" : true,
   "data" : {
      "username" : "randomgeneratedusername",
      "password" : "randomgeneratedpassword"
   },
   "auth" : null,
   "lease_duration" : 3600,
   "warnings" : null,
   "lease_id" : "database/creds/my-role/randomsecretname"
}

When my Guzzle code looks like this:

class MySQLVaultAPI extends VaultAPI
{
    public function createUser() {
        $response = $this->getClient()->request('GET', $this->url.'/database/creds/my-role',
            ['headers' => $this->headers]);

    }
}

And:

class VaultAPI
{
    protected string $url;
    protected Client $http;
    protected array $headers;

    public function __construct(Client $client)
    {
        $this->url = 'http://192.168.1.3:8200/v1';
        $this->http = $client;
        $this->headers = [
            'X-Vault-Token' => 'secrettoken',
            'Accept' => 'application/json',
        ];
    }
}

And the response from GuzzleHTTP(I have used symfony dumper on $response object):

^ GuzzleHttp\Psr7\Response {#43 ▼
  -reasonPhrase: "OK"
  -statusCode: 200
  -headers: array:4 [▼
    "Cache-Control" => array:1 [▶]
    "Content-Type" => array:1 [▶]
    "Date" => array:1 [▶]
    "Content-Length" => array:1 [▶]
  ]
  -headerNames: array:4 [▼
    "cache-control" => "Cache-Control"
    "content-type" => "Content-Type"
    "date" => "Date"
    "content-length" => "Content-Length"
  ]
  -protocol: "1.1"
  -stream: GuzzleHttp\Psr7\Stream {#21 ▼
    -stream: stream resource @137 ▶}
    -size: null
    -seekable: true
    -readable: true
    -writable: true
    -uri: "php://temp"
    -customMetadata: []
  }
}

Solution

  • Okey,

    I have found out the answer. All of the content is in GuzzleHttp\Psr7\Stream

    So I had to make additional method in my VaultAPI service

    public function getFullBody(Stream $responseBody)
    {
        $responseBody->seek(0);
        $output = json_decode(trim($responseBody->getContents()), true);
        if ($output === null) {
            throw new \Exception('Error parsing response JSON ('.json_last_error().')');
        }
    
        return $output;
    }
    

    And then inside my MySQLVaultAPI I am calling it

    public function createUser() {
        $response = $this->getClient()->request('GET', $this->url.'/database/creds/my-role',
            ['headers' => $this->headers]);
        return $this->getFullBody($response->getBody());
    }