2424use Generator ;
2525use GuzzleHttp \Client ;
2626use GuzzleHttp \ClientInterface ;
27+ use GuzzleHttp \Exception \GuzzleException ;
2728use GuzzleHttp \Exception \RequestException ;
2829use GuzzleHttp \Handler \CurlHandler ;
2930use GuzzleHttp \HandlerStack ;
3031use GuzzleHttp \Middleware ;
3132use GuzzleHttp \Pool ;
3233use GuzzleHttp \RetryMiddleware ;
3334use Illuminate \Support \Facades \Cache ;
35+ use League \OAuth2 \Client \Provider \Exception \IdentityProviderException ;
3436use League \OAuth2 \Client \Provider \GenericProvider ;
35- use League \OAuth2 \Client \Token \AccessTokenInterface ;
3637use Psr \Http \Message \RequestInterface ;
3738
38- /**
39- * Class HttpRequest
40- *
41- * Handles HTTP requests with OAuth2 authentication and retry capabilities.
42- * Provides functionality for making authenticated HTTP requests, managing access tokens,
43- * and handling request retries with customizable retry strategies.
44- *
45- * Features:
46- * - OAuth2 authentication integration
47- * - Automatic token refresh
48- * - Configurable retry mechanism with exponential backoff
49- * - Support for request pooling
50- * - Direct HTTP client creation without OAuth2
51- */
5239class HttpRequest
5340{
5441 /**
@@ -57,9 +44,9 @@ class HttpRequest
5744 protected GenericProvider $ provider ;
5845
5946 /**
60- * Current OAuth2 access token
47+ * Current OAuth2 access token string
6148 */
62- protected AccessTokenInterface $ accessToken ;
49+ protected ? string $ accessToken = null ;
6350
6451 /**
6552 * Maximum number of retry attempts for failed requests
@@ -70,7 +57,6 @@ class HttpRequest
7057 * Set authentication provider with retry middleware
7158 *
7259 * @param array $config Configuration options for the OAuth2 provider
73- * @return GenericProvider Configured OAuth2 provider instance
7460 */
7561 public function setHttpProvider (array $ config = []): GenericProvider
7662 {
@@ -89,8 +75,6 @@ public function setHttpProvider(array $config = []): GenericProvider
8975
9076 /**
9177 * Get a configured HTTP client from the OAuth2 provider
92- *
93- * @return ClientInterface Configured GuzzleHttp client
9478 */
9579 public function getHttpClient (): ClientInterface
9680 {
@@ -102,28 +86,45 @@ public function getHttpClient(): ClientInterface
10286 *
10387 * @param string $token Cache key for storing the access token
10488 *
105- * @throws \League\OAuth2\Client\Provider\Exception\ IdentityProviderException
106- * @throws \GuzzleHttp\Exception\ GuzzleException
89+ * @throws IdentityProviderException
90+ * @throws GuzzleException
10791 */
10892 protected function setAccessToken (string $ token ): void
10993 {
11094 $ accessToken = $ this ->provider ->getAccessToken ('client_credentials ' );
111- Cache::put ($ token , $ accessToken , 720 );
95+
96+ Cache::put ($ token , [
97+ 'access_token ' => $ accessToken ->getToken (),
98+ 'expires_at ' => $ accessToken ->getExpires (),
99+ ], 720 );
100+
101+ $ this ->accessToken = $ accessToken ->getToken ();
112102 }
113103
114104 /**
115- * Verify and refresh the access token if expired
105+ * Verify and refresh the access token if expired
106+ *
107+ * @param string $token
116108 *
117- * @throws \GuzzleHttp\Exception\ GuzzleException
118- * @throws \League\OAuth2\Client\Provider\Exception\ IdentityProviderException
109+ * @throws GuzzleException
110+ * @throws IdentityProviderException
119111 */
120112 public function checkAccessToken ($ token ): void
121113 {
122- if (Cache::get ($ token ) === null || Cache::get ($ token )->hasExpired ()) {
114+ $ cachedToken = Cache::get ($ token );
115+
116+ if (
117+ ! is_array ($ cachedToken ) ||
118+ empty ($ cachedToken ['access_token ' ]) ||
119+ empty ($ cachedToken ['expires_at ' ]) ||
120+ time () >= (int ) $ cachedToken ['expires_at ' ]
121+ ) {
123122 $ this ->setAccessToken ($ token );
123+
124+ return ;
124125 }
125126
126- $ this ->accessToken = Cache:: get ( $ token ) ;
127+ $ this ->accessToken = $ cachedToken [ ' access_token ' ] ;
127128 }
128129
129130 /**
@@ -135,15 +136,18 @@ public function checkAccessToken($token): void
135136 */
136137 protected function buildAuthenticatedRequest (string $ method , string $ uri , array $ options = []): RequestInterface
137138 {
138- return $ this ->provider ->getAuthenticatedRequest ($ method , $ uri , $ this ->accessToken ->getToken (), $ options );
139+ if ($ this ->accessToken === null ) {
140+ throw new \RuntimeException ('Access token has not been initialized. ' );
141+ }
142+
143+ return $ this ->provider ->getAuthenticatedRequest ($ method , $ uri , $ this ->accessToken , $ options );
139144 }
140145
141146 /**
142147 * Create a request pool for concurrent requests
143148 *
144149 * @param Generator $promises Generator of request promises
145150 * @param array $poolConfig Pool configuration options
146- * @return Pool Configured request pool
147151 */
148152 public function pool (Generator $ promises , array $ poolConfig ): Pool
149153 {
@@ -208,6 +212,7 @@ public function retryDelay(): \Closure
208212 * Set maximum number of retry attempts
209213 *
210214 * @param int $maxRetries Maximum number of retries
215+ * @return $this
211216 */
212217 public function setMaxRetries (int $ maxRetries ): self
213218 {
@@ -220,7 +225,6 @@ public function setMaxRetries(int $maxRetries): self
220225 * Create a standalone Guzzle HTTP client with retry middleware
221226 *
222227 * @param array $config Additional client configuration
223- * @return Client Configured Guzzle client
224228 */
225229 public function createDirectHttpClient (array $ config = []): Client
226230 {
0 commit comments