Perform an HTTP request, checking for curl extension support

@param $action
@param array $data
@param string $method
@param array $options
@return string
@throws Sailthru_Client_Exception
183126
protected function httpRequest($action, $data, $method = 'POST', $options = [ ]) {
        $response = $this->{$this->http_request_type}($action, $data, $method, $options);
        $json = json_decode($response, true);
        if ($json === NULL) {
            throw new Sailthru_Client_Exception(
                "Response: {$response} is not a valid JSON",
                Sailthru_Client_Exception::CODE_RESPONSE_INVALID
            );
        }
        if (!empty($json['error'])) {
            throw new Sailthru_Client_Exception($json['errormsg'], $json['error']);
        }

        return $json;
    }
132425
public function request($method, $uri, array $parameters = [], array $options = [])
    {
        $parameters['key'] = $this->apiKey;
        $options['query'] = $parameters;

        $uri = $this->apiUrl.$uri.'/json';

        $this->log($method, $uri, $options);
        $response = $this->httpClient->request($method, $uri, $options);

        $result = $this->decoder->decode($response);

        if (!isset($result['status'])) {
            throw new ClientErrorException('Missing return status');
        }

        if (!in_array($result['status'], [
                'OK',
                'ZERO_RESULTS',
            ], true)) {
            throw new ClientErrorException(sprintf('Invalid return status "%s"', $result['status']));
        }

        return $result;
    }
377561
public function perform($action, $table, $body, $options = [])
    {
        $query = $this->createQuery($action, $table, $options)->body($body);

        return $this->createRequest($query);
    }
552062
protected function doRequest($data = null, $options = array())
    {
        $endpoint = isset($options['endpoint']) ? $options['endpoint'] : '';
        $verb = isset($options['verb']) ? $options['verb'] : 'GET';
        $url = $this->_gatewayUrlForKey() . '/' . $endpoint;

        if (isset($this->limit) && isset($this->offset)) {
            $paging = array(
                'limit'  => $this->limit,
                'offset' => $this->offset,
            );
            $url .= '?' . http_build_query($paging);
        }

        if ($this->searchFields != null) {
            $data = $this->searchFields;
        }

        $encodedData = json_encode($data);

        $identity = array();
        if (isset($this->_config->siteId)) {
            $identity[0] = 'SiteID='.$this->_config->siteId;
        }
        if (isset($this->_config->deviceId)) {
            $identity[1] = 'DeviceID='.$this->_config->deviceId;
        }
        if (isset($this->_config->licenseId)) {
            $identity[2] = 'LicenseID='.$this->_config->licenseId;
        }

        $auth = isset($this->_config->username)
            ? $this->_config->username.':'.$this->_config->password
            : $this->_config->secretApiKey;
        $header = array(
            'Authorization: Basic '.base64_encode($auth),
            'Content-Type: application/json; charset=utf-8',
            'Content-Length: '.strlen($encodedData),
        );

        if (isset($this->_config->username)) {
            $header[] = 'HPS-Identity: '.implode(',', $identity);
        }
        $keyType = HpsServicesConfig::KEY_TYPE_SECRET;
        // print "\n" . $encodedData;
        return $this->submitRequest($url, $header, $encodedData, $verb, $keyType);
    }
360934
private function sendRequest($method, $url, array $options = [])
    {
        $response = $this->httpClient->request((string)$method, $url, $options);

        return json_decode($response->getBody(), true);
    }
754348
private function sendRequest($method, $url, $data = false)
    {
        $curlHandler = curl_init();
        curl_setopt($curlHandler, CURLOPT_HTTPHEADER, $this->formatUserAgentInfo());

        if ($method === 'POST') {
            curl_setopt($curlHandler, CURLOPT_POST, 1);

            if ($data) {
                curl_setopt($curlHandler, CURLOPT_POSTFIELDS, json_encode($data));
            }
        }

        if ($method === 'GET' && $data) {
            $url = sprintf("%s?%s", $url, http_build_query($data));
        }

        curl_setopt($curlHandler, CURLOPT_URL, $url);
        curl_setopt($curlHandler, CURLOPT_RETURNTRANSFER, 1);

        $this->response = curl_exec($curlHandler);

        $this->curlInfo = curl_getinfo($curlHandler);
        $httpCode = curl_getinfo($curlHandler)['http_code'];

        if ($httpCode >= 400) {
            throw new \Exception($this->json()['status'], $httpCode);
        }

        curl_close($curlHandler);

        return $this;
    }
353253
public function sendRequest($action, $data)
    {
        if (!$this->connected) {
            $this->connect();
        }
        try {
            $result = $this->client->__soapCall($action, $data);
        } catch (SoapFault $fault) {
            $this->handleError($fault->faultstring);
        }

        return $result;
    }
289059
protected function request($url, $method = 'GET', array $data = [])
    {
        try {
            return call_user_func_array([$this, strtolower($method)], [$url, $data]);
        } catch (\Exception $exception) {
            throw new \RuntimeException('Http method is not valid.');
        }
    }
8622
public function action($action, $options = [])
    {
        if ($this->shouldValidate) $this->validate();
        if ($this->shouldCallGuard) $this->guard();
        if ($this->shouldFallThrough) return $this;

        if (is_string($action) && !class_exists($action)) {
            throw new Exception("{$action} does not exist.");
        }

        if (!is_subclass_of($action, Action::class)) {
            throw new Exception('Actions must extend '.Action::class.'.');
        }

        if (is_string($action)) {
            $action = new $action($this, $options);
        }

        $this->perform($action);

        return $this;
    }
1138130
private function request($method, $uri, array $options = array())
    {
        $options['auth'] = array($this->accessKey, $this->secretKey);

        return $this->httpClient->request($method, $uri, $options);
    }
1354459
protected function _doRequest($method, $url, $data, $options)
    {
        $request = $this->_createRequest(
            $method,
            $url,
            $data,
            $options
        );

        return $this->send($request, $options);
    }
63551
protected function doRequest($method, $apiMethod, array $data = [])
    {
        $url = $this->config['endpoint'] . $apiMethod;
        $data = $this->mergeData($this->createAuthData(), $data);

        $response = $this->getGuzzleClient()->request($method, $url, ['json' => $data]);
        $responseContent = \GuzzleHttp\json_decode($response->getBody());

        if (!property_exists($responseContent, 'success') || !$responseContent->success) {
            throw new InvalidRequestException($method, $url, $data, $response);
        }

        return $responseContent;
    }
1044893
public function request(string $method, string $url, $options = []): array
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        if (isset($options['body'])) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($options['body']) ? http_build_query($options['body']) : $options['body']);
        }
        if (SmsConfig::getTimeout() > 0) {
            curl_setopt($ch, CURLOPT_TIMEOUT, SmsConfig::getTimeout());
        }
        if (SmsConfig::getConnectTimeout()) {
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, SmsConfig::getConnectTimeout());
        }
        //https request
        if (strlen($url) > 5 && strtolower(substr($url, 0, 5)) == "https") {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        if (isset($options['headers']) && is_array($options['headers']) && 0 < count($options['headers'])) {
            $http_headers = $this->getHttpHearders($options['headers']);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $http_headers);
        }
        $content = curl_exec($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        return [$code, $content];
    }
1286517
public function request($method, $uri, $options = [])
    {
        if ($this->authorization !== null) {
            $authHeader = sprintf('%s %s', $this->authorization->getAuthType(), $this->authorization->getCredentials());
            $headers = isset($options['headers']) ? $options['headers'] : [];
            $headers['Authorization'] = $authHeader;
            $options['headers'] = $headers;
        }

        if (!isset($options['retries'])) {
            $options['retries'] = $this->maxRetries;
        }

        return $this->requestHub($method, $uri, $options);
    }
487891
public static function request($resource, $method, array $data = null, array $files = null)
    {
        if (!strpos($resource, '://')) {
            if (!strpos($resource, '.')) {
                $resource .= '.json';
            }
            $resource = self::API_URL . $resource;
        }

        $hasCURLFile = class_exists('CURLFile', false) && defined('CURLOPT_SAFE_UPLOAD');

        foreach ((array) $data as $key => $val) {
            if ($val === null) {
                unset($data[$key]);
            } elseif ($files && !$hasCURLFile && substr($val, 0, 1) === '@') {
                throw new TwitterException('Due to limitation of cURL it is not possible to send message starting with @ and upload file at the same time in PHP < 5.5');
            }
        }

        foreach ((array) $files as $key => $file) {
            if (!is_file($file)) {
                throw new TwitterException("Cannot read the file $file. Check if file exists on disk and check its permissions.");
            }
            $data[$key] = $hasCURLFile ? new \CURLFile($file) : '@' . $file;
        }

        $request = Twitter_OAuthRequest::from_consumer_and_token(self::$consumer, self::$token, $method, $resource, $files ? [] : $data);
        $request->sign_request(new Twitter_OAuthSignatureMethod_HMAC_SHA1, self::$consumer, self::$token);

        $options = [
                CURLOPT_HEADER => false,
                CURLOPT_RETURNTRANSFER => true,
            ] + ($method === 'POST' ? [
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $files ? $data : $request->to_postdata(),
                CURLOPT_URL => $files ? $request->to_url() : $request->get_normalized_http_url(),
            ] : [
                CURLOPT_URL => $request->to_url(),
            ]) + self::$httpOptions;

        if ($method === 'POST' && $hasCURLFile) {
            $options[CURLOPT_SAFE_UPLOAD] = true;
        }

        $curl = curl_init();
        curl_setopt_array($curl, $options);
        $result = curl_exec($curl);
        if (curl_errno($curl)) {
            throw new TwitterException('Server error: ' . curl_error($curl));
        }

        $payload = defined('JSON_BIGINT_AS_STRING')
            ? @json_decode($result, false, 128, JSON_BIGINT_AS_STRING)
            : @json_decode($result); // intentionally @

        if ($payload === false) {
            throw new TwitterException('Invalid server response');
        }

        $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        if ($code >= 400) {
            throw new TwitterException(isset($payload->errors[0]->message)
                ? $payload->errors[0]->message
                : "Server error #$code with answer $result",
                $code
            );
        }

        return $payload;
    }
658432
protected function httpRequestCurl($action, array $data, $method = 'POST', $options = [ ]) {
        $url = $this->api_uri . "/" . $action;
        $ch = curl_init();
        $options = array_merge($this->options, $options);
        if ($method == 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            if ($this->fileUpload === true) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                $this->fileUpload = false;
            } else {
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data, '', '&'));
            }
        } else {
            $url .= '?' . http_build_query($data, '', '&');
            if ($method != 'GET') {
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
            }
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
        curl_setopt($ch, CURLOPT_TIMEOUT_MS, $options['timeout']);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $options['connect_timeout']);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->httpHeaders);
        $response = curl_exec($ch);
        $this->lastResponseInfo = curl_getinfo($ch);
        curl_close($ch);

        if (!$response) {
            throw new Sailthru_Client_Exception(
                "Bad response received from $url",
                Sailthru_Client_Exception::CODE_RESPONSE_EMPTY
            );
        }

        // parse headers and body
        $parts = explode("\r\n\r\nHTTP/", $response);
        $parts = (count($parts) > 1 ? 'HTTP/' : '') . array_pop($parts); // deal with HTTP/1.1 100 Continue before other headers
        list($headers, $body) = explode("\r\n\r\n", $parts, 2);
        $this->lastRateLimitInfo[$action][$method] = self::parseRateLimitHeaders($headers);

        return $body;
    }
1010379
protected function request($url, $method, $data = null)
    {
        $this->testLogin();
        try {
            $response = $this->transport->send(
                $url, $method, $data, array(
                'Content-Type: ' . $this->mapper->getContentType(),
                )
            );
        } catch (HttpStatusException $e) {
            $message = $e->getMessage();
            if ($e->getCode() == 403 || $e->getCode() == 422) {
                $this->errors = $this->mapper->mapFromStorage($this->transport->getLastResponse());
                if ($this->errors instanceof ErrorArray && count($this->errors) > 0) {
                    $message .= PHP_EOL . 'Errors:' . PHP_EOL . $this->errors;
                }
            }

            if (self::$debug) {
                printf(
                    'Url: %s' . PHP_EOL . 'Method: %s' . PHP_EOL . 'Data: %s', $url, $method, $data
                );
            }

            switch ($e->getCode()) {
                case 401:
                    throw new NotLoggedInException($message, 0, $e);
                    break;
                case 403:
                    throw new ForbiddenException($message, 0, $e);
                    break;
                case 404:
                    throw new NotFoundException($message, 0, $e);
                    break;
                case 406:
                case 422:
                    throw new NotValidException($message, 0, $e);
                    break;
                default:
                    $message = 'Unknown error; check https://github.com/bluetools/moneybird_php_api/wiki/Common-errors';
                // no break
                case 500:
                case 501:
                    throw new ServerErrorException($message, 0, $e);
                    break;
            }
        }

        return $response;
    }