public function send(Requests\Request $request) {
        
        if($request instanceof Requests\Batch && count($request->requests) > Client::BATCH_MAX_SIZE)
            return $this->sendMultipartBatch($request);

        $this->request = $request;
        $path = Util::sliceDbName($request->getPath());
        $request_url =  $path . $this->paramsToUrl($request->getQueryParameters());
        $signed_url = $this->signUrl($request_url);
        $protocol = ($request->getEnsureHttps()) ? 'https' : $this->protocol;
        $uri = $protocol . '://' . $this->base_uri . $signed_url;
        $timeout = $request->getTimeout() / 1000;
        $result = null;

        try {
            switch ($request->getMethod()) {
                case Requests\Request::HTTP_GET:
                    $result = $this->get($uri, $timeout);
                    break;

                case Requests\Request::HTTP_PUT:
                    $json = json_encode($request->getBodyParameters(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
                    $result = $this->put($uri, $timeout, $json);
                    break;

                case Requests\Request::HTTP_DELETE:
                    $result = $this->delete($uri, $timeout);
                    break;

                case Requests\Request::HTTP_POST:
                    $json = json_encode($request->getBodyParameters(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
                    $result = $this->post($uri, $timeout, $json);
                    break;
            }
        }
        catch(\Requests_Exception $e)
        {
            if(strpos($e->getMessage(), 'cURL error 28') !== false) throw new ApiTimeoutException($request);
            if(strpos($e->getMessage(), 'timed out') !== false) throw new ApiTimeoutException($request);

            throw $e;
        }

        return $result;
    }