Skip to content
Merged
2 changes: 1 addition & 1 deletion .github/workflows/ci-cd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
"5.6",
"7.4",
"8.0",
"8.4",
"8.5",
]
os: [ubuntu-latest, macOS-latest, windows-latest]
steps:
Expand Down
8 changes: 8 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 1.6.4
* Will use POST instead of GET when retrieving result.
* Remove deprecated `curl_close` for PHP version 8. https://www.php.net/manual/en/function.curl-close.php.
* Support PHP `8.5`.

## 1.6.3
* Add minimum TLS 1.2 version to curl options as protocol negotiation on certain openssl/libcurl versions is flaky.

## 1.6.2
* Remove deprecated curl constant (https://php.watch/versions/8.4/CURLOPT_BINARYTRANSFER-deprecated)

Expand Down
2 changes: 1 addition & 1 deletion lib/Tinify.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Tinify;

const VERSION = "1.6.2";
const VERSION = "1.6.4";

class Tinify {
const AUTHENTICATED = true;
Expand Down
24 changes: 18 additions & 6 deletions lib/Tinify/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ private static function caBundle() {
return __DIR__ . "/../data/cacert.pem";
}

function __construct($key, $appIdentifier = NULL, $proxy = NULL) {
function __construct($key, $app_identifier = NULL, $proxy = NULL) {
$curl = curl_version();

if (!($curl["features"] & CURL_VERSION_SSL)) {
Expand All @@ -31,15 +31,19 @@ function __construct($key, $appIdentifier = NULL, $proxy = NULL) {
throw new ClientException("Your curl version {$version} is outdated; please upgrade to 7.18.1 or higher");
}

$userAgent = join(" ", array_filter(array(self::userAgent(), $appIdentifier)));

# Set minimum TLS version to 1.2, CURL_SSLVERSION_TLSv1_2 is not available in curl < 7.34.0
# Additionally old PHP versions may not support this constant
$tlsVersion = ($curl["version_number"] < 0x072200)
? 6
: (defined('CURL_SSLVERSION_TLSv1_2') ? CURL_SSLVERSION_TLSv1_2 : 6);
$this->options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true,
CURLOPT_USERPWD => $key ? ("api:" . $key) : NULL,
CURLOPT_CAINFO => self::caBundle(),
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_USERAGENT => $userAgent,
CURLOPT_USERAGENT => join(" ", array_filter(array(self::userAgent(), $app_identifier))),
CURLOPT_SSLVERSION => $tlsVersion,
);

if ($proxy) {
Expand Down Expand Up @@ -108,7 +112,11 @@ function request($method, $url, $body = NULL) {
if (is_string($response)) {
$status = curl_getinfo($request, CURLINFO_HTTP_CODE);
$headerSize = curl_getinfo($request, CURLINFO_HEADER_SIZE);
curl_close($request);
if (PHP_VERSION_ID < 80000) {
curl_close($request);
} else {
unset($request);
}

$headers = self::parseHeaders(substr($response, 0, $headerSize));
$responseBody = substr($response, $headerSize);
Expand Down Expand Up @@ -177,7 +185,11 @@ function request($method, $url, $body = NULL) {
return (object) array("body" => $responseBody, "headers" => $headers);
} else {
$message = sprintf("%s (#%d)", curl_error($request), curl_errno($request));
curl_close($request);
if (PHP_VERSION_ID < 80000) {
curl_close($request);
} else {
unset($request);
}
if ($retries > 0) continue;
throw new ConnectionException("Error while connecting: " . $message);
}
Expand Down
5 changes: 4 additions & 1 deletion lib/Tinify/Source.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ public function transform($options) {
}

public function result() {
$response = Tinify::getClient()->request("get", $this->url, $this->commands);
$has_commands = !empty($this->commands);
$method = $has_commands ? "post" : "get";
$body = $has_commands ? $this->commands : null;
$response = Tinify::getClient()->request($method, $this->url, $body);
return new Result($response->headers, $response->body);
}

Expand Down
26 changes: 26 additions & 0 deletions test/TinifySourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,31 @@ public function testResultShouldReturnResult() {
));

$this->assertInstanceOf("Tinify\Result", Tinify\Source::fromBuffer("png file")->result());
$this->assertSame("GET", CurlMock::last(CURLOPT_CUSTOMREQUEST));
}

/**
* When request does not contain commands, it should use method GET
* when it contains commands, it should have a body and method POST
*/
public function testResultWithCommandsShouldReturnResultUsingPost() {
Tinify\setKey("valid");

CurlMock::register("https://api.tinify.com/shrink", array(
"status" => 201,
"headers" => array("Location" => "https://api.tinify.com/some/location"),
));

CurlMock::register("https://api.tinify.com/some/location", array(
"status" => 200, "body" => "resized file"
));

$source = Tinify\Source::fromBuffer("png file")->resize(array("width" => 400));
$result = $source->result();

$this->assertInstanceOf("Tinify\Result", $result);
$this->assertSame("POST", CurlMock::last(CURLOPT_CUSTOMREQUEST));
$this->assertSame('{"resize":{"width":400}}', CurlMock::last(CURLOPT_POSTFIELDS));
}

public function testPreserveShouldReturnSource() {
Expand Down Expand Up @@ -162,6 +187,7 @@ public function testPreserveShouldReturnSourceWithData() {

$this->assertSame("copyrighted file", Tinify\Source::fromBuffer("png file")->preserve("copyright", "location")->toBuffer());
$this->assertSame("{\"preserve\":[\"copyright\",\"location\"]}", CurlMock::last(CURLOPT_POSTFIELDS));
$this->assertSame("POST", CurlMock::last(CURLOPT_CUSTOMREQUEST));
}

public function testPreserveShouldReturnSourceWithDataForArray() {
Expand Down
1 change: 1 addition & 0 deletions test/curl_mock.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class CurlMock {
private static $version = array();

public $options = array();
public $request;
public $response;
public $closed = false;

Expand Down