/** * Perform a request to the server and return the result * * Perform a request to the server and return the result converted into a * Response object. If you do not expect a JSON structure, which * could be converted in such a response object, set the forth parameter to * true, and you get a response object retuerned, containing the raw body. * * @param string $method * @param string $path * @param string $data * @param bool $raw * @return Response * @throws HTTPException */ public function request($method, $path, $data = null, $raw = false) { $basicAuth = ''; if ($this->options['username']) { $basicAuth .= "{$this->options['username']}:{$this->options['password']}@"; } // TODO SSL support? $httpFilePointer = @fopen('http://' . $basicAuth . $this->options['host'] . ':' . $this->options['port'] . $path, 'r', false, stream_context_create(array('http' => array('method' => $method, 'content' => $data, 'ignore_errors' => true, 'max_redirects' => 0, 'user_agent' => 'Doctrine CouchDB ODM $Revision$', 'timeout' => $this->options['timeout'], 'header' => 'Content-type: application/json')))); // Check if connection has been established successfully if ($httpFilePointer === false) { $error = error_get_last(); throw HTTPException::connectionFailure($this->options['ip'], $this->options['port'], $error['message'], 0); } // Read request body $body = ''; while (!feof($httpFilePointer)) { $body .= fgets($httpFilePointer); } $metaData = stream_get_meta_data($httpFilePointer); // The structure of this array differs depending on PHP compiled with // --enable-curlwrappers or not. Both cases are normally required. $rawHeaders = isset($metaData['wrapper_data']['headers']) ? $metaData['wrapper_data']['headers'] : $metaData['wrapper_data']; $headers = array(); foreach ($rawHeaders as $lineContent) { // Extract header values if (preg_match('(^HTTP/(?P<version>\\d+\\.\\d+)\\s+(?P<status>\\d+))S', $lineContent, $match)) { $headers['version'] = $match['version']; $headers['status'] = (int) $match['status']; } else { list($key, $value) = explode(':', $lineContent, 2); $headers[strtolower($key)] = ltrim($value); } } if (empty($headers['status'])) { throw HTTPException::readFailure($this->options['ip'], $this->options['port'], 'Received an empty response or not status code', 0); } // Create repsonse object from couch db response if ($headers['status'] >= 400) { return new ErrorResponse($headers['status'], $headers, $body); } return new Response($headers['status'], $headers, $body, $raw); }
/** * Perform request to the source, parse the multipart response, * stream the documents with attachments to the target and return * the responses along with docs that did not have any attachments. * * @param string $sourceMethod * @param string $sourcePath * @param string $targetPath * @param string $sourceData * @param array $sourceHeaders * @return array|ErrorResponse|string * @throws HTTPException * @throws \Exception */ public function request($sourceMethod, $sourcePath, $targetPath, $sourceData = null, array $sourceHeaders = array()) { $this->sourceConnection = $this->sourceClient->getConnection($sourceMethod, $sourcePath, $sourceData, $sourceHeaders); $sourceResponseHeaders = $this->sourceClient->getStreamHeaders(); $body = ''; if (empty($sourceResponseHeaders['status'])) { try { // Close the connection resource. fclose($this->sourceConnection); } catch (\Exception $e) { } throw HTTPException::readFailure($this->sourceClient->getOptions()['ip'], $this->sourceClient->getOptions()['port'], 'Received an empty response or not status code', 0); } elseif ($sourceResponseHeaders['status'] != 200) { while (!feof($this->sourceConnection)) { $body .= fgets($this->sourceConnection); } try { fclose($this->sourceConnection); } catch (\Exception $e) { } return new ErrorResponse($sourceResponseHeaders['status'], $sourceResponseHeaders, $body); } else { try { // Body is an array containing: // 1) Array of json string documents that don't have // attachments. These should be posted using the Bulk API. // 2) Responses of posting docs with attachments. $body = $this->parseAndSend($targetPath); try { fclose($this->sourceConnection); } catch (\Exception $e) { } return $body; } catch (\Exception $e) { throw $e; } } }
/** * Perform a request to the server and return the result * * Perform a request to the server and return the result converted into a * Response object. If you do not expect a JSON structure, which * could be converted in such a response object, set the forth parameter to * true, and you get a response object returned, containing the raw body. * * @param string $method * @param string $path * @param string $data * @param bool $raw * @param array $headers * @return Response * @throws HTTPException */ public function request($method, $path, $data = null, $raw = false, array $headers = array()) { $fullPath = $path; if ($this->options['path']) { $fullPath = '/' . $this->options['path'] . $path; } $this->checkConnection($method, $fullPath, $data, $headers); // Read request body. $body = ''; while (!feof($this->httpFilePointer)) { $body .= fgets($this->httpFilePointer); } $headers = $this->getStreamHeaders(); if (empty($headers['status'])) { throw HTTPException::readFailure($this->options['ip'], $this->options['port'], 'Received an empty response or not status code', 0); } // Create response object from couch db response. if ($headers['status'] >= 400) { return new ErrorResponse($headers['status'], $headers, $body); } return new Response($headers['status'], $headers, $body, $raw); }