Skip to content

Commit cf9e167

Browse files
author
Jacob Middag
committed
Use status code in output and be more robust in shrink
1 parent df3b32d commit cf9e167

8 files changed

Lines changed: 106 additions & 24 deletions

File tree

src/class-tiny-compress-curl.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,11 @@ protected function output($url, $resize_options, $preserve_options) {
109109

110110
$response = curl_exec($request);
111111
$header_size = curl_getinfo($request, CURLINFO_HEADER_SIZE);
112+
$status_code = curl_getinfo($request, CURLINFO_HTTP_CODE);
112113
$headers = self::parse_headers(substr($response, 0, $header_size));
113114
curl_close($request);
114115

115-
return array(substr($response, $header_size), $headers);
116+
return array(substr($response, $header_size), $headers, $status_code);
116117
}
117118

118119
private function add_proxy_options($url, $options) {

src/class-tiny-compress-fopen.php

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@
1919
*/
2020

2121
class Tiny_Compress_Fopen extends Tiny_Compress {
22+
private function status_code($header) {
23+
if ($header && count($header) > 0) {
24+
$http_code_values = explode(' ', $header[0]);
25+
if (count($http_code_values) > 1) {
26+
return intval($http_code_values[1]);
27+
}
28+
}
29+
return null;
30+
}
31+
2232
protected function shrink_options($input) {
2333
return array(
2434
'http' => array(
@@ -44,14 +54,7 @@ protected function shrink($input) {
4454
$context = stream_context_create($this->shrink_options($input));
4555
$request = @fopen(Tiny_Config::URL, 'r', false, $context);
4656

47-
$status_code = null;
48-
if ($http_response_header && count($http_response_header) > 0) {
49-
$http_code_values = explode(' ', $http_response_header[0]);
50-
if (count($http_code_values) > 1) {
51-
$status_code = intval($http_code_values[1]);
52-
}
53-
}
54-
57+
$status_code = self::status_code($http_response_header);
5558
if (!$request) {
5659
$headers = self::parse_headers($http_response_header);
5760

@@ -106,15 +109,16 @@ protected function output($url, $resize_options, $preserve_options) {
106109
$context = stream_context_create($this->output_options($resize_options, $preserve_options));
107110
$request = @fopen($url, 'rb', false, $context);
108111

112+
$status_code = self::status_code($http_response_header);
109113
if ($request) {
110114
$response = stream_get_contents($request);
111115
$meta_data = stream_get_meta_data($request);
112116
$headers = self::parse_headers($meta_data['wrapper_data']);
113117
fclose($request);
114118
} else {
115119
$response = '';
116-
$headers = array();
120+
$headers = self::parse_headers($http_response_header);
117121
}
118-
return array($response, $headers);
122+
return array($response, $headers, $status_code);
119123
}
120124
}

src/class-tiny-compress.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,29 @@ public function get_status(&$details) {
5656
}
5757

5858
public function compress($input, $resize_options, $preserve_options) {
59-
list($details, $headers) = $this->shrink($input);
59+
list($details, $headers, $status_code) = $this->shrink($input);
6060
$this->call_after_compress_callback($details, $headers);
6161
$outputUrl = isset($headers['location']) ? $headers['location'] : null;
6262
if (isset($details['error']) && $details['error']) {
6363
throw new Tiny_Exception($details['message'], $details['error']);
64+
} else if ($status_code >= 400) {
65+
throw new Tiny_Exception('Unexepected error in shrink', 'UnexpectedError');
6466
} else if ($outputUrl === null) {
6567
throw new Tiny_Exception('Could not find output url', 'OutputNotFound');
6668
}
67-
list($output, $headers) = $this->output($outputUrl, $resize_options, $preserve_options);
69+
70+
list($output, $headers, $status_code) = $this->output($outputUrl, $resize_options, $preserve_options);
71+
if (isset($headers['content-type']) && substr($headers['content-type'], 0, 16) == 'application/json') {
72+
$details = self::decode($output);
73+
if (isset($details['error']) && $details['error']) {
74+
throw new Tiny_Exception($details['message'], $details['error']);
75+
} else {
76+
throw new Tiny_Exception('Unknown error', 'UnknownError');
77+
}
78+
} else if ($status_code >= 400) {
79+
throw new Tiny_Exception('Unexepected error in output', 'UnexpectedError');
80+
}
81+
6882
$this->call_after_compress_callback(null, $headers);
6983
if (strlen($output) == 0) {
7084
throw new Tiny_Exception('Could not download output', 'OutputError');

test/integration/CompressIntegrationTest.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public function testResizeDisabledShouldDisplayOriginalDimensionsInEditScreen()
167167
public function testPreserveCopyrightShouldDisplayCorrectImageSizeInMediaLibrary()
168168
{
169169
$this->set_api_key('PRESERVEJPG123');
170-
$this->enable_preserve_copyright();
170+
$this->enable_preserve(array('copyright'));
171171
$this->upload_media(dirname(__FILE__) . '/../fixtures/input-copyright.jpg');
172172
$this->assertNotContains('files modified after compression',
173173
self::$driver->findElement(WebDriverBy::cssSelector('div#tinify-compress-details'))->getText());
@@ -186,4 +186,35 @@ public function testNonImageFileShouldNotShowCompressInfoInMediaLibrary()
186186
$this->assertEquals('',
187187
self::$driver->findElement(WebDriverBy::cssSelector('div#tinify-compress-details'))->getText());
188188
}
189+
190+
public function testGatewayTimeoutShouldBeDetectedInShrink()
191+
{
192+
$this->enable_compression_sizes(array('medium'));
193+
$this->set_api_key('GATEWAYTIMEOUT');
194+
$this->upload_media(dirname(__FILE__) . '/../fixtures/input-example.png');
195+
$this->assertContains('JSON: Syntax error [4]',
196+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images'))->getText());
197+
}
198+
199+
public function testGatewayTimeoutShouldBeDetectedInOutput()
200+
{
201+
$this->enable_compression_sizes(array('medium'));
202+
$this->enable_preserve(array('copyright'));
203+
$this->set_api_key('PNG123_GATEWAYTIMEOUT');
204+
$this->upload_media(dirname(__FILE__) . '/../fixtures/input-example.png');
205+
self::$driver->takeScreenshot("/Users/jacobmiddag/Downloads/ss2.png");
206+
$this->assertContains('Unexepected error in output',
207+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images'))->getText());
208+
}
209+
210+
public function testErrorShouldBeDetectedInOutput()
211+
{
212+
$this->enable_compression_sizes(array('medium'));
213+
$this->enable_preserve(array('copyright'));
214+
$this->set_api_key('PNG123_INVALID');
215+
$this->upload_media(dirname(__FILE__) . '/../fixtures/input-example.png');
216+
self::$driver->takeScreenshot("/Users/jacobmiddag/Downloads/ss3.png");
217+
$this->assertContains("Metadata key 'author' not supported",
218+
self::$driver->findElement(WebDriverBy::cssSelector('td.tiny-compress-images'))->getText());
219+
}
189220
}

test/integration/IntegrationTestCase.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,23 @@ protected function disable_resize() {
9090
self::$driver->findElement(WebDriverBy::tagName('form'))->submit();
9191
}
9292

93-
protected function enable_preserve_copyright() {
93+
protected function enable_preserve($keys) {
9494
$url = wordpress('/wp-admin/options-media.php');
9595
if (self::$driver->getCurrentUrl() != $url) {
9696
self::$driver->get($url);
9797
}
98-
$element = self::$driver->findElement(WebDriverBy::id('tinypng_preserve_data_copyright'));
99-
if (!$element->getAttribute('checked')) {
100-
$element->click();
98+
$elements = self::$driver->findElements(WebDriverBy::xpath('//input[starts-with(@id, "tinypng_preserve_data")]'));
99+
foreach($elements as $element) {
100+
$key = str_replace('tinypng_preserve_data_', '', $element->getAttribute('id'));
101+
if (in_array($key, $keys)) {
102+
if (!$element->getAttribute('checked')) {
103+
$element->click();
104+
}
105+
} else {
106+
if ($element->getAttribute('checked')) {
107+
$element->click();
108+
}
109+
}
101110
}
102111
self::$driver->findElement(WebDriverBy::tagName('form'))->submit();
103112
}

test/mock-tinypng-webservice/common.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ function mock_invalid_response() {
3939

4040
$response = array(
4141
"error" => "Unauthorized",
42-
"message" => "Credentials are invalid"
42+
"message" => "Credentials are invalid "
4343
);
4444
return json_encode($response);
4545
}
46+
47+
function mock_service_unavailable_response() {
48+
header('HTTP/1.1 503 Service unavailable');
49+
return 'HTTP Error 503. The service is unavailable';
50+
}

test/mock-tinypng-webservice/output.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,36 @@
1010
} else {
1111
$file = null;
1212
}
13+
$headers = [];
1314

1415
$api_key = get_api_key();
1516
if (!is_null($api_key)) {
1617
$data = get_json_body();
1718
$resize = $data->resize;
1819
if ($resize->method) {
1920
$file = "output-resized.$ext";
20-
header("Image-Width: {$resize->width}");
21-
header("Image-Height: {$resize->height}");
21+
$headers["Image-Width"] = $resize->width;
22+
$headers["Image-Height"] = $resize->height;
2223
}
2324
}
2425

25-
if ($file && file_exists($file)) {
26+
if (strpos($api_key, 'GATEWAYTIMEOUT') !== false) {
27+
echo mock_service_unavailable_response();
28+
} else if (strpos($api_key, 'INVALID') !== false) {
29+
header('HTTP/1.1 400 Bad Request');
30+
header("Content-Type: application/json; charset=utf-8");
31+
32+
$response = array(
33+
"error" => "JSON validation error",
34+
"message" => "Metadata key 'author' not supported"
35+
);
36+
echo json_encode($response);
37+
} else if ($file && file_exists($file)) {
2638
header("Content-Type: $mime");
2739
header('Content-Disposition: attachment');
40+
foreach ($headers as $name => $value) {
41+
header("$name: $value");
42+
}
2843
readfile($file);
2944
} else {
3045
header("HTTP/1.1 404 Not Found");

test/mock-tinypng-webservice/shrink.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function mock_empty_response() {
5959

6060
$response = array(
6161
"error" => "InputMissing",
62-
"message" => "Your monthly limit has been exceeded"
62+
"message" => "File is empty"
6363
);
6464
return json_encode($response);
6565
}
@@ -89,8 +89,9 @@ function mock_invalid_json_response() {
8989
return '{invalid: json}';
9090
}
9191

92+
9293
$api_key = get_api_key();
93-
if ($api_key == 'PNG123') {
94+
if (substr($api_key, 0, 6) == 'PNG123') {
9495
if (intval($_SERVER['CONTENT_LENGTH']) == 0) {
9596
echo mock_empty_response();
9697
} else {
@@ -116,6 +117,8 @@ function mock_invalid_json_response() {
116117
}
117118
} else if ($api_key == 'LIMIT123') {
118119
echo mock_limit_reached_response();
120+
} else if ($api_key == 'GATEWAYTIMEOUT') {
121+
echo mock_service_unavailable_response();
119122
} else {
120123
echo mock_invalid_response();
121124
}

0 commit comments

Comments
 (0)