[英]What could be the cause of unexpected characters served by the PHP internal web server?
我在基于 Alpine 3.8 的 Docker 容器中运行 PHP 内部 Web 服务器。
这是一个简单的页面,它是:
<!DOCTYPE html>
<html>
<head>
<title>Test page</title>
</head>
<body>
<div>
This is a 'hello world' for my CD container.
</div>
<p>
Version: <?php echo getenv('CD_DEMO_VERSION') ?>
</p>
<p>
GUID: <?php echo file_get_contents(__DIR__ . '/guid.txt') ?>
</p>
</body>
</html>
我在 CircleCI 构建过程中有这个,PHPUnit 使用simplexml_load_string()
读取 HTML 以检查它是否正常工作。 大多数情况下它没问题,但偶尔会在 HTML 的开头或结尾添加控制字符,导致 HTML 解析失败。 我会说这种情况发生的概率为 10%,因此很难复制。 它似乎不会发生在本地。
在这个构建过程中,我正在等待 Web 服务器启动,所以我认为这里不会发生竞争条件。
如果 cruft 出现在开始时,它看起来像这样(我的输出交换回车到⏎
符号,这不会被 XML 处理器看到):
^@^@<html>⏎ <head>⏎ <title>Test page</title>⏎ </head>⏎ <body>⏎ <div>⏎ This is a 'hello world' for my CD container.⏎ </div>⏎ <p>⏎ Version: </p>⏎ <p>⏎ GUID: 47294362a6154e9a5397a9f9b72cefe1d349ec2e31de12e6084746a084e4e4ef </p>⏎ </body>⏎</html>
如果 cruft 出现在最后,它看起来像这样:
<!DOCTYPE html>⏎<html>⏎ <head>⏎ <title>Test page</title>⏎ </head>⏎ <body>⏎ <div>⏎ This is a 'hello world' for my CD container.⏎ </div>⏎ <p>⏎ Version: </p>⏎ <p>⏎ GUID: a721f44d05e93debb593eef135fc664fb6b0d3aa6a04d50af7f17339d0d75399 </p>⏎ </body>⏎</html>⏎^@^@
我不知道这些是否是实际的抑扬符和符号,或者这是否只是随机内容呈现到我的屏幕上的方式。
看起来 Web 服务器正在提供 UTF-8 字符集标头。
我认为我的 PHPUnit 测试是相关的,所以我会在这里添加它。 由于 CircleCI 的工作方式,我无法在容器外部发布 Docker 端口,因此我使用docker exec
从内部执行 HTTP 操作:
public function testApp()
{
// Get the page and convert it to an XML object
$html = $this->getWebPage();
// CI is giving me some parsing issues, so let's see it
echo str_replace("\n", "⏎", $html);
$doc = simplexml_load_string($html);
$message = trim((string) $doc->body->div);
$this->assertEquals(
"This is a 'hello world' for my CD container.",
$message
);
}
protected function getWebPage()
{
$output = $return = null;
$command = sprintf(
'docker exec -ti %s php -r "echo file_get_contents(\'http://localhost\');"',
escapeshellarg($this->getRepoName())
);
exec($command, $output, $return);
// Check return value first
if ($return)
{
throw new RuntimeException(
sprintf(
'Returned a failure exit code %d on Docker operation',
$return
)
);
}
$imploded = implode(PHP_EOL, $output);
return $imploded;
}
我已经在 Alpine 3.8 中更新到 Apache 2.4.x,令我惊讶的是,我遇到了完全相同的问题。 因此,结果证明它不是 PHP Web 服务器。
我也试过 Alpine 3.7,同样的结果。 我再次尝试了 Ubuntu 18.10。
我试过php -r
与file_get_contents()
和wget
作为容器内的 HTTP 设备。
我现在认为从docker exec
捕获标准输出是错误的。 我假设如果我在另一个镜像中设置我的测试并使用 Docker Compose 运行容器,它可能会工作。 或者,我可以使用docker exec
,写入一个容器文件,然后使用docker cp
取出文件。
不过,知道出了什么问题仍然很有趣。
正如我在问题中推测的那样,这是通过执行docker exec
并将标准输出重定向到容器中的临时文件来解决的。 然后我使用docker cp
将文件从容器中取出回主机。
我没有发现是什么导致了奇怪的文本伪影,并想知道它是否可能特定于 CircleCI。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.