private function send($ch): HttpResponse
    {
        $returnHeaders = array();
        curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$returnHeaders) {
            if (strpos($header, ':') !== false) {
                list($name, $value) = explode(':', $header);
                if (!array_key_exists($name, $returnHeaders)) {
                    $returnHeaders[$name] = array();
                }

                $returnHeaders[$name][] = trim($value);
            }

            return strlen($header);
        });

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        // Ensure we are coping with 300 (redirect) responses:
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_HEADER, true);

        // Set request timeout
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout);

        // Set verification of SSL certificates
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verifySslCertificate);

        if (!empty($this->username)) {
            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
            curl_setopt($ch, CURLOPT_USERPWD, "$this->username:$this->password");
        }

        $response = curl_exec($ch);
        $requestInfo = curl_getinfo($ch);
        $error = curl_error($ch);

        if (!empty($error)) {
            throw new HttpRequestException($error);
        }

        $httpResponse = new HttpResponse($requestInfo, $returnHeaders, $response, $error);

        return $httpResponse;
    }