Where I work, we finally outgrew our shared hosting britches and moved over to a VPS. Most of this growth came not from the need for processing power, but from our need to store a large number of images. The standard real estate listing went from averaging 8 images to 15 and storing multiple file sizes led to us needing to store 120,000 images. The plan was to activate ludicrous speed.

I got everything set up, RackSpace for hosting, used GlobalSign for SSL, CloudFlare for DNS and MaxCDN for images. Everything went well and we immediately saw a decrease in first byte time and overall page load times were decreased. I noticed some intermittent issues with both CloudFlare and MaxCDN, but the nginx access logs showed that everything was being resolved fine and ending with a 200 status code. I moved the main application back to the shared host but left resolving images with MaxCDN and started troubleshooting.

MaxCDN support thought the issue could be with our certificate so I set down the path of testing the SSL configuration. I used SSLLabs and a tutorial from Remy van Elst to get a solid A+ rating. I ran a battery of other SSL tests against the server and they all agreed that SSL was solid. I went back to MaxCDN and they ran a few more tests and insisted I add the Root CA to the certificate chain. I went back to GlobalSign Support to get their take. They didn’t think adding the Root CA to the chain would make a difference, but they sent the cert and I added it. My SSL rating went to an A for containing an anchor in the chain, but if it solves MaxCDN 502 issue, I’ll take it. I purged the cache and ran it again. 502!

After some troubleshooting, I found that I could 502 in Chrome, but in Firefox I would get the file. But I would only get the first file. Additional files in Firefox would 502. I jumped over to the command line to cURL the image URLs. Each and every time the file would be resolved and returned. I jumped back to Chrome and opened an incognito tab. 200! I attempted a second file and returned a 502. I compared the response headers across the various attempts as well as accessing the files directly. That is when it hit me. Cookies!

I went back to MaxCDN with my theory of the number and size of cookies being sent by CodeIgniter causing the 502. I was told it had to be because the server wasn’t performing TLS 1.1/1.2 properly and that our host was blocking their requests and that they were going to continue looking in to the issue. At this point, I gave up on MaxCDN providing a solution, so I went about testing my own solution. I searched for other persons having the same issue and came across a thread on EllisLabs that had the exact solution I needed. I added the custom session class and the post_controller hook and the 502s disappeared. Completely. I turned CloudFlare back on and the 520s disappeared as well.

So, if you are having a 502 error with MaxCDN or a 520 with CloudFlare and can’t figure out where it is coming from, check your cookies. Despite the blue muppet’s persistence, there is a chance that you can have too many cookies or your cookies may be too big.

UPDATE: The Ellis Lab forum links are dead, so here is the solution to the problem. I haven’t ran CI 3.0 yet, so I don’t know if this update is required there or not.

In your application/libraries directory, extend CI_Session. For my install, my prefix is RS.

class RS_Session extends CI_Session {
	private $cookie_data = array();
	public function _set_cookie($cookie_data = NULL){
		if(is_null($cookie_data)){
			$cookie_data = $this->userdata;
		}
		$cookie_data = $this->_serialize($cookie_data);
		if($this->sess_encrypt_cookie == true){
			$cookie_data = $this->CI->encrypt->encode($cookie_data);
		} else {
			$cookie_data = $cookie_data . md5($cookie_data . $this->encryption_key);
		}
		$this->cookie_data[] = $cookie_data;
	}
	public function finalize_session(){
		if(!empty($this->cookie_data)){
			$cookie_data = array_pop($this->cookie_data);
			$expire = ($this->sess_expire_on_close === true) ? 0 : $this->sess_expiration + time();
			setcookie(
				$this->sess_cookie_name,
				$cookie_data,
				$expire,
				$this->cookie_path,
				$this->cookie_domain,
				$this->cookie_secure
			);
			$this->cookie_data = array();
		}
	}

You also need to add a hook to finalize the session. I created a file, “finalizeSession.php”, in my application/hooks directory.

function finalize_session(){
	$CI =& get_instance();
	$CI->session->finalize_session();
}

And then added this to the application/config/hooks.php file

$hook['post_controller'][] = array(
    "class" => "",
    "function" => "finalize_session",
    "filename" => "finalizeSession.php",
    "filepath" => "hooks"
);