Example #1
0
 /**
  * Callback function called by cURL for saving the response headers
  *
  * @param    resource    cURL handle
  * @param    string      response header (with trailing CRLF)
  * @return   integer     number of bytes saved
  * @see      HTTP_Request2_Response::parseHeaderLine()
  */
 protected function callbackWriteHeader($ch, $string)
 {
     // we may receive a second set of headers if doing e.g. digest auth
     if ($this->eventReceivedHeaders || !$this->eventSentHeaders) {
         // don't bother with 100-Continue responses (bug #15785)
         if (!$this->eventSentHeaders || $this->response->getStatus() >= 200) {
             $this->request->setLastEvent('sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT));
         }
         $this->eventSentHeaders = true;
         // we'll need a new response object
         if ($this->eventReceivedHeaders) {
             $this->eventReceivedHeaders = false;
             $this->response = null;
         }
     }
     if (empty($this->response)) {
         $this->response = new HTTP_Request2_Response($string, false);
     } else {
         $this->response->parseHeaderLine($string);
         if ('' == trim($string)) {
             // don't bother with 100-Continue responses (bug #15785)
             if (200 <= $this->response->getStatus()) {
                 $this->request->setLastEvent('receivedHeaders', $this->response);
             }
             $this->eventReceivedHeaders = true;
         }
     }
     return strlen($string);
 }
Example #2
0
 /**
  * Callback function called by cURL for saving the response headers
  *
  * @param    resource    cURL handle
  * @param    string      response header (with trailing CRLF)
  * @return   integer     number of bytes saved
  * @see      HTTP_Request2_Response::parseHeaderLine()
  */
 protected function callbackWriteHeader($ch, $string)
 {
     // we may receive a second set of headers if doing e.g. digest auth
     if ($this->eventReceivedHeaders || !$this->eventSentHeaders) {
         // don't bother with 100-Continue responses (bug #15785)
         if (!$this->eventSentHeaders || $this->response->getStatus() >= 200) {
             $this->request->setLastEvent('sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT));
         }
         $upload = curl_getinfo($ch, CURLINFO_SIZE_UPLOAD);
         // if body wasn't read by a callback, send event with total body size
         if ($upload > $this->position) {
             $this->request->setLastEvent('sentBodyPart', $upload - $this->position);
             $this->position = $upload;
         }
         if ($upload && (!$this->eventSentHeaders || $this->response->getStatus() >= 200)) {
             $this->request->setLastEvent('sentBody', $upload);
         }
         $this->eventSentHeaders = true;
         // we'll need a new response object
         if ($this->eventReceivedHeaders) {
             $this->eventReceivedHeaders = false;
             $this->response = null;
         }
     }
     if (empty($this->response)) {
         $this->response = new HTTP_Request2_Response($string, false);
     } else {
         $this->response->parseHeaderLine($string);
         if ('' == trim($string)) {
             // don't bother with 100-Continue responses (bug #15785)
             if (200 <= $this->response->getStatus()) {
                 $this->request->setLastEvent('receivedHeaders', $this->response);
             }
             if ($this->request->getConfig('follow_redirects') && $this->response->isRedirect()) {
                 $redirectUrl = new Net_URL2($this->response->getHeader('location'));
                 // for versions lower than 5.2.10, check the redirection URL protocol
                 if (!defined('CURLOPT_REDIR_PROTOCOLS') && $redirectUrl->isAbsolute() && !in_array($redirectUrl->getScheme(), array('http', 'https'))) {
                     return -1;
                 }
                 if ($jar = $this->request->getCookieJar()) {
                     $jar->addCookiesFromResponse($this->response, $this->request->getUrl());
                     if (!$redirectUrl->isAbsolute()) {
                         $redirectUrl = $this->request->getUrl()->resolve($redirectUrl);
                     }
                     if ($cookies = $jar->getMatching($redirectUrl, true)) {
                         curl_setopt($ch, CURLOPT_COOKIE, $cookies);
                     }
                 }
             }
             $this->eventReceivedHeaders = true;
         }
     }
     return strlen($string);
 }
Example #3
0
 /**
  * Creates a array of responses from the batch response body.
  * 
  * @param string            $body           The HTTP response body.
  * @param IMimeReaderWriter $mimeSerializer The MIME reader and writer.
  * 
  * @return array
  */
 private static function _constructResponses($body, $mimeSerializer)
 {
     $responses = array();
     $parts = $mimeSerializer->decodeMimeMultipart($body);
     // Decrease the count of parts to remove the batch response body and just
     // include change sets response body. We may need to undo this action in
     // case that batch response body has useful info.
     $count = count($parts) - 1;
     for ($i = 0; $i < $count; $i++) {
         $lines = explode("\r\n", $parts[$i]);
         $response = new \HTTP_Request2_Response($lines[0]);
         $j = 1;
         do {
             $headerLine = $lines[$j++];
             $response->parseHeaderLine($headerLine);
         } while (Resources::EMPTY_STRING != $headerLine);
         $body = implode("\r\n", array_slice($lines, $j));
         $response->appendBody($body);
         $responses[] = $response;
     }
     return $responses;
 }
 /**
  * Constructor
  *
  * @param string                                         $content Http response
  * as string
  *
  * @param WindowsAzure\Common\Internal\Http\BatchRequest $request Source batch
  * request object
  */
 public function __construct($content, $request = null)
 {
     $params['include_bodies'] = true;
     $params['input'] = $content;
     $mimeDecoder = new \Mail_mimeDecode($content);
     $structure = $mimeDecoder->decode($params);
     $parts = $structure->parts;
     $this->_contexts = array();
     $requestContexts = null;
     if ($request != null) {
         Validate::isA($request, 'WindowsAzure\\Common\\Internal\\Http\\BatchRequest', 'request');
         $requestContexts = $request->getContexts();
     }
     $i = 0;
     foreach ($parts as $part) {
         if (!empty($part->body)) {
             $headerEndPos = strpos($part->body, "\r\n\r\n");
             $header = substr($part->body, 0, $headerEndPos);
             $body = substr($part->body, $headerEndPos + 4);
             $headerStrings = explode("\r\n", $header);
             $response = new \HTTP_Request2_Response(array_shift($headerStrings));
             foreach ($headerStrings as $headerString) {
                 $response->parseHeaderLine($headerString);
             }
             $response->appendBody($body);
             $this->_contexts[] = $response;
             if (is_array($requestContexts)) {
                 $expectedCodes = $requestContexts[$i]->getStatusCodes();
                 $statusCode = $response->getStatus();
                 if (!in_array($statusCode, $expectedCodes)) {
                     $reason = $response->getReasonPhrase();
                     throw new ServiceException($statusCode, $reason, $body);
                 }
             }
             $i++;
         }
     }
 }
Example #5
0
 /**
  * Reads the remote server's response
  *
  * @return   HTTP_Request2_Response
  * @throws   HTTP_Request2_Exception
  */
 protected function readResponse()
 {
     $bufferSize = $this->request->getConfig('buffer_size');
     do {
         $response = new HTTP_Request2_Response($this->readLine($bufferSize), true);
         do {
             $headerLine = $this->readLine($bufferSize);
             $response->parseHeaderLine($headerLine);
         } while ('' != $headerLine);
     } while (in_array($response->getStatus(), array(100, 101)));
     $this->request->setLastEvent('receivedHeaders', $response);
     // No body possible in such responses
     if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() || HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() && 200 <= $response->getStatus() && 300 > $response->getStatus() || in_array($response->getStatus(), array(204, 304))) {
         return $response;
     }
     $chunked = 'chunked' == $response->getHeader('transfer-encoding');
     $length = $response->getHeader('content-length');
     $hasBody = false;
     if ($chunked || null === $length || 0 < intval($length)) {
         // RFC 2616, section 4.4:
         // 3. ... If a message is received with both a
         // Transfer-Encoding header field and a Content-Length header field,
         // the latter MUST be ignored.
         $toRead = $chunked || null === $length ? null : $length;
         $this->chunkLength = 0;
         while (!feof($this->socket) && (is_null($toRead) || 0 < $toRead)) {
             if ($chunked) {
                 $data = $this->readChunked($bufferSize);
             } elseif (is_null($toRead)) {
                 $data = $this->fread($bufferSize);
             } else {
                 $data = $this->fread(min($toRead, $bufferSize));
                 $toRead -= strlen($data);
             }
             if ('' == $data && (!$this->chunkLength || feof($this->socket))) {
                 break;
             }
             $hasBody = true;
             if ($this->request->getConfig('store_body')) {
                 $response->appendBody($data);
             }
             if (!in_array($response->getHeader('content-encoding'), array('identity', null))) {
                 $this->request->setLastEvent('receivedEncodedBodyPart', $data);
             } else {
                 $this->request->setLastEvent('receivedBodyPart', $data);
             }
         }
     }
     if ($hasBody) {
         $this->request->setLastEvent('receivedBody', $response);
     }
     return $response;
 }
Example #6
0
 protected function readResponseFromFile($filename)
 {
     $fp = fopen(dirname(dirname(__FILE__)) . '/_files/' . $filename, 'rb');
     $response = new HTTP_Request2_Response(fgets($fp));
     do {
         $headerLine = fgets($fp);
         $response->parseHeaderLine($headerLine);
     } while ('' != trim($headerLine));
     while (!feof($fp)) {
         $response->appendBody(fread($fp, 1024));
     }
     return $response;
 }
Example #7
0
 /**
  * Creates a new HTTP_Request2_Response object from a file
  *
  * @param    resource    file pointer returned by fopen()
  * @return   HTTP_Request2_Response
  * @throws   HTTP_Request2_Exception
  */
 public static function createResponseFromFile($fp)
 {
     $response = new HTTP_Request2_Response(fgets($fp));
     do {
         $headerLine = fgets($fp);
         $response->parseHeaderLine($headerLine);
     } while ('' != trim($headerLine));
     while (!feof($fp)) {
         $response->appendBody(fread($fp, 8192));
     }
     return $response;
 }
Example #8
0
 /**
  * Reads the remote server's response
  *
  * @return   HTTP_Request2_Response
  * @throws   HTTP_Request2_Exception
  */
 protected function readResponse()
 {
     $bufferSize = $this->request->getConfig('buffer_size');
     // http://tools.ietf.org/html/rfc2616#section-8.2.3
     // ...the client SHOULD NOT wait for an indefinite period before sending the request body
     $timeout = $this->expect100Continue ? 1 : null;
     do {
         try {
             $response = new HTTP_Request2_Response($this->socket->readLine($bufferSize, $timeout), true, $this->request->getUrl());
             do {
                 $headerLine = $this->socket->readLine($bufferSize);
                 $response->parseHeaderLine($headerLine);
             } while ('' != $headerLine);
         } catch (HTTP_Request2_MessageException $e) {
             if (HTTP_Request2_Exception::TIMEOUT === $e->getCode() && $this->expect100Continue) {
                 return null;
             }
             throw $e;
         }
         if ($this->expect100Continue && 100 == $response->getStatus()) {
             return $response;
         }
     } while (in_array($response->getStatus(), array(100, 101)));
     $this->request->setLastEvent('receivedHeaders', $response);
     // No body possible in such responses
     if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() || HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() && 200 <= $response->getStatus() && 300 > $response->getStatus() || in_array($response->getStatus(), array(204, 304))) {
         return $response;
     }
     $chunked = 'chunked' == $response->getHeader('transfer-encoding');
     $length = $response->getHeader('content-length');
     $hasBody = false;
     if ($chunked || null === $length || 0 < intval($length)) {
         // RFC 2616, section 4.4:
         // 3. ... If a message is received with both a
         // Transfer-Encoding header field and a Content-Length header field,
         // the latter MUST be ignored.
         $toRead = $chunked || null === $length ? null : $length;
         $this->chunkLength = 0;
         while (!$this->socket->eof() && (is_null($toRead) || 0 < $toRead)) {
             if ($chunked) {
                 $data = $this->readChunked($bufferSize);
             } elseif (is_null($toRead)) {
                 $data = $this->socket->read($bufferSize);
             } else {
                 $data = $this->socket->read(min($toRead, $bufferSize));
                 $toRead -= strlen($data);
             }
             if ('' == $data && (!$this->chunkLength || $this->socket->eof())) {
                 break;
             }
             $hasBody = true;
             if ($this->request->getConfig('store_body')) {
                 $response->appendBody($data);
             }
             if (!in_array($response->getHeader('content-encoding'), array('identity', null))) {
                 $this->request->setLastEvent('receivedEncodedBodyPart', $data);
             } else {
                 $this->request->setLastEvent('receivedBodyPart', $data);
             }
         }
     }
     if ($hasBody) {
         $this->request->setLastEvent('receivedBody', $response);
     }
     return $response;
 }