/**
  * Create a request string (header and body)
  *
  * @param ConnectionOptions $options - connection options
  * @param string            $method  - HTTP method
  * @param string            $url     - HTTP URL
  * @param string            $body    - optional body to post
  * @param array             $customHeader - any arry containing header elements
  *
  * @return string - assembled HTTP request string
  */
 public static function buildRequest(ConnectionOptions $options, $method, $url, $body, $customHeader = array())
 {
     $host = $contentType = $authorization = $connection = '';
     $length = strlen($body);
     $endpoint = $options[ConnectionOptions::OPTION_ENDPOINT];
     if (Endpoint::getType($endpoint) !== Endpoint::TYPE_UNIX) {
         $host = sprintf('Host: %s%s', Endpoint::getHost($endpoint), self::EOL);
     }
     if ($options[ConnectionOptions::OPTION_BATCH] === true) {
         $contentType = 'Content-Type: multipart/form-data; boundary=' . self::MIME_BOUNDARY . self::EOL;
     } else {
         if ($length > 0 && $options[ConnectionOptions::OPTION_BATCHPART] === false) {
             // if body is set, we should set a content-type header
             $contentType = 'Content-Type: application/json' . self::EOL;
         }
     }
     if (isset($options[ConnectionOptions::OPTION_AUTH_TYPE]) && isset($options[ConnectionOptions::OPTION_AUTH_USER])) {
         // add authorization header
         $authorizationValue = base64_encode($options[ConnectionOptions::OPTION_AUTH_USER] . ':' . $options[ConnectionOptions::OPTION_AUTH_PASSWD]);
         $authorization = sprintf('Authorization: %s %s%s', $options[ConnectionOptions::OPTION_AUTH_TYPE], $authorizationValue, self::EOL);
     }
     if (isset($options[ConnectionOptions::OPTION_CONNECTION])) {
         // add connection header
         $connection = sprintf("Connection: %s%s", $options[ConnectionOptions::OPTION_CONNECTION], self::EOL);
     }
     $apiVersion = 'X-Arango-Version: ' . Connection::$_apiVersion . self::EOL;
     $customHeaders = "";
     foreach ($customHeader as $headerKey => $headerValue) {
         $customHeaders .= $headerKey . ": " . $headerValue . self::EOL;
     }
     // finally assemble the request
     $request = sprintf('%s %s %s%s', $method, $url, self::PROTOCOL, self::EOL) . $host . $apiVersion . $customHeaders . $contentType . $authorization . $connection . sprintf('Content-Length: %s%s%s', $length, self::EOL, self::EOL) . $body;
     return $request;
 }
 /**
  * Validate the options
  *
  * @throws ClientException
  * @return void - will throw if an invalid option value is found
  */
 private function validate()
 {
     if (isset($this->_values[self::OPTION_HOST]) && !is_string($this->_values[self::OPTION_HOST])) {
         throw new ClientException('host should be a string');
     }
     if (isset($this->_values[self::OPTION_PORT]) && !is_int($this->_values[self::OPTION_PORT])) {
         throw new ClientException('port should be an integer');
     }
     // can use either endpoint or host/port
     if (isset($this->_values[self::OPTION_HOST]) && isset($this->_values[self::OPTION_ENDPOINT])) {
         throw new ClientException('must not specify both host and endpoint');
     } else {
         if (isset($this->_values[self::OPTION_HOST]) && !isset($this->_values[self::OPTION_ENDPOINT])) {
             // upgrade host/port to an endpoint
             $this->_values[self::OPTION_ENDPOINT] = 'tcp://' . $this->_values[self::OPTION_HOST] . ':' . $this->_values[self::OPTION_PORT];
         }
     }
     assert(isset($this->_values[self::OPTION_ENDPOINT]));
     // set up a new endpoint, this will also validate it
     $this->getEndpoint();
     if (Endpoint::getType($this->_values[self::OPTION_ENDPOINT]) === Endpoint::TYPE_UNIX) {
         // must set port to 0 for UNIX sockets
         $this->_values[self::OPTION_PORT] = 0;
     }
     if (isset($this->_values[self::OPTION_AUTH_TYPE]) && !in_array($this->_values[self::OPTION_AUTH_TYPE], self::getSupportedAuthTypes())) {
         throw new ClientException('unsupported authorization method');
     }
     if (isset($this->_values[self::OPTION_CONNECTION]) && !in_array($this->_values[self::OPTION_CONNECTION], self::getSupportedConnectionTypes())) {
         throw new ClientException(sprintf("unsupported connection value '%s'", $this->_values[self::OPTION_CONNECTION]));
     }
     UpdatePolicy::validate($this->_values[self::OPTION_UPDATE_POLICY]);
     UpdatePolicy::validate($this->_values[self::OPTION_REPLACE_POLICY]);
     UpdatePolicy::validate($this->_values[self::OPTION_DELETE_POLICY]);
 }