PHP `curl_exec` 无响应排错

/ 0评 / 0

编写这样一个模块:转发用户的 Cookie 和 POST 请求到另一个页面上。自然地想到应该使用 curl.

代码应该是直白的,从请求的 $_COOKIE 中提取 Cookie 以及 $_POST 中提取请求内容,再直接扔给 curl 转发,将响应中的 Cookie 提取并作为响应 Cookie 最后返回内容就可以了。然而这段代码写好之后发现所有通过这个模块响应的请求都卡死了。如果添加五秒钟的请求超时,则所有请求都会超时。考虑到目标页面和这个页面在同一个文件夹下,而且之前不经过代理的时候目标页面可以正常工作,这个超时十分奇怪。

太长不看:XDEBUG_SESSION 影响了 XDebug 的调试,导致服务器挂死。有兴趣看排错流程的请继续阅读。

首先想到,并不是所有请求都是 POST, 当这是一个 GET 请求的时候,$_POST 是空的,而似乎 Apache 不能很好地解析空的 POST 请求。那么添加判断,如果是  GET 请求就按照 GET 方式转发,没有卵用;检查 Cookie 的格式,应该是分号后面有一个空格,没发现问题;目标页面也会使用会话,所以在请求之前,代理脚本应该主动结束会话(这样 PHP 会释放会话文件的锁),在编写的时候考虑到了这一点,所以应该不是问题所在;打开 verbose 模式看调试,请求头也是正常的,没有出现错误的内容长度,依然毫无进展。

这时候只能调 curl 命令先确定一下是不是 libcurl 本身有问题。于是在构建请求的时候发现当 Cookie 中包含 XDEBUG_SESSION 的时候命令挂死,去除该 Cookie 项目之后正常返回内容。在 PHP 中过滤掉这个 Cookie 项后问题消失。

考虑一下,这应该是 XDebug 的锅。当 XDEBUG_SESSION 传入目标页面的时候,相当于代理页面再次开启了调试会话,而调试会话在客户端处已经开启了。

基本上就是这样。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Your comments will be submitted to a human moderator and will only be shown publicly after approval. The moderator reserves the full right to not approve any comment without reason. Please be civil.