【问题标题】:cURL not sending content-lengthcURL 不发送内容长度
【发布时间】:2022-01-26 17:06:06
【问题描述】:

我正在尝试从 Spotify API 获取 O-Auth 令牌,但在 Debian 8 上使用 cURL 时,当它在我的 MacBook 上运行时,我总是收到错误消息 POST requests require a Content-length header.。

$authString = $spotifyId . ":" . $spotifySecret;
$encodedAuthString = base64_encode($authString);

$spotifyHeaders = array(
    "Authorization: Basic " . $encodedAuthString,
    "Content-Type: application/x-www-form-urlencoded",
);

$spotifyOauthCurl = curl_init();
curl_setopt($spotifyOauthCurl, CURLOPT_URL, "https://accounts.spotify.com/api/token");
curl_setopt($spotifyOauthCurl, CURLOPT_POST, true);
curl_setopt($spotifyOauthCurl, CURLOPT_HTTPHEADER, $spotifyHeaders);
curl_setopt($spotifyOauthCurl, POSTFIELDS, "grant_type=client_credentials");
curl_setopt($spotifyOauthCurl, CURLOPT_RETURNTRANSFER, true);
// curl_setopt($spotifyOauthCurl, CURLINFO_HEADER_OUT, true);
$result = curl_exec($spotifyOauthCurl);
echo curl_getinfo($spotifyOauthCurl, CURLINFO_HEADER_OUT);

按照@hanshenrik 的建议添加 CURLOPT_VERBOSE 会返回以下输出

Trying 35.186.224.25...
* TCP_NODELAY set
* Connected to accounts.spotify.com (35.186.224.25) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=SE; L=Stockholm; O=Spotify AB; CN=*.spotify.com
*  start date: May  3 00:00:00 2021 GMT
*  expire date: May  3 23:59:59 2022 GMT
*  subjectAltName: host "accounts.spotify.com" matched certs "*.spotify.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS RSA SHA256 2020 CA1
*  SSL certificate verify ok.
> POST /api/token HTTP/1.1

/api/token?grant_type=client_credentials HTTP/1.1
Host: accounts.spotify.com
Accept: */ *
Authorization: Basic ...
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue

* HTTP 1.0, assume close after body
< HTTP/1.0 411 Length Required
< Content-Type: text/html; charset=UTF-8
< Referrer-Policy: no-referrer
< Content-Length: 1564
< Date: Wed, 26 Jan 2022 17:36:23 GMT
< 
* Curl_http_done: called premature == 0
* Closing connection 0

【问题讨论】:

  • 添加 CURLOPT_VERBOSE: $stderrh=tmpfile(); curl_setopt_array($spotifyOauthCurl,array(CURLOPT_VERBOSE=&gt;1,CURLOPT_STDERR=&gt;$stderrh)); curl_exec($spotifyOauthCurl); /* https://bugs.php.net/bug.php?id=76268 */ rewind($stderrh); $stderr=stream_get_contents($stderrh); fclose($stderrh); echo $stderr; 并显示详细日志...我发现很难相信将 POSTFIELDS 设置为字符串不会使 libcurl 添加内容-长度标头..
  • body 设置在哪里?
  • @hanshenrik 不幸的是,它什么也没输出
  • @hobbs 我之前尝试使用 POSTFIELDS 设置正文,但它并没有改变 Spotify API 的响应
  • @ProfGhost 在这种情况下,您的脚本要么崩溃,要么在 ob_start() 下运行; ... php 错误日志中的任何内容?

标签: php curl php-curl


【解决方案1】:

1:每次运行时都会忽略错误日志

curl_setopt($spotifyOauthCurl, POSTFIELDS, "grant_type: client_credentials");

您的错误日志会收到类似的消息

Warning: Use of undefined constant POSTFIELDS - assumed 'POSTFIELDS' (this will throw an Error in a future version of PHP) in /in/S9fsj on line 3
string(10) "POSTFIELDS"

另外你正在运行 php 5/7,因为在 PHP8 中这会抛出异常:https://3v4l.org/S9fsj

2:您忽略 curl_setopt 返回错误,curl_setopt 在错误时返回 false,您的代码将忽略这些错误。一个简单的方法是

function ecurl_setopt ( /*resource*/$ch , int $option , /*mixed*/ $value ){
    $ret=curl_setopt($ch,$option,$value);
    if($ret!==true){
        //option should be obvious by stack trace
        throw new RuntimeException ( 'curl_setopt() failed. curl_errno: ' .  curl_errno ($ch) .'. curl_error: '.curl_error($ch) );
    }
}

3:都是错字造成的!它应该是CURLOPT_POSTFIELDS 而不仅仅是POSTFIELDS

【讨论】:

  • 该死,我已经在正确的路线上? 好找到汉斯!
  • 非常感谢,好像找了几天都忽略了。我仍然想知道为什么它在我的 MacBook 上而不是在 Debian 上工作
  • 你真的应该打开错误报告来调试。如果你隐藏了所有的错误,你就会离开你自己和你要求的人进行猜谜游戏。
  • @ProfGhost 确实是个谜,它绝对不应该在你的 macbook 上工作:o
猜你喜欢
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-07
  • 1970-01-01
  • 2016-03-17
  • 2019-07-10
相关资源
最近更新 更多