Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/zend/Zend/Http/Response.php
Go to the documentation of this file.
00001 <?php
00002 
00034 class Zend_Http_Response
00035 {
00042     protected static $messages = array(
00043         // Informational 1xx
00044         100 => 'Continue',
00045         101 => 'Switching Protocols',
00046 
00047         // Success 2xx
00048         200 => 'OK',
00049         201 => 'Created',
00050         202 => 'Accepted',
00051         203 => 'Non-Authoritative Information',
00052         204 => 'No Content',
00053         205 => 'Reset Content',
00054         206 => 'Partial Content',
00055 
00056         // Redirection 3xx
00057         300 => 'Multiple Choices',
00058         301 => 'Moved Permanently',
00059         302 => 'Found',  // 1.1
00060         303 => 'See Other',
00061         304 => 'Not Modified',
00062         305 => 'Use Proxy',
00063         // 306 is deprecated but reserved
00064         307 => 'Temporary Redirect',
00065 
00066         // Client Error 4xx
00067         400 => 'Bad Request',
00068         401 => 'Unauthorized',
00069         402 => 'Payment Required',
00070         403 => 'Forbidden',
00071         404 => 'Not Found',
00072         405 => 'Method Not Allowed',
00073         406 => 'Not Acceptable',
00074         407 => 'Proxy Authentication Required',
00075         408 => 'Request Timeout',
00076         409 => 'Conflict',
00077         410 => 'Gone',
00078         411 => 'Length Required',
00079         412 => 'Precondition Failed',
00080         413 => 'Request Entity Too Large',
00081         414 => 'Request-URI Too Long',
00082         415 => 'Unsupported Media Type',
00083         416 => 'Requested Range Not Satisfiable',
00084         417 => 'Expectation Failed',
00085 
00086         // Server Error 5xx
00087         500 => 'Internal Server Error',
00088         501 => 'Not Implemented',
00089         502 => 'Bad Gateway',
00090         503 => 'Service Unavailable',
00091         504 => 'Gateway Timeout',
00092         505 => 'HTTP Version Not Supported',
00093         509 => 'Bandwidth Limit Exceeded'
00094     );
00095 
00101     protected $version;
00102 
00108     protected $code;
00109 
00116     protected $message;
00117 
00123     protected $headers = array();
00124 
00130     protected $body;
00131 
00151     public function __construct($code, $headers, $body = null, $version = '1.1', $message = null)
00152     {
00153         // Make sure the response code is valid and set it
00154         if (self::responseCodeAsText($code) === null) {
00155             require_once 'Zend/Http/Exception.php';
00156             throw new Zend_Http_Exception("{$code} is not a valid HTTP response code");
00157         }
00158 
00159         $this->code = $code;
00160 
00161         // Make sure we got valid headers and set them
00162         if (! is_array($headers)) {
00163             require_once 'Zend/Http/Exception.php';
00164             throw new Zend_Http_Exception('No valid headers were passed');
00165     }
00166 
00167         foreach ($headers as $name => $value) {
00168             if (is_int($name))
00169                 list($name, $value) = explode(": ", $value, 1);
00170 
00171             $this->headers[ucwords(strtolower($name))] = $value;
00172         }
00173 
00174         // Set the body
00175         $this->body = $body;
00176 
00177         // Set the HTTP version
00178         if (! preg_match('|^\d\.\d$|', $version)) {
00179             require_once 'Zend/Http/Exception.php';
00180             throw new Zend_Http_Exception("Invalid HTTP response version: $version");
00181         }
00182 
00183         $this->version = $version;
00184 
00185         // If we got the response message, set it. Else, set it according to
00186         // the response code
00187         if (is_string($message)) {
00188             $this->message = $message;
00189         } else {
00190             $this->message = self::responseCodeAsText($code);
00191         }
00192     }
00193 
00199     public function isError()
00200     {
00201         $restype = floor($this->code / 100);
00202         if ($restype == 4 || $restype == 5) {
00203             return true;
00204         }
00205 
00206         return false;
00207     }
00208 
00214     public function isSuccessful()
00215     {
00216         $restype = floor($this->code / 100);
00217         if ($restype == 2 || $restype == 1) { // Shouldn't 3xx count as success as well ???
00218             return true;
00219         }
00220 
00221         return false;
00222     }
00223 
00229     public function isRedirect()
00230     {
00231         $restype = floor($this->code / 100);
00232         if ($restype == 3) {
00233             return true;
00234         }
00235 
00236         return false;
00237     }
00238 
00251     public function getBody()
00252     {
00253         $body = '';
00254 
00255         // Decode the body if it was transfer-encoded
00256         switch (strtolower($this->getHeader('transfer-encoding'))) {
00257 
00258             // Handle chunked body
00259             case 'chunked':
00260                 $body = self::decodeChunkedBody($this->body);
00261                 break;
00262 
00263             // No transfer encoding, or unknown encoding extension:
00264             // return body as is
00265             default:
00266                 $body = $this->body;
00267                 break;
00268         }
00269 
00270         // Decode any content-encoding (gzip or deflate) if needed
00271         switch (strtolower($this->getHeader('content-encoding'))) {
00272 
00273             // Handle gzip encoding
00274             case 'gzip':
00275                 $body = self::decodeGzip($body);
00276                 break;
00277 
00278             // Handle deflate encoding
00279             case 'deflate':
00280                 $body = self::decodeDeflate($body);
00281                 break;
00282 
00283             default:
00284                 break;
00285         }
00286 
00287         return $body;
00288     }
00289 
00298     public function getRawBody()
00299     {
00300         return $this->body;
00301     }
00302 
00308     public function getVersion()
00309     {
00310         return $this->version;
00311     }
00312 
00318     public function getStatus()
00319     {
00320         return $this->code;
00321     }
00322 
00329     public function getMessage()
00330     {
00331         return $this->message;
00332     }
00333 
00339     public function getHeaders()
00340     {
00341         return $this->headers;
00342     }
00343 
00350     public function getHeader($header)
00351     {
00352         $header = ucwords(strtolower($header));
00353         if (! is_string($header) || ! isset($this->headers[$header])) return null;
00354 
00355         return $this->headers[$header];
00356     }
00357 
00365     public function getHeadersAsString($status_line = true, $br = "\n")
00366     {
00367         $str = '';
00368 
00369         if ($status_line) {
00370             $str = "HTTP/{$this->version} {$this->code} {$this->message}{$br}";
00371         }
00372 
00373         // Iterate over the headers and stringify them
00374         foreach ($this->headers as $name => $value)
00375         {
00376             if (is_string($value))
00377                 $str .= "{$name}: {$value}{$br}";
00378 
00379             elseif (is_array($value)) {
00380                 foreach ($value as $subval) {
00381                     $str .= "{$name}: {$subval}{$br}";
00382                 }
00383             }
00384         }
00385 
00386         return $str;
00387     }
00388 
00395     public function asString($br = "\n")
00396     {
00397         return $this->getHeadersAsString(true, $br) . $br . $this->getRawBody();
00398     }
00399 
00405     public function __toString()
00406     {
00407         return $this->asString();
00408     }
00409 
00422     public static function responseCodeAsText($code = null, $http11 = true)
00423     {
00424         $messages = self::$messages;
00425         if (! $http11) $messages[302] = 'Moved Temporarily';
00426 
00427         if ($code === null) {
00428             return $messages;
00429         } elseif (isset($messages[$code])) {
00430             return $messages[$code];
00431         } else {
00432             return 'Unknown';
00433         }
00434     }
00435 
00442     public static function extractCode($response_str)
00443     {
00444         preg_match("|^HTTP/[\d\.x]+ (\d+)|", $response_str, $m);
00445 
00446         if (isset($m[1])) {
00447             return (int) $m[1];
00448         } else {
00449             return false;
00450         }
00451     }
00452 
00459     public static function extractMessage($response_str)
00460     {
00461         preg_match("|^HTTP/[\d\.x]+ \d+ ([^\r\n]+)|", $response_str, $m);
00462 
00463         if (isset($m[1])) {
00464             return $m[1];
00465         } else {
00466             return false;
00467         }
00468     }
00469 
00476     public static function extractVersion($response_str)
00477     {
00478         preg_match("|^HTTP/([\d\.x]+) \d+|", $response_str, $m);
00479 
00480         if (isset($m[1])) {
00481             return $m[1];
00482         } else {
00483             return false;
00484         }
00485     }
00486 
00493     public static function extractHeaders($response_str)
00494     {
00495         $headers = array();
00496 
00497         // First, split body and headers
00498         $parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2);
00499         if (! $parts[0]) return $headers;
00500 
00501         // Split headers part to lines
00502         $lines = explode("\n", $parts[0]);
00503         unset($parts);
00504         $last_header = null;
00505 
00506         foreach($lines as $line) {
00507             $line = trim($line, "\r\n");
00508             if ($line == "") break;
00509 
00510             if (preg_match("|^([\w-]+):\s+(.+)|", $line, $m)) {
00511                 unset($last_header);
00512                 $h_name = strtolower($m[1]);
00513                 $h_value = $m[2];
00514 
00515                 if (isset($headers[$h_name])) {
00516                     if (! is_array($headers[$h_name])) {
00517                         $headers[$h_name] = array($headers[$h_name]);
00518                     }
00519 
00520                     $headers[$h_name][] = $h_value;
00521                 } else {
00522                     $headers[$h_name] = $h_value;
00523                 }
00524                 $last_header = $h_name;
00525             } elseif (preg_match("|^\s+(.+)$|", $line, $m) && $last_header !== null) {
00526                 if (is_array($headers[$last_header])) {
00527                     end($headers[$last_header]);
00528                     $last_header_key = key($headers[$last_header]);
00529                     $headers[$last_header][$last_header_key] .= $m[1];
00530                 } else {
00531                     $headers[$last_header] .= $m[1];
00532                 }
00533             }
00534         }
00535 
00536         return $headers;
00537     }
00538 
00545     public static function extractBody($response_str)
00546     {
00547         $parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2);
00548         if (isset($parts[1])) {
00549             return $parts[1];
00550         }
00551         return '';
00552     }
00553 
00560     public static function decodeChunkedBody($body)
00561     {
00562         $decBody = '';
00563 
00564         // If mbstring overloads substr and strlen functions, we have to
00565         // override it's internal encoding
00566         if (function_exists('mb_internal_encoding') &&
00567            ((int) ini_get('mbstring.func_overload')) & 2) {
00568 
00569             $mbIntEnc = mb_internal_encoding();
00570             mb_internal_encoding('ASCII');
00571         }
00572 
00573         while (trim($body)) {
00574             if (! preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $body, $m)) {
00575                 require_once 'Zend/Http/Exception.php';
00576                 throw new Zend_Http_Exception("Error parsing body - doesn't seem to be a chunked message");
00577             }
00578 
00579             $length = hexdec(trim($m[1]));
00580             $cut = strlen($m[0]);
00581             $decBody .= substr($body, $cut, $length);
00582             $body = substr($body, $cut + $length + 2);
00583         }
00584 
00585         if (isset($mbIntEnc)) {
00586             mb_internal_encoding($mbIntEnc);
00587         }
00588 
00589         return $decBody;
00590     }
00591 
00600     public static function decodeGzip($body)
00601     {
00602         if (! function_exists('gzinflate')) {
00603             require_once 'Zend/Http/Exception.php';
00604             throw new Zend_Http_Exception(
00605                 'zlib extension is required in order to decode "gzip" encoding'
00606             );
00607         }
00608 
00609         return gzinflate(substr($body, 10));
00610     }
00611 
00620     public static function decodeDeflate($body)
00621     {
00622         if (! function_exists('gzuncompress')) {
00623             require_once 'Zend/Http/Exception.php';
00624             throw new Zend_Http_Exception(
00625                 'zlib extension is required in order to decode "deflate" encoding'
00626             );
00627         }
00628 
00640         $zlibHeader = unpack('n', substr($body, 0, 2));
00641         if ($zlibHeader[1] % 31 == 0) {
00642             return gzuncompress($body);
00643         } else {
00644             return gzinflate($body);
00645         }
00646     }
00647 
00654     public static function fromString($response_str)
00655     {
00656         $code    = self::extractCode($response_str);
00657         $headers = self::extractHeaders($response_str);
00658         $body    = self::extractBody($response_str);
00659         $version = self::extractVersion($response_str);
00660         $message = self::extractMessage($response_str);
00661 
00662         return new Zend_Http_Response($code, $headers, $body, $version, $message);
00663     }
00664 }
 All Data Structures Namespaces Files Functions Variables Enumerations