PluginProbe ʕ •ᴥ•ʔ
TinyPNG – JPEG, PNG & WebP image compression / 2.2.4
TinyPNG – JPEG, PNG & WebP image compression v2.2.4
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 9 years ago Exception.php 10 years ago Result.php 10 years ago ResultMeta.php 10 years ago Source.php 10 years ago
Client.php
165 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, $appIdentifier = NULL, $proxy = NULL) {
23 $userAgent = join(" ", array_filter(array(self::userAgent(), $appIdentifier)));
24
25 $this->options = array(
26 CURLOPT_BINARYTRANSFER => true,
27 CURLOPT_RETURNTRANSFER => true,
28 CURLOPT_HEADER => true,
29 CURLOPT_USERPWD => $key ? ("api:" . $key) : NULL,
30 CURLOPT_CAINFO => self::caBundle(),
31 CURLOPT_SSL_VERIFYPEER => true,
32 CURLOPT_USERAGENT => $userAgent,
33 );
34
35 if ($proxy) {
36 $parts = parse_url($proxy);
37 if (isset($parts["host"])) {
38 $this->options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
39 $this->options[CURLOPT_PROXY] = $parts["host"];
40 } else {
41 throw new ConnectionException("Invalid proxy");
42 }
43
44 if (isset($parts["port"])) {
45 $this->options[CURLOPT_PROXYPORT] = $parts["port"];
46 }
47
48 $creds = "";
49 if (isset($parts["user"])) $creds .= $parts["user"];
50 if (isset($parts["pass"])) $creds .= ":" . $parts["pass"];
51
52 if ($creds) {
53 $this->options[CURLOPT_PROXYAUTH] = CURLAUTH_ANY;
54 $this->options[CURLOPT_PROXYUSERPWD] = $creds;
55 }
56 }
57 }
58
59 function request($method, $url, $body = NULL) {
60 $header = array();
61 if (is_array($body)) {
62 if (!empty($body)) {
63 $body = json_encode($body);
64 array_push($header, "Content-Type: application/json");
65 } else {
66 $body = NULL;
67 }
68 }
69
70 for ($retries = self::RETRY_COUNT; $retries >= 0; $retries--) {
71 if ($retries < self::RETRY_COUNT) {
72 usleep(self::RETRY_DELAY * 1000);
73 }
74
75 $request = curl_init();
76 if ($request === false || $request === null) {
77 throw new ConnectionException(
78 "Error while connecting: curl extension is not functional or disabled."
79 );
80 }
81
82 curl_setopt_array($request, $this->options);
83
84 $url = strtolower(substr($url, 0, 6)) == "https:" ? $url : self::API_ENDPOINT . $url;
85 curl_setopt($request, CURLOPT_URL, $url);
86 curl_setopt($request, CURLOPT_CUSTOMREQUEST, strtoupper($method));
87
88 if (count($header) > 0) {
89 curl_setopt($request, CURLOPT_HTTPHEADER, $header);
90 }
91
92 if ($body) {
93 curl_setopt($request, CURLOPT_POSTFIELDS, $body);
94 }
95
96 $response = curl_exec($request);
97
98 if (is_string($response)) {
99 $status = curl_getinfo($request, CURLINFO_HTTP_CODE);
100 $headerSize = curl_getinfo($request, CURLINFO_HEADER_SIZE);
101 curl_close($request);
102
103 $headers = self::parseHeaders(substr($response, 0, $headerSize));
104 $body = substr($response, $headerSize);
105
106 if (isset($headers["compression-count"])) {
107 Tinify::setCompressionCount(intval($headers["compression-count"]));
108 }
109
110 $isJson = false;
111 if (isset($headers["content-type"])) {
112 /* Parse JSON response bodies. */
113 list($contentType) = explode(";", $headers["content-type"], 2);
114 if (strtolower(trim($contentType)) == "application/json") {
115 $isJson = true;
116 }
117 }
118
119 /* 1xx and 3xx are unexpected and will be treated as error. */
120 $isError = $status <= 199 || $status >= 300;
121
122 if ($isJson || $isError) {
123 /* Parse JSON bodies, always interpret errors as JSON. */
124 $body = json_decode($body);
125 if (!$body) {
126 $message = sprintf("Error while parsing response: %s (#%d)",
127 PHP_VERSION_ID >= 50500 ? json_last_error_msg() : "Error",
128 json_last_error());
129 if ($retries > 0 && $status >= 500) continue;
130 throw Exception::create($message, "ParseError", $status);
131 }
132 }
133
134 if ($isError) {
135 if ($retries > 0 && $status >= 500) continue;
136 throw Exception::create($body->message, $body->error, $status);
137 }
138
139 return (object) array("body" => $body, "headers" => $headers);
140 } else {
141 $message = sprintf("%s (#%d)", curl_error($request), curl_errno($request));
142 curl_close($request);
143 if ($retries > 0) continue;
144 throw new ConnectionException("Error while connecting: " . $message);
145 }
146 }
147 }
148
149 protected static function parseHeaders($headers) {
150 if (!is_array($headers)) {
151 $headers = explode("\r\n", $headers);
152 }
153
154 $result = array();
155 foreach ($headers as $header) {
156 if (empty($header)) continue;
157 $split = explode(":", $header, 2);
158 if (count($split) === 2) {
159 $result[strtolower($split[0])] = trim($split[1]);
160 }
161 }
162 return $result;
163 }
164 }
165