Send a raw API request, without attempting to handle error responses.

@param $method
@param $path
@param array $options
@param bool $withAuthorization
@return Response
14649
public function raw($method, $path, $options, $withAuthorization = true)
    {
        // Find what traits this class is using.
        $class = get_called_class();
        $traits = Introspector::getAllClassTraits($class);

        if (empty($options['headers'])) {
            // Guzzle doesn't merge default headers with $options array
            $options['headers'] = $this->defaultHeaders ?: [];
        }

        // If these traits have a "hook" (uh oh!), run that before making a request.
        foreach ($traits as $trait) {
            $function = 'run'.Introspector::baseName($trait).'Tasks';
            if (method_exists($class, $method)) {
                $this->{$function}($method, $path, $options, $withAuthorization);
            }
        }

        return $this->client->request($method, $path, $options);
    }
824167
protected function sendRequest(string $method, string $uri, array $options = []): array
    {
        $request = $this->client->createRequest($method, $uri);

        $key = $method === Api::GET ? 'query' : 'form_params';
        $options[$key] = $this->signRequest(
            $method,
            $request->getUri()->__toString(),
            $options[$key] ?? []
        );

        return $this->processResponse(
            $this->client->send($request, $options)
        );
    }
1128559
public function send(string $method, string $url, array $options)
    {
        try {
            // Guzzle overwrites all query string values in the URI if queries are specified
            // in the 'query' option, so they need to be extracted first.
            $optionsPayload = $this->mergeOptions(
                ['query' => $this->parseQueryParams($url)],
                $options
            );

            $response = $this->buildClient()->request($method, $url, $optionsPayload);

            return $this->buildResponse($response);
        } catch (GuzzleException $exception) {
            // No "custom" exceptions, just rethrow whatever guzzle spits out.
            throw $exception;
        }
    }
1198389
public function apiCall($method, $url, $options = [])
    {
        if($this->accessToken === null) {
            throw new TokenMissingException();
        }

        $options['headers']['User-Agent'] = self::USER_AGENT . '/' . self::VERSION;
        $request = $this->getAuthenticatedRequest($method, $url, $this->getAccessToken()->getToken(), $options);
        $request = $this->applyOptions($request, $options);

        return $this->getResponse($request);
    }
175007
protected function newAPIRequest($method, $path, $parameters = [], $options = [])
    {
        $api_path = '/api/v1/' . $path;
        return $this->call($method, $api_path, $parameters, $options);
    }
1054661
public function post($path, $payload = [], $withAuthorization = true)
    {
        $options = [
            'json' => $payload,
        ];

        return $this->send('POST', $path, $options, $withAuthorization);
    }
725658
public function send($method, $path, $options = [], $withAuthorization = true)
    {
        try {
            return parent::send($method, $path, $options, $withAuthorization);
        } catch (ValidationException $e) {
            throw LaravelValidationException::withMessages($e->getErrors());
        } catch (UnauthorizedException $e) {
            throw new \Illuminate\Auth\AuthenticationException;
        } catch (ForbiddenException $e) {
            throw new \Illuminate\Auth\AuthenticationException;
        } catch (InternalException $e) {
            $message = 'Northstar returned an unexpected error for that request.';

            if (config('app.debug')) {
                $message = $e->getMessage();
            }

            throw new HttpException(500, $message);
        }
    }
917006
public function request($method, $uri = null, array $options = [])
    {
        return $this->doRequest($method, $uri, $options);
    }
806030
public function getAuthenticatedRequest($method, $url, $token = null, array $options = null)
    {
        return $this->getRequestFactory()->getRequest($method, $url);
    }
810286
public function request($method = 'GET', $uri = '', $options = [])
    {
        try {
            // Make the request.
            return $this->getClient()->request($method, $uri, $this->getRequestOptions($options));
        } catch (ClientException $e) {
            // We are using token auth and probably token expired.
            if ($this->authMethod == 'token' && $e->getCode() == 401 && ! $this->isThrottledReached()) {
                // Try refresh token.
                $this->fetchToken(true);

                // Try requesting again.
                return $this->request($method, $uri, $options);
            }
            // Clear throttle for this request.
            $this->clearThrottle();
            // Call Failed Request.
            $this->failedRequest($e->getResponse());
        }
    }
905715
private function request($path = 'post/index.json', $method = 'GET', array $data = null, array $options = null, $class = null)
    {
        if (empty($path)) {
            throw new \InvalidArgumentException('Argument "path" cannot be empty');
        }

        if (strtoupper($method) === 'GET') {
            $request_options = ['query' => $data];
        } elseif (strtoupper($method) === 'POST') {
            $request_options = $this->prepareRequestParams($data);
        } else {
            throw new \InvalidArgumentException('Unsupported request method');
        }

        ($this->progress_handler !== null && is_callable($this->progress_handler)) && $request_options['progress'] = $this->progress_handler;
        ($this->debug_log_handler !== null && is_callable($this->debug_log_handler)) && $request_options['debug'] = $this->createDebugStream();

        if (is_array($options)) {
            $request_options = array_replace_recursive($request_options, $options);
        }

        try {
            $response = $this->client->request($method, $path, $request_options);
            $raw_result = (string)$response->getBody();
            $result = json_decode($raw_result, true);

            if (!is_array($result)) {
                if ($this->throw_exceptions === true) {
                    throw new E621Exception(E621Exception::MESSAGE_DATA_INVALID, 0, null, $response);
                } else {
                    $result = [
                        'reason' => E621Exception::MESSAGE_DATA_INVALID,
                        'error'  => 'Response couldn\'t be decoded into array',
                    ];
                }
            }
        } catch (GuzzleConnectException $e) {
            if ($this->throw_exceptions === true) {
                throw new ConnectException($e);
            } else {
                $result = [
                    'reason' => ConnectException::MESSAGE,
                    'error'  => $e->getMessage(),
                ];
            }
        } catch (RequestException $e) {
            $response = $e->getResponse();
            $this->debugLog($e);

            if ($response !== null && $response->getBody() !== null) {
                $raw_result = (string)$response->getBody();
                $result = json_decode($raw_result, true);

                if (!is_array($result)) {
                    $result = 'Request resulted in a `' . $e->getResponse()->getStatusCode() . ' ' . $e->getResponse()->getReasonPhrase() . '` response';

                    if ($this->throw_exceptions === true) {
                        throw new E621Exception($result, 0, $e, $response);
                    }

                    $result = [
                        'reason' => ConnectException::MESSAGE,
                        'error'  => $result,
                    ];
                }
            } else {
                if ($this->throw_exceptions === true) {
                    throw new E621Exception(E621Exception::MESSAGE_REQUEST_ERROR, 0, $e, $response);
                } else {
                    $result = [
                        'reason' => ConnectException::MESSAGE,
                        'error'  => $e->getMessage(),
                    ];
                }
            }
        } catch (GuzzleException $e) {
            if ($this->throw_exceptions === true) {
                throw new E621Exception(E621Exception::MESSAGE_CLIENT_ERROR, 0, $e);
            } else {
                $result = [
                    'reason' => E621Exception::MESSAGE_CLIENT_ERROR,
                    'error'  => $e->getMessage(),
                ];
            }
        } finally {
            $this->endDebugStream();
        }

        // Search for result class if we don't have one, this shouldn't happen but fail safe should be left anyway
        if (empty($class)) {
            $class = Generic::class;
            $method_config = Methods::lookupByPath($path);

            if ($method_config !== null) {
                $class = $method_config['class'];
            }
        }

        /** @noinspection PhpUndefinedVariableInspection */
        return new Response($class, $result, isset($raw_result) ? $raw_result : null);
    }
1138130
private function request($method, $uri, array $options = array())
    {
        $options['auth'] = array($this->accessKey, $this->secretKey);

        return $this->httpClient->request($method, $uri, $options);
    }
241130
protected function sendRequest($path, $method = 'GET', $data = array(), $useToken = true)
    {
        $url = $this->apiUrl . '/' . $path;
        $method = strtoupper($method);
        $curl = curl_init();

        if ($useToken && !empty($this->token)) {
            $headers = array('Authorization: Bearer ' . $this->token);
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        }

        switch ($method) {
            case 'POST':
                curl_setopt($curl, CURLOPT_POST, count($data));
                curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
                break;
            case 'PUT':
                curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
                curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
                break;
            case 'DELETE':
                curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
                curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
                break;
            default:
                if (!empty($data)) {
                    $url .= '?' . http_build_query($data);
                }
        }

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, true);
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 15);
        curl_setopt($curl, CURLOPT_TIMEOUT, 15);

        $response = curl_exec($curl);
        $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
        $headerCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $responseBody = substr($response, $header_size);

        curl_close($curl);

        if ($headerCode === 401 && $this->refreshToken === 0) {
            ++$this->refreshToken;
            $this->getToken();
            $retval = $this->sendRequest($path, $method, $data);
        } else {
            $retval = new stdClass();
            $retval->data = json_decode($responseBody);
            $retval->http_code = $headerCode;
        }

        return $retval;
    }
667809
private function performRequest($method, $url, $options) {

        try {
            switch ($method) {
                case 'GET':
                    return json_decode($this->client->get($url, $options)->getBody(), true);
                case 'POST':
                    return json_decode($this->client->post($url, $options)->getBody(), true);
                case 'PUT':
                    return json_decode($this->client->put($url, $options)->getBody(), true);
                case 'DELETE':
                    return json_decode($this->client->delete($url, $options)->getBody(), true);
                default:
                    return null;
            }
        } catch (RequestException $e) {
            throw ApiException::create($e);
        }
    }
3730
private function _call($method, $path, $param, $header = false) {
    // Clear connection; Set timeout, and json header.
    $this->curl->resetConnection();

    // Set additional headers.
    if ($header) {
      foreach ($header as $name => $value) {
        $this->curl->setHeader($name, $value);
      }
    }

    // Make an API request to the GDAX server.
    if ($param) {
      // If the method is not GET, pass JSON in the request body.
      $payload = false;
      if ($method != 'GET') {
        $param = json_encode($param);
        $payload = true;
      }
      $this->curl->{strtolower($method)}("$this->api/$path", $param, $payload);
    } else {
      $this->curl->{strtolower($method)}("$this->api/$path");
    }

    // TODO: Move error logs out of class. ~: Monolog
    // Error Logging
    if ($this->curl->error) {
      $this->_error[] = "$path: {$this->curl->error_message}";
      if ($this->_debug) {
        $this->_error[] = $this->_dump($path, $param);
      }
    }

    if (is_null($ret = json_decode($this->curl->response))) {
      throw new \Exception(__METHOD__ ." - Invalid JSON or null returned."); 
    }

    // Throw an exception on any returned messages from GDAX.
    if ($ret && isset($ret->message)) {
      throw new \Exception("API: $path-> ". $ret->message);
    }

    return $ret;
  }
1263853
public function getRequest($method, $path, $parameters = [], $authenticated = true)
    {
        $request = $this->createRequest($method, $path, $parameters);

        if ($authenticated) {
            $request = $this->authenticateRequest($request);
        }

        return $request;
    }
204351
private function makeRequest($method, $path, $headers = array(), $params = '') {
        if (time() - $this->previousRequestTime < 1) {
            sleep(1);
        }        
        $response = call_user_func_array(array($this->http, $method), array($path, $headers, $params));
        $this->previousRequestTime = time();
        list($status, $headers, $body) = $response;
        return $this->processResponse($response);
    }