|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00046 class HTTP_Encoder { 00047 00062 public static $encodeToIe6 = false; 00063 00064 00072 public static $compressionLevel = 6; 00073 00074 00091 public function __construct($spec) 00092 { 00093 $this->_content = $spec['content']; 00094 $this->_headers['Content-Length'] = (string)strlen($this->_content); 00095 if (isset($spec['type'])) { 00096 $this->_headers['Content-Type'] = $spec['type']; 00097 } 00098 if (isset($spec['method']) 00099 && in_array($spec['method'], array('gzip', 'deflate', 'compress', ''))) 00100 { 00101 $this->_encodeMethod = array($spec['method'], $spec['method']); 00102 } else { 00103 $this->_encodeMethod = self::getAcceptedEncoding(); 00104 } 00105 } 00106 00114 public function getContent() 00115 { 00116 return $this->_content; 00117 } 00118 00133 public function getHeaders() 00134 { 00135 return $this->_headers; 00136 } 00137 00149 public function sendHeaders() 00150 { 00151 foreach ($this->_headers as $name => $val) { 00152 header($name . ': ' . $val); 00153 } 00154 } 00155 00167 public function sendAll() 00168 { 00169 $this->sendHeaders(); 00170 echo $this->_content; 00171 } 00172 00193 public static function getAcceptedEncoding($allowCompress = true, $allowDeflate = true) 00194 { 00195 // @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html 00196 00197 if (! isset($_SERVER['HTTP_ACCEPT_ENCODING']) 00198 || self::_isBuggyIe()) 00199 { 00200 return array('', ''); 00201 } 00202 $ae = $_SERVER['HTTP_ACCEPT_ENCODING']; 00203 // gzip checks (quick) 00204 if (0 === strpos($ae, 'gzip,') // most browsers 00205 || 0 === strpos($ae, 'deflate, gzip,') // opera 00206 ) { 00207 return array('gzip', 'gzip'); 00208 } 00209 // gzip checks (slow) 00210 if (preg_match( 00211 '@(?:^|,)\\s*((?:x-)?gzip)\\s*(?:$|,|;\\s*q=(?:0\\.|1))@' 00212 ,$ae 00213 ,$m)) { 00214 return array('gzip', $m[1]); 00215 } 00216 if ($allowDeflate) { 00217 // deflate checks 00218 $aeRev = strrev($ae); 00219 if (0 === strpos($aeRev, 'etalfed ,') // ie, webkit 00220 || 0 === strpos($aeRev, 'etalfed,') // gecko 00221 || 0 === strpos($ae, 'deflate,') // opera 00222 // slow parsing 00223 || preg_match( 00224 '@(?:^|,)\\s*deflate\\s*(?:$|,|;\\s*q=(?:0\\.|1))@', $ae)) { 00225 return array('deflate', 'deflate'); 00226 } 00227 } 00228 if ($allowCompress && preg_match( 00229 '@(?:^|,)\\s*((?:x-)?compress)\\s*(?:$|,|;\\s*q=(?:0\\.|1))@' 00230 ,$ae 00231 ,$m)) { 00232 return array('compress', $m[1]); 00233 } 00234 return array('', ''); 00235 } 00236 00254 public function encode($compressionLevel = null) 00255 { 00256 $this->_headers['Vary'] = 'Accept-Encoding'; 00257 if (null === $compressionLevel) { 00258 $compressionLevel = self::$compressionLevel; 00259 } 00260 if ('' === $this->_encodeMethod[0] 00261 || ($compressionLevel == 0) 00262 || !extension_loaded('zlib')) 00263 { 00264 return false; 00265 } 00266 if ($this->_encodeMethod[0] === 'deflate') { 00267 $encoded = gzdeflate($this->_content, $compressionLevel); 00268 } elseif ($this->_encodeMethod[0] === 'gzip') { 00269 $encoded = gzencode($this->_content, $compressionLevel); 00270 } else { 00271 $encoded = gzcompress($this->_content, $compressionLevel); 00272 } 00273 if (false === $encoded) { 00274 return false; 00275 } 00276 $this->_headers['Content-Length'] = strlen($encoded); 00277 $this->_headers['Content-Encoding'] = $this->_encodeMethod[1]; 00278 $this->_content = $encoded; 00279 return true; 00280 } 00281 00294 public static function output($content, $compressionLevel = null) 00295 { 00296 if (null === $compressionLevel) { 00297 $compressionLevel = self::$compressionLevel; 00298 } 00299 $he = new HTTP_Encoder(array('content' => $content)); 00300 $ret = $he->encode($compressionLevel); 00301 $he->sendAll(); 00302 return $ret; 00303 } 00304 00305 protected $_content = ''; 00306 protected $_headers = array(); 00307 protected $_encodeMethod = array('', ''); 00308 00312 protected static function _isBuggyIe() 00313 { 00314 $ua = $_SERVER['HTTP_USER_AGENT']; 00315 // quick escape for non-IEs 00316 if (0 !== strpos($ua, 'Mozilla/4.0 (compatible; MSIE ') 00317 || false !== strpos($ua, 'Opera')) { 00318 return false; 00319 } 00320 // no regex = faaast 00321 $version = (float)substr($ua, 30); 00322 return self::$encodeToIe6 00323 ? ($version < 6 || ($version == 6 && false === strpos($ua, 'SV1'))) 00324 : ($version < 7); 00325 } 00326 }