php - Symfony2 功能测试客户端强制服务器参数 SERVER_NAME

标签 php apache symfony testing client

我设计了一个 multiste 应用程序。有多站点管理员(即 http://root.com/admin )和所有站点访问权限(即 http://site1.comhttp://site2.com.. .)。

为了处理路由(多站点管理或子站点),我在 vhost 配置上设置了 UseCanonicalName :

ServerName root.com
ServerAlias media.site1.com site1.com media.site2.com, site2.com ...

UseCanonicalName On

这样做,我确定 $request->server->get('SERVER_NAME') 在给定的情况下总是返回 root.com,我在路由过程中使用它来区分根域(对于管理员目的)、子站点和 404 内容。

它在现实生活中运行良好,但在测试时,似乎 UseCanonicalName 不会强制使用 vhost 中定义的 ServerName 的 SERVER_NAME。

从常规 Chrome 客户端转储:

array(34) {
  'HTTP_HOST' => 
   string(9) string 'site1.com'
   ...
  'HTTP_USER_AGENT' => 
   string(105) 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36'
  'SERVER_NAME' => 
   string(8) 'root.com'
   ...
}

从测试客户端转储

array(16) {
  'SERVER_NAME' =>
  string(9) "site1.com"
  'HTTP_HOST' =>
  string(9) "site1.com"
  'HTTP_USER_AGENT' =>
  string(19) "Symfony2 BrowserKit"
  ...
}

我试图在测试客户端上强制使用 SERVER_NAME :

$crawler = $this->client->request('GET', $route, [], [], ['SERVER_NAME' => 'root.com']);

但这并没有改变任何事情,我的 SERVER_NAME 值仍然等于 HTTP_HOST,这在测试子站点 FO 或 BO 时搞砸了一切(当 SERVER_NAME 和 HTTP_HOST 之间的差异很重要时)。

所以,

  • 为什么 Symfony2 BrowserKit 对 UseCanonicalName 指令不敏感?
  • 如何使用 Client 类参数强制执行它?

最佳答案

从严格的角度来看,我终于找到了解决上述问题的方法:我重载了客户端类(Symfony\Bundle\FrameworkBundle\Client),特别是在 filterRequest 调用之后的请求方法:

public function request($method, $uri, array $parameters = array(), array $files = array(), array $server = array(), $content = null, $changeHistory = true)
    {
        if ($this->isMainRequest) {
            $this->redirectCount = 0;
        } else {
            ++$this->redirectCount;
        }

        $uri = $this->getAbsoluteUri($uri);

        $server = array_merge($this->server, $server);

        if (isset($server['HTTPS'])) {
            $uri = preg_replace('{^'.parse_url($uri, PHP_URL_SCHEME).'}', $server['HTTPS'] ? 'https' : 'http', $uri);
        }

        if (!$this->history->isEmpty()) {
            $server['HTTP_REFERER'] = $this->history->current()->getUri();
        }

        if (empty($server['HTTP_HOST'])) {
            $server['HTTP_HOST'] = $this->extractHost($uri);
        }

        $server['HTTPS'] = 'https' == parse_url($uri, PHP_URL_SCHEME);


        $this->internalRequest = new Request($uri, $method, $parameters, $files, $this->cookieJar->allValues($uri), $server, $content);

        $this->request = $this->filterRequest($this->internalRequest);

        // MY ADDITION
        //
        $this->request->server->replace(array_merge($this->request->server->all(), $server));

        // /MY ADDITION
        //

        if (true === $changeHistory) {
            $this->history->add($this->internalRequest);
        }

        if ($this->insulated) {
            $this->response = $this->doRequestInProcess($this->request);
        } else {
            $this->response = $this->doRequest($this->request);
        }

        $this->internalResponse = $this->filterResponse($this->response);

        $this->cookieJar->updateFromResponse($this->internalResponse, $uri);

        $status = $this->internalResponse->getStatus();

        if ($status >= 300 && $status < 400) {
            $this->redirect = $this->internalResponse->getHeader('Location');
        } else {
            $this->redirect = null;
        }

        if ($this->followRedirects && $this->redirect) {
            return $this->crawler = $this->followRedirect();
        }

        return $this->crawler = $this->createCrawlerFromContent($this->internalRequest->getUri(), $this->internalResponse->getContent(), $this->internalResponse->getHeader('Content-Type'));
    }

这样做,我强制合并传递给请求方法的 $server 参数和包含在 $this->request->server 中的真实服务器参数。

这样的合并已经在上面完成了 ($server = array_merge($this->server, $server);) 但出于某种原因我无法解释,filterRequest 调用有点“重置”请求,扫除了我的自定义服务器参数。

对于子请求,我看不出这有什么明显的深层含义。据我所知,它只会将我的自定义服务器参数合并到源自第一个请求或子请求的每个请求中。

另一方面,有人知道为什么 filterRequest(它只是一个旁路器)会重置所有服务器变量吗?

PS:当我在功能测试 session 变量上遇到另一个(但相关的问题)时,我问了 another question

关于php - Symfony2 功能测试客户端强制服务器参数 SERVER_NAME,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38380193/

相关文章:

symfony - Symfony2 中的实体表单字段和验证?

php - 在 htaccess 中声明 session 最大生命周期

php - 重置 while 循环

php - 从 URL 参数自动填充输入表单字段

php - 为什么 PHP 的 hash_equals() 函数中的参数顺序很重要?

apache - .htaccess - 帮助重写 ssl 规则

PHP 脚本无法从 Python 脚本获取输出

PHP、shell 命令和 jar 文件

php - 如何在 symfony 3.4 中正确验证 JSON 请求

forms - 如何在 Symfony2 中动态添加验证器?