Laravel 7 的 Http 客户端 + xml = 错误请求,尽管 curl 工作正常

Laravel 7's Http client + xml = Bad request although curl works fine

对于用户使用 curl 而不是使用 php 的 Guzzle http 获得所需结果的情况,SO 有很多问题。在我的例子中,我试图通过以下方式使用 laravel 7 的新 Httpclient(本质上是 Guzzle 的包装器):

$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);

这给了我一个 400 响应。

我用curl做了:

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

我试过拦截我的请求并检查它们:它们看起来是一样的。尽管如此,我为 Http 设置 body 的方式一定有问题,因为我一直收到 400。有什么见解吗?

Ps。我也试过只使用 Guzzle 而不是 Http,但结果是一样的。我也尝试过使用:

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

而不是在 withOptions 调用中设置 body 但没有成功。我什至添加了 user-agent header 以 100% 模仿卷曲,但是,当然,这没有帮助。

更新:

我注意到我将此附加到 Http 的响应中:

* Mark bundle as not supporting multiuse 

更新2:

我还设法通过以下方式从 PHP 内部使用 curl 使请求正常工作:

$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);


设法解决了。奇怪的是,在 form_params 选项中设置 xml 使我发布的端点接受我的请求:

$response = $req->post($url, ['form_params' => [$xml]]);