Symfony2功能测试客户端强制服务器参数SERVER_NAME [英] Symfony2 functional test client force server param SERVER_NAME

查看:130
本文介绍了Symfony2功能测试客户端强制服务器参数SERVER_NAME的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设计了一个multiste应用.有多站点管理员(即 http://root.com/admin ),而且所有站点都可以访问(即 http://site1.com http://site2.com .. .).

I designed a multiste app. There is multisite admin (ie. http://root.com/admin) and also all sites access (ie http://site1.com, http://site2.com...).

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

To handle routing (multisite admin or child sites), I set the UseCanonicalName on vhost configuration :

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

UseCanonicalName On

这样做,我确定$ request-> server-> get('SERVER_NAME')在给定的情况下将始终返回root.com,并且在路由过程中使用它来使根域之间有所区别(对于admin目的),子网站和404内容.

Doing so, I'm sure that $request->server->get('SERVER_NAME') will always return in given case root.com, and I use this in routing process to make difference between root domain (for admin purposes), child sites, and 404 content.

它在现实生活中运行良好,但是在测试时,UseCanonicalName似乎并没有强制使用在vhost中定义的ServerName来使用SERVER_NAME.

It's working great on real life, but when it comes to testing, it seems that UseCanonicalName doesn't force SERVER_NAME with ServerName defined in vhost.

从常规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:

I tried to force SERVER_NAME on test client :

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

但是这并没有改变,我的SERVER_NAME值仍然等于HTTP_HOST,当测试子站点FO或BO时(当SERVER_NAME与HTTP_HOST之间的区别很重要时),它将拧紧所有内容.

But this doesn't change a thing, I still have SERVER_NAME value equals to HTTP_HOST, which screws everything when it comes to test child sites FO or BO (when difference between SERVER_NAME and HTTP_HOST matters).

所以

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

推荐答案

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

On a strict point of view, I finally managed to find my way through above problem : I overloaded the Client class (Symfony\Bundle\FrameworkBundle\Client), specifically request method after filterRequest call :

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中包含的真实服务器参数合并.

Doing so, I force a merge with $server params passed to request method and real server params contained in $this->request->server.

上面已经完成了这样的合并($ server = array_merge($ this-> server,$ server);),但是由于某种原因我无法解释,filterRequest调用会重置"请求,从而清除了我的请求.自定义服务器参数.

Such a merge is already done above ($server = array_merge($this->server, $server);) but for some reason I can't explain, filterRequest call kind of "reset" the request, sweeping away my custom server params.

对于子请求,我看不到很深的含义. AFAIK,它将仅在来自第一个请求或子请求的每个请求或子请求中合并我的自定义服务器参数.

I don't see clearly deep implications of this regarding subrequest. AFAIK, it will just merge my custom server params in every request or subrequest originating from the first one.

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

In other hand, does anybody know why filterRequest (which is only a bypasser) would reset all server variable?

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

PS : as I encountered another (but yet related problem) on functional testing session vars, I asked another question

这篇关于Symfony2功能测试客户端强制服务器参数SERVER_NAME的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆