PluginProbe ʕ •ᴥ•ʔ
TinyPNG – JPEG, PNG & WebP image compression / 3.8.0
TinyPNG – JPEG, PNG & WebP image compression v3.8.0
3.8.0 3.7.0 3.6.14 trunk 1.0.0 1.1.0 1.2.0 1.2.1 1.3.0 1.3.1 1.3.2 1.4.0 1.5.0 1.6.0 1.7.0 1.7.1 1.7.2 2.0.0 2.0.1 2.0.2 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 3.0.0 3.0.1 3.1.0 3.2.0 3.2.1 3.3 3.4 3.4.1 3.4.2 3.4.4 3.4.5 3.4.6 3.5.0 3.5.1 3.5.2 3.6.0 3.6.1 3.6.10 3.6.11 3.6.12 3.6.13 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.6.9
tiny-compress-images / src / vendor / tinify / Tinify / Client.php
tiny-compress-images / src / vendor / tinify / Tinify Last commit date
Client.php 6 months ago Exception.php 4 years ago Result.php 4 years ago ResultMeta.php 1 year ago Source.php 6 months ago
Client.php
215 lines
1 <?php
2
3 namespace Tinify;
4
5 class Client {
6 const API_ENDPOINT = "https://api.tinify.com";
7
8 const RETRY_COUNT = 1;
9 const RETRY_DELAY = 500;
10
11 protected $options;
12
13 public static function userAgent() {
14 $curl = curl_version();
15 return "Tinify/" . VERSION . " PHP/" . PHP_VERSION . " curl/" . $curl["version"];
16 }
17
18 private static function caBundle() {
19 return __DIR__ . "/../data/cacert.pem";
20 }
21
22 function __construct($key, $app_identifier = NULL, $proxy = NULL) {
23 $curl = curl_version();
24
25 if (!($curl["features"] & CURL_VERSION_SSL)) {
26 throw new ClientException("Your curl version does not support secure connections");
27 }
28
29 if ($curl["version_number"] < 0x071201) {
30 $version = $curl["version"];
31 throw new ClientException("Your curl version {$version} is outdated; please upgrade to 7.18.1 or higher");
32 }
33
34 # Set minimum TLS version to 1.2, CURL_SSLVERSION_TLSv1_2 is not available in curl < 7.34.0
35 # Additionally old PHP versions may not support this constant
36 $tlsVersion = ($curl["version_number"] < 0x072200)
37 ? 6
38 : (defined('CURL_SSLVERSION_TLSv1_2') ? CURL_SSLVERSION_TLSv1_2 : 6);
39 $this->options = array(
40 CURLOPT_RETURNTRANSFER => true,
41 CURLOPT_HEADER => true,
42 CURLOPT_USERPWD => $key ? ("api:" . $key) : NULL,
43 CURLOPT_CAINFO => self::caBundle(),
44 CURLOPT_SSL_VERIFYPEER => true,
45 CURLOPT_USERAGENT => join(" ", array_filter(array(self::userAgent(), $app_identifier))),
46 CURLOPT_SSLVERSION => $tlsVersion,
47 );
48
49 if ($proxy) {
50 $parts = parse_url($proxy);
51 if (isset($parts["host"])) {
52 $this->options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
53 $this->options[CURLOPT_PROXY] = $parts["host"];
54 } else {
55 throw new ConnectionException("Invalid proxy");
56 }
57
58 if (isset($parts["port"])) {
59 $this->options[CURLOPT_PROXYPORT] = $parts["port"];
60 }
61
62 $creds = "";
63 if (isset($parts["user"])) $creds .= $parts["user"];
64 if (isset($parts["pass"])) $creds .= ":" . $parts["pass"];
65
66 if ($creds) {
67 $this->options[CURLOPT_PROXYAUTH] = CURLAUTH_ANY;
68 $this->options[CURLOPT_PROXYUSERPWD] = $creds;
69 }
70 }
71 }
72
73 function request($method, $url, $body = NULL) {
74 $header = array();
75 if (is_array($body)) {
76 if (!empty($body)) {
77 $body = json_encode($body);
78 array_push($header, "Content-Type: application/json");
79 } else {
80 $body = NULL;
81 }
82 }
83
84 for ($retries = self::RETRY_COUNT; $retries >= 0; $retries--) {
85 if ($retries < self::RETRY_COUNT) {
86 usleep(self::RETRY_DELAY * 1000);
87 }
88
89 $request = curl_init();
90 if ($request === false || $request === null) {
91 throw new ConnectionException(
92 "Error while connecting: curl extension is not functional or disabled."
93 );
94 }
95
96 curl_setopt_array($request, $this->options);
97
98 $url = strtolower(substr($url, 0, 6)) == "https:" ? $url : self::API_ENDPOINT . $url;
99 curl_setopt($request, CURLOPT_URL, $url);
100 curl_setopt($request, CURLOPT_CUSTOMREQUEST, strtoupper($method));
101
102 if (count($header) > 0) {
103 curl_setopt($request, CURLOPT_HTTPHEADER, $header);
104 }
105
106 if ($body) {
107 curl_setopt($request, CURLOPT_POSTFIELDS, $body);
108 }
109
110 $response = curl_exec($request);
111
112 if (is_string($response)) {
113 $status = curl_getinfo($request, CURLINFO_HTTP_CODE);
114 $headerSize = curl_getinfo($request, CURLINFO_HEADER_SIZE);
115 if (PHP_VERSION_ID < 80000) {
116 curl_close($request);
117 } else {
118 unset($request);
119 }
120
121 $headers = self::parseHeaders(substr($response, 0, $headerSize));
122 $responseBody = substr($response, $headerSize);
123
124 if ( isset($headers["compression-count"] ) ) {
125 Tinify::setCompressionCount(intval($headers["compression-count"]));
126 }
127
128 if ( isset( $headers["compression-count-remaining"] ) ) {
129 Tinify::setRemainingCredits( intval( $headers["compression-count-remaining"] ) );
130 }
131
132 if ( isset( $headers["paying-state"] ) ) {
133 Tinify::setPayingState( $headers["paying-state"] );
134 }
135
136 $details = json_decode($responseBody);
137 if (!$details) {
138 $message = sprintf("Error while parsing response: %s (#%d)",
139 PHP_VERSION_ID >= 50500 ? json_last_error_msg() : "Error",
140 json_last_error());
141 $details = (object) array(
142 "message" => $message,
143 "error" => "ParseError"
144 );
145 }
146
147 if ( isset( $headers["email-address"] ) ) {
148 Tinify::setEmailAddress( $headers["email-address"] );
149 }
150
151 $isJson = false;
152 if (isset($headers["content-type"])) {
153 /* Parse JSON response bodies. */
154 list($contentType) = explode(";", $headers["content-type"], 2);
155 if (strtolower(trim($contentType)) == "application/json") {
156 $isJson = true;
157 }
158 }
159
160 /* 1xx and 3xx are unexpected and will be treated as error. */
161 $isError = $status <= 199 || $status >= 300;
162
163 if ($isJson || $isError) {
164 /* Parse JSON bodies, always interpret errors as JSON. */
165 $responseBody = json_decode($responseBody);
166 if (!$responseBody) {
167 $message = sprintf("Error while parsing response: %s (#%d)",
168 PHP_VERSION_ID >= 50500 ? json_last_error_msg() : "Error",
169 json_last_error());
170 if ($retries > 0 && $status >= 500) continue;
171 throw Exception::create($message, "ParseError", $status);
172 }
173 }
174
175 if ($isError) {
176 if ($retries > 0 && $status >= 500) continue;
177 /* When the key doesn't exist a 404 response is given. */
178 if ($status == 404) {
179 throw Exception::create(null, null, $status);
180 } else {
181 throw Exception::create($responseBody->message, $responseBody->error, $status);
182 }
183 }
184
185 return (object) array("body" => $responseBody, "headers" => $headers);
186 } else {
187 $message = sprintf("%s (#%d)", curl_error($request), curl_errno($request));
188 if (PHP_VERSION_ID < 80000) {
189 curl_close($request);
190 } else {
191 unset($request);
192 }
193 if ($retries > 0) continue;
194 throw new ConnectionException("Error while connecting: " . $message);
195 }
196 }
197 }
198
199 protected static function parseHeaders($headers) {
200 if (!is_array($headers)) {
201 $headers = explode("\r\n", $headers);
202 }
203
204 $result = array();
205 foreach ($headers as $header) {
206 if (empty($header)) continue;
207 $split = explode(":", $header, 2);
208 if (count($split) === 2) {
209 $result[strtolower($split[0])] = trim($split[1]);
210 }
211 }
212 return $result;
213 }
214 }
215