php - PayPal IPN 错误:不支持标题字段的行折叠
问题描述
一个运行多年的 PayPal IPN 脚本突然停止工作。PayPal 正在返回以下响应:
HTTP/1.1 400 Bad Request
Connection: close
Content-Length: 46
content-type: text/plain; charset=utf-8
line folding of header fields is not supported
总结一下 PayPal IPN 应该如何工作:
- PayPal POST 到您系统上的端点
- 端点必须用它收到的 POST 数据回复 PayPal
- PayPal 回复 VERIFIED
就我而言,PayPal 无法验证响应,因为“不支持标题字段的行折叠”。
谷歌没有提供太多关于“行折叠标题字段”的内容。我只能假设这与标题格式有关。以下是相关代码:
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
// 7/22/2013 - Update to use HTTP 1.1 instead of HTTP 1.0
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n";
$header .= "Host: www.paypal.com\r\n ";
$header .= "Connection: close\r\n\r\n";
// Open a connection to PayPal.com
$fp = @fsockopen("ssl://{$target}", 443, $errno, $errstr, 30);
if (!$fp) {
// HTTP ERROR
}else{
@fputs ($fp, $header . $req);
while (!@feof($fp)) {
$res = @fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
$verified = true;
}else{
// Log failure
}
}
@fclose ($fp);
}
任何想法可能导致关于标题的行折叠错误?
解决方案
标题折叠在https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4下进行了解释:
从历史上看,HTTP 标头字段值可以通过在每一额外行之前至少一个空格或水平制表符(obs-fold)来扩展多行。
我不得不回显您生成的标题以自己查看问题,这很难发现:
$header .= "Host: www.paypal.com\r\n ";
此处换行后的额外空格意味着下一个标题行将从该空格开始- 这意味着您正在“折叠标题”,而实际上并没有打算这样做。
删除多余的尾随空间,事情应该可以正常工作。
推荐阅读
- java - 有史以来最奇怪的事情(Java 和 Angular(简单))
- grails - 启用级联保存和事务的 Grails 域关联
- vue.js - 将数据传递给 Vue 应用程序
- javascript - 将数组从 javascript 发送到 Django
- vba - 从 Excel VBA 运行访问查询
- php - 使用 PHP 以编程方式保存远程图像
- node.js - VScode 调试器出错,因为我将 nodejs 版本从 6.10 更新到 8.10
- c# - 如何为类或类列表生成构造函数依赖图?
- centos - OSError: [Errno 99] 无法分配请求的地址
- c - c中的strcpy表现不同