2

SO has a lot of questions for cases where a user is getting the desired result with curl but not with php's Guzzle http. In my case I am trying to use the new Httpclient of laravel 7 (essentially a wrapper around Guzzle) in the following manner:

$xml= '<root></root>';
$url = 'http://10.0.0.2/rcp';
$req = Http::withHeaders([
        'Content-Type' => 'application/xml',
        'Accept' => 'application/xml',
        'user-agent' => 'Curl 7',
])
        ->withBasicAuth('user', 'secret')
        ->bodyFormat('xml')
        ->withOptions([
                'body' => $xml,
                'debug' => true,
        ])
        ->contentType('application/xml');
$req->post($url);

This gives me a 400 response.

With curl I have done:

curl http://10.0.0.2/rcp -X POST -u "user:secret" -H "Content-Type: application/xml" -H "Accept: application/xml" --data '<root></root>'

I have tried intercepting my requests and inspecting them: they seem identical. Still, there must be something wrong in the way I'm setting the body for Http, since I keep getting 400. Any insights?

Ps. I've also tried using mere Guzzle instead of Http, but the result is the same. I have also tried using:

$req->send('POST', $url, ['body' => $xml]);

instead of setting the body in the withOptions call but with no success. I even added a user-agent header in order to 100% mimic curl but, of course, that didn't help.

UPDATE:

I noticed that I get this attached to the response with Http:

* Mark bundle as not supporting multiuse 

UPDATE2:

I also managed to get the request working using curl from inside PHP in the following manner:

$xml= '<root></root>';
$url = 'http://10.0.0.2/rcp';
$username = 'user';
$password = 'secret';

$curl = curl_init();
curl_setopt_array($curl, [
        curlopt_verbose => 1,
        curlopt_url => $url,
        curlopt_userpwd => $username . ':' . $password,
        curlopt_timeout => 30,
        curlopt_http_version => curl_http_version_1_1,
        curlopt_customrequest => 'post',
        curlopt_postfields => $xml,
        curlopt_httpheader => [
                'content-type: application/xml',
                'accept: application/xml',
        ],
]);

$response = curl_exec($curl);


jharme
  • 166
  • 7

1 Answers1

1

Managed to sort it out. Weirdly enough, setting the xml inside the form_params option made the endpoint I was posting to accept my requests:

$response = $req->post($url, ['form_params' => [$xml]]);
jharme
  • 166
  • 7
  • I had the same issue when trying to reproduce an HTTP call that dealt with uncommon Content-Type. At first, I used the `body` request option as I could not see that the request body was actually URL-encoded (it was a single value). Then, I tried with the `form_params` it worked. The Content-Type `application/x-www-form-urlencoded` is only set if there's not already a `Content-Type` provided along with the request. – eexit Apr 22 '22 at 10:58