Что может быть причиной неожиданных символов, обслуживаемых внутренним веб-сервером PHP? - PullRequest
0 голосов
/ 03 сентября 2018

Я использую внутренний веб-сервер PHP внутри контейнера Docker на основе Alpine 3.8.

Это обслуживает простую страницу, которая:

<!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 читает HTML, используя simplexml_load_string(), чтобы проверить, работает ли он. В большинстве случаев это нормально, но иногда он добавляет в начало или конец HTML смещение управляющих символов, что приводит к сбою синтаксического анализа HTML. Я бы сказал, что это происходит в 10% случаев, поэтому его сложно воспроизвести. Кажется, это не происходит локально.

В этом процессе сборки я жду запуска веб-сервера, поэтому я не думаю, что здесь происходит гонка.

Если в начале происходит смещение, это выглядит следующим образом (моя выходная каретка подкачки возвращается к символу , процессор 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>

Если в конце появляется крест, это выглядит так:

<!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>⏎^@^@

Я не знаю, являются ли они действительными окружностями и символами, или это то, как случайные вещи отображаются на моем экране.

Похоже, веб-сервер обслуживает заголовок набора символов 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;
}

Обновление

Я обновил до Apache 2.4.x внутри Alpine 3.8, и, к моему большому удивлению, у меня точно такая же проблема. Таким образом, оказывается, что это не веб-сервер PHP.

Я также попробовал Alpine 3.7, тот же результат снова. Я попробовал Ubuntu 18.10, снова то же самое.

Я пробовал php -r с file_get_contents() и wget в качестве HTTP-устройств внутри контейнера.

Теперь я склонен думать, что захват стандартного вывода из docker exec виноват. Я предполагаю, что если я настрою свои тесты в другом образе и запустим контейнеры с помощью Docker Compose, это, вероятно, будет работать. Или я мог бы использовать docker exec, записать в файл контейнера, а затем отправить файл с помощью docker cp.

Хотя было бы интересно узнать, что происходит не так.

1 Ответ

0 голосов
/ 20 сентября 2018

Как я догадался в этом вопросе, это было исправлено путем выполнения docker exec и перенаправления stdout во временный файл в контейнере. Затем я использовал docker cp, чтобы выловить файл из контейнера обратно на хост.

Я не выяснил, что вызвало странные текстовые артефакты, и задаюсь вопросом, может ли это быть специфичным для CircleCI.

...