Proxy Server, Cache, Https And Chttprequest::$Issecureconnection

I have a "special" setup on my servers where I have a proxy sitting in front of the cache which in term fetches data from the actual web service.

After installing a SSL certificate @ the proxy level, I had some difficulty maintaining the ‘https’ directive in front of the redirects.

It turned out that Yii considered it was not running on a secure connection because the web service it is running on is serving pages using the http protocol. However, these pages are served internally to the cache server which serves them to the proxy where the SSL encryption takes place.

After looking into the available variables, I found that [size="2"]


$_SERVER['HTTP_X_FORWARDED_PROTO']

could tell the tale.[/size]

[size="2"]So I replaced CHttpRequest::getIsSecureConnection() with the following:[/size]




	/**

     * Return if the request is sent via secure channel (https).

     * @return boolean if the request is sent via secure channel (https)

     */

	public function getIsSecureConnection()

	{

		return (!empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'],'off'))

	         || (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])

	            	&& strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'],'https')==0)

	    	;

	}



That does the trick for me.

I am not reporting it as a bug or an issue, just logging it here for info.

Instead of changing a Yii core file (need to make the same changes on every version upgrade) you can add this code to your index.php




if(!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) 

   && strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'],'https')==0)

   $_SERVER['HTTPS'] = 'on';



Hi

Thanks for the suggestion.

I don’t like hacking core values too much, si[size=2] I extended the CHttpRequest class and specified the new class for it in the configuration file, which was actually already in place to disable CSRF checking in specific cases. In this code I put the …X_PROTO test first because that is what happens most often for me:[/size]




class YHttpRequest extends CHttpRequest {

    public $noCsrfValidationRoutes = array();


    protected function normalizeRequest()

    {

        parent::normalizeRequest();

        $route = implode('/', array_slice(explode('/', Yii::app()->getUrlManager()->parseUrl($this)), 0, 2));


        if($this->enableCsrfValidation && array_search($route, $this->noCsrfValidationRoutes) !== false)

            Yii::app()->detachEventHandler('onbeginRequest',array($this,'validateCsrfToken'));

    }


    /**

     * Return if the request is sent via secure channel (https).

     * @return boolean if the request is sent via secure channel (https)

     */

    public function getIsSecureConnection()

    {

        return (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])

                && strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'],'https')==0)

                ||(!empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'],'off'))

                ;

    }

}

[color="#006400"]NOTE: moved to proper section (Tips, Snippets and Tutorials instead of Bug Discussion)[/color]

What is your actual webserver running? In Apache, you can do pretty much the same thing with SetEnvIf.

Hi

The Yii application is interpreted in PHP through the Apache server, in another setup it is interpreted in PHP through a lighttpd server.

The latter does not support the .htaccess configuration.

So basically we have three solutions now:

  1. Extend the CHttpRequest class;

  2. Hack the $_SERVER[‘HTTPS’] value in ‘index.php’;

  3. Hack the $_SERVER[‘HTTPS’] value in ‘.htaccess’ or other web server setup.

I’ll stick with the first solution.

Thanks

Mario

Uhm, well … Lighty does support setting additional enviromental variables for (fast)cgi, so lacking .htaccess support wouldn’t be a problem.

Sure, the configureability of lighttpd is one of the reasons why it is used as an entry point to the server.

On that account it looks like the current HTTPS detection of Yii is not intrinsically compatible with lighttpd and that it requires the hack in the lighttpd configuration:

http://redmine.lighttpd.net/projects/1/wiki/Docs_SSL#HTTPS-detection-in-PHP

Perhaps you should know that the HTTPS variable is really a de-facto standard set in place by Apache. There’s little Yii can do about that.