Exemplo n.º 1
0
 /**
  * Read a part of response body encoded with chunked Transfer-Encoding
  * 
  * @access private
  * @return string
  */
 function _readChunked()
 {
     // at start of the next chunk?
     if (0 == $this->_chunkLength) {
         $line = $this->_sock->readLine();
         if (preg_match('/^([0-9a-f]+)/i', $line, $matches)) {
             $this->_chunkLength = hexdec($matches[1]);
             // Chunk with zero length indicates the end
             if (0 == $this->_chunkLength) {
                 $this->_sock->readAll();
                 // make this an eof()
                 return '';
             }
         } elseif ($this->_sock->eof()) {
             return '';
         }
     }
     $data = $this->_sock->read($this->_chunkLength);
     $this->_chunkLength -= strlen($data);
     if (0 == $this->_chunkLength) {
         $this->_sock->readLine();
         // Trailing CRLF
     }
     return $data;
 }
Exemplo n.º 2
0
 /**
  * Processes a HTTP response
  *
  * This extracts response code, headers, cookies and decodes body if it
  * was encoded in some way
  *
  * @access public
  * @param  bool      Whether to store response body in object property, set
  *                   this to false if downloading a LARGE file and using a Listener.
  *                   This is assumed to be true if body is gzip-encoded.
  * @throws PEAR_Error
  * @return mixed     true on success, PEAR_Error in case of malformed response
  */
 function process($saveBody = true)
 {
     do {
         $line = $this->_sock->readLine();
         if (sscanf($line, 'HTTP/%s %s', $http_version, $returncode) != 2) {
             return PEAR::raiseError('Malformed response.');
         } else {
             $this->_protocol = 'HTTP/' . $http_version;
             $this->_code = intval($returncode);
         }
         while ('' !== ($header = $this->_sock->readLine())) {
             $this->_processHeader($header);
         }
     } while (100 == $this->_code);
     $this->_notify('gotHeaders', $this->_headers);
     // If response body is present, read it and decode
     $chunked = isset($this->_headers['transfer-encoding']) && 'chunked' == $this->_headers['transfer-encoding'];
     $gzipped = isset($this->_headers['content-encoding']) && 'gzip' == $this->_headers['content-encoding'];
     $hasBody = false;
     if (!isset($this->_headers['content-length']) || 0 != $this->_headers['content-length']) {
         while (!$this->_sock->eof()) {
             if ($chunked) {
                 $data = $this->_readChunked();
             } else {
                 $data = $this->_sock->read(4096);
             }
             if ('' == $data) {
                 break;
             } else {
                 $hasBody = true;
                 if ($saveBody || $gzipped) {
                     $this->_body .= $data;
                 }
                 $this->_notify($gzipped ? 'gzTick' : 'tick', $data);
             }
         }
     }
     if ($hasBody) {
         // Uncompress the body if needed
         if ($gzipped) {
             $this->_body = gzinflate(substr($this->_body, 10));
             $this->_notify('gotBody', $this->_body);
         } else {
             $this->_notify('gotBody');
         }
     }
     return true;
 }
Exemplo n.º 3
0
 /**
  * Processes a HTTP response
  * 
  * This extracts response code, headers, cookies and decodes body if it 
  * was encoded in some way
  *
  * @access public
  * @param  bool      Whether to store response body in object property, set
  *                   this to false if downloading a LARGE file and using a Listener.
  *                   This is assumed to be true if body is gzip-encoded.
  * @param  bool      Whether the response can actually have a message-body.
  *                   Will be set to false for HEAD requests.
  * @throws PEAR_Error
  * @return mixed     true on success, PEAR_Error in case of malformed response
  */
 function process($saveBody = true, $canHaveBody = true)
 {
     do {
         $line = $this->_sock->readLine();
         if (sscanf($line, 'HTTP/%s %s', $http_version, $returncode) != 2) {
             return PEAR::raiseError('Malformed response.');
         } else {
             $this->_protocol = 'HTTP/' . $http_version;
             $this->_code = intval($returncode);
         }
         while ('' !== ($header = $this->_sock->readLine())) {
             $this->_processHeader($header);
         }
     } while (100 == $this->_code);
     $this->_notify('gotHeaders', $this->_headers);
     // RFC 2616, section 4.4:
     // 1. Any response message which "MUST NOT" include a message-body ...
     // is always terminated by the first empty line after the header fields
     // 3. ... If a message is received with both a
     // Transfer-Encoding header field and a Content-Length header field,
     // the latter MUST be ignored.
     $canHaveBody = $canHaveBody && $this->_code >= 200 && $this->_code != 204 && $this->_code != 304;
     // If response body is present, read it and decode
     $chunked = isset($this->_headers['transfer-encoding']) && 'chunked' == $this->_headers['transfer-encoding'];
     $gzipped = isset($this->_headers['content-encoding']) && 'gzip' == $this->_headers['content-encoding'];
     $hasBody = false;
     if ($canHaveBody && ($chunked || !isset($this->_headers['content-length']) || 0 != $this->_headers['content-length'])) {
         if ($chunked || !isset($this->_headers['content-length'])) {
             $this->_toRead = null;
         } else {
             $this->_toRead = $this->_headers['content-length'];
         }
         while (!$this->_sock->eof() && (is_null($this->_toRead) || 0 < $this->_toRead)) {
             if ($chunked) {
                 $data = $this->_readChunked();
             } elseif (is_null($this->_toRead)) {
                 $data = $this->_sock->read(4096);
             } else {
                 $data = $this->_sock->read(min(4096, $this->_toRead));
                 $this->_toRead -= strlen($data);
             }
             if ('' == $data) {
                 break;
             } else {
                 $hasBody = true;
                 if ($saveBody || $gzipped) {
                     $this->_body .= $data;
                 }
                 $this->_notify($gzipped ? 'gzTick' : 'tick', $data);
             }
         }
     }
     if ($hasBody) {
         // Uncompress the body if needed
         if ($gzipped) {
             $body = $this->_decodeGzip($this->_body);
             if (PEAR::isError($body)) {
                 return $body;
             }
             $this->_body = $body;
             $this->_notify('gotBody', $this->_body);
         } else {
             $this->_notify('gotBody');
         }
     }
     return true;
 }