22
33namespace Nitrapi \Common \Http ;
44
5+ use DateTime ;
56use GuzzleHttp \Client as GuzzleClient ;
67use GuzzleHttp \Exception \RequestException ;
78use GuzzleHttp \Psr7 \Response ;
89use Nitrapi \Common \Exceptions \NitrapiConcurrencyException ;
910use Nitrapi \Common \Exceptions \NitrapiException ;
1011use Nitrapi \Common \Exceptions \NitrapiHttpErrorException ;
1112use Nitrapi \Common \Exceptions \NitrapiMaintenanceException ;
13+ use Nitrapi \Common \Exceptions \NitrapiRateLimitException ;
1214
1315class Client extends GuzzleClient
1416{
@@ -18,6 +20,14 @@ class Client extends GuzzleClient
1820
1921 protected $ accessToken = null ;
2022
23+ // Rate Limit metadata
24+ /** @var integer */
25+ protected $ rateLimit ;
26+ /** @var integer */
27+ protected $ remainingRequests ;
28+ /** @var DateTime */
29+ protected $ rateLimitResetTime ;
30+
2131 protected $ clientCertificate ;
2232 protected $ clientCertificateKey ;
2333
@@ -82,7 +92,70 @@ public function fillOptions(&$options) {
8292 }
8393 }
8494
95+ /**
96+ * Rate limit
97+ *
98+ * @return int The number of requests which are allowed in one hour.
99+ */
100+ public function getRateLimit () {
101+ return $ this ->rateLimit ;
102+ }
103+
104+ /**
105+ * Check for rate limit
106+ *
107+ * @return bool if there is a rate limit in place
108+ */
109+ public function hasRateLimit () {
110+ return $ this ->rateLimit !== false ;
111+ }
112+
113+ /**
114+ * Remaining requests
115+ *
116+ * @return int The number of requests remaining until the rate limit is exceeded.
117+ */
118+ public function getRemainingRequests () {
119+ return $ this ->remainingRequests ;
120+ }
121+
122+ /**
123+ * Rate limit reset time
124+ *
125+ * @return DateTime The time the rate limit will be reset
126+ */
127+ public function getRateLimitResetTime () {
128+ return $ this ->rateLimitResetTime ;
129+ }
130+
131+ /**
132+ * Parse the NitrAPI response
133+ *
134+ * @param Response $response
135+ * @return bool|mixed true if response is fine but without message, data or message otherwise.
136+ * @throws NitrapiHttpErrorException when the API responds with an error message.
137+ * @throws NitrapiRateLimitException when the user ran into the rate limit.
138+ */
85139 public function parseResponse (Response $ response ) {
140+ // Rate limit metadata
141+ if ($ response ->hasHeader ('X-RateLimit-Limit ' )) {
142+ $ this ->rateLimit = $ response ->getHeader ('X-RateLimit-Limit ' )[0 ];
143+ $ this ->remainingRequests = $ response ->getHeader ('X-RateLimit-Remaining ' )[0 ];
144+ $ resetDateTime = new DateTime ();
145+ $ resetDateTime ->setTimestamp ($ response ->getHeader ('X-RateLimit-Reset ' )[0 ]);
146+ $ this ->rateLimitResetTime = $ resetDateTime ;
147+
148+ // We ran into the rate limit, so we throw an exception with all needed information.
149+ // This gives the client the option to handle that error. To access the rate limit
150+ // metadata, the getRateLimit(), getRemainingRequests() and getRateLimitResetTime()
151+ // method can be used at any time.
152+ if ($ response ->getStatusCode () === 429 ) {
153+ throw new NitrapiRateLimitException ($ this ->getRateLimit (), $ this ->getRateLimitResetTime ());
154+ }
155+ } else {
156+ $ this ->rateLimit = false ;
157+ }
158+
86159 $ contentType = $ response ->getHeader ('Content-Type ' )[0 ];
87160
88161 // Return plain text
0 commit comments