Skip to content

Commit f021569

Browse files
committed
Merge pull request #5 from imgix/5-fully-qualified-urls
UrlBuilder does not CGI-encode fully-qualified URLs
2 parents 516bae0 + 44aaa64 commit f021569

File tree

5 files changed

+84
-50
lines changed

5 files changed

+84
-50
lines changed

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"imgix"
77
],
88
"require": {
9-
"php": ">=5.3"
9+
"php": ">=5.3",
10+
"jakeasmith/http_build_url": "^1.0"
1011
},
1112
"require-dev": {
1213
"phpunit/phpunit": "*"
@@ -16,4 +17,4 @@
1617
"Imgix\\": "src/"
1718
}
1819
}
19-
}
20+
}

composer.lock

Lines changed: 39 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Imgix/UrlHelper.php

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22

33
namespace Imgix;
4-
4+
55
class UrlHelper {
66

77
private $domain;
@@ -12,7 +12,8 @@ class UrlHelper {
1212

1313
public function __construct($domain, $path, $scheme = "http", $signKey = "", $params = array()) {
1414
$this->domain = $domain;
15-
$this->path = substr($path, 0, 1) !== "/" ? ("/" . $path) : $path;
15+
$this->path = substr($path, 0, 4) === "http" ? urlencode($path) : $path;
16+
$this->path = substr($this->path, 0, 1) !== "/" ? ("/" . $this->path) : $this->path;
1617
$this->scheme = $scheme;
1718
$this->signKey = $signKey;
1819
$this->params = $params;
@@ -42,7 +43,7 @@ public function getURL() {
4243
$query = join("&", $queryPairs);
4344

4445
if ($this->signKey) {
45-
$delim = $query === "" ? "" : "?";
46+
$delim = "?";
4647
$toSign = $this->signKey . $this->path . $delim . $query;
4748
$sig = md5($toSign);
4849
if ($query) {
@@ -54,50 +55,21 @@ public function getURL() {
5455

5556
$url_parts = array('scheme' => $this->scheme, 'host' => $this->domain, 'path' => $this->path, 'query' => $query);
5657

57-
return self::join_url($url_parts);
58+
return self::joinURL($url_parts);
5859
}
5960

6061
public static function encodeURIComponent($str) {
6162
$revert = array('%21'=>'!', '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')');
6263
return strtr(rawurlencode($str), $revert);
6364
}
6465

65-
public static function join_url($parts, $encode=true) {
66-
$url = '';
67-
if (!empty($parts['scheme'])) {
68-
$url .= $parts['scheme'] . ':';
69-
}
70-
if (isset($parts['host'])) {
71-
$url .= '//';
72-
if (isset($parts['user'])) {
73-
$url .= $parts['user'];
74-
if (isset($parts['pass']))
75-
$url .= ':' . $parts['pass'];
76-
$url .= '@';
77-
}
78-
if (preg_match('!^[\da-f]*:[\da-f.:]+$!ui', $parts['host'])) {
79-
$url .= '[' . $parts['host'] . ']';
80-
} else {
81-
$url .= $parts['host'];
82-
}
83-
if (isset($parts['port'])) {
84-
$url .= ':' . $parts['port'];
85-
}
86-
if (!empty($parts['path']) && $parts['path'][0] != '/') {
87-
$url .= '/';
88-
}
89-
}
90-
if (!empty($parts['path'])) {
91-
$url .= $parts['path'];
92-
}
93-
if (isset($parts['query']) && strlen($parts['query']) > 0) {
94-
$url .= '?' . $parts['query'];
95-
}
96-
if (isset($parts['fragment'])) {
97-
$url .= '#' . $parts['fragment'];
66+
public static function joinURL($parts) {
67+
68+
// imgix idiosyncracy for signing URLs when only the signature exists. Our query string must begin with '?&s='
69+
if (substr($parts['query'], 0, 2) === "s=") {
70+
$parts['query'] = "&" . $parts['query'];
9871
}
9972

100-
return $url;
73+
return http_build_url($parts);
10174
}
102-
10375
}

tests/Imgix/Tests/UrlBuilderTest.php

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public function testExamplePlain() {
3939
$params = array("w" => 100, "h" => 100);
4040
$url = $builder->createURL("bridge.png", $params);
4141

42-
$this->assertEquals($url, "http://demos.imgix.net/bridge.png?h=100&w=100");
42+
$this->assertEquals("http://demos.imgix.net/bridge.png?h=100&w=100", $url);
4343
}
4444

4545
public function testExamplePlainHttps() {
@@ -49,7 +49,7 @@ public function testExamplePlainHttps() {
4949
$params = array("w" => 100, "h" => 100);
5050
$url = $builder->createURL("bridge.png", $params);
5151

52-
$this->assertEquals($url, "https://demos.imgix.net/bridge.png?h=100&w=100");
52+
$this->assertEquals("https://demos.imgix.net/bridge.png?h=100&w=100", $url);
5353
}
5454

5555
public function testExamplePlainSecure() {
@@ -58,7 +58,31 @@ public function testExamplePlainSecure() {
5858
$params = array("w" => 100, "h" => 100);
5959
$url = $builder->createURL("bridge.png", $params);
6060

61-
$this->assertEquals($url, "http://demos.imgix.net/bridge.png?h=100&w=100&s=bb8f3a2ab832e35997456823272103a4");
61+
$this->assertEquals("http://demos.imgix.net/bridge.png?h=100&w=100&s=bb8f3a2ab832e35997456823272103a4", $url);
62+
}
63+
64+
public function testWithFullyQualifiedUrl() {
65+
$builder = new UrlBuilder("demos.imgix.net", true);
66+
$builder->setSignKey("test1234");
67+
$url = $builder->createUrl("http://media.giphy.com/media/jCMq0p94fgBIk/giphy.gif");
68+
69+
$this->assertEquals("https://demos.imgix.net/http%3A%2F%2Fmedia.giphy.com%2Fmedia%2FjCMq0p94fgBIk%2Fgiphy.gif?&s=ffc3359566fe1dc6445ad17d17b98951", $url);
70+
}
71+
72+
public function testWithFullyQualifiedUrlWithSpaces() {
73+
$builder = new UrlBuilder("demos.imgix.net", true);
74+
$builder->setSignKey("test1234");
75+
$url = $builder->createUrl("https://my-demo-site.com/files/133467012/avatar icon.png");
76+
77+
$this->assertEquals("https://demos.imgix.net/https%3A%2F%2Fmy-demo-site.com%2Ffiles%2F133467012%2Favatar+icon.png?&s=f6a4e1504af365564014564f1d7e13de", $url);
78+
}
79+
80+
public function testWithFullyQualifiedUrlWithParams() {
81+
$builder = new UrlBuilder("demos.imgix.net", true);
82+
$builder->setSignKey("test1234");
83+
$url = $builder->createUrl("https://my-demo-site.com/files/133467012/avatar icon.png?some=chill&params=1");
84+
85+
$this->assertEquals("https://demos.imgix.net/https%3A%2F%2Fmy-demo-site.com%2Ffiles%2F133467012%2Favatar+icon.png%3Fsome%3Dchill%26params%3D1?&s=259b9ca6206721752ad7a3ce50f08dd2", $url);
6286
}
6387
}
6488
?>

tests/Imgix/Tests/UrlHelperTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,26 @@ public function testHelperBuildSignedURLWithHashMapParams() {
88
$params = array("w" => 500);
99
$uh = new URLHelper("securejackangers.imgix.net", "chester.png", "http", "Q61NvXIy", $params);
1010

11-
$this->assertEquals($uh->getURL(), "http://securejackangers.imgix.net/chester.png?w=500&s=0ddf97bf1a266a1da6c30c6ce327f917");
11+
$this->assertEquals("http://securejackangers.imgix.net/chester.png?w=500&s=0ddf97bf1a266a1da6c30c6ce327f917", $uh->getURL());
1212
}
1313

1414
public function testHelperBuildSignedURLWithHashMapAndNoParams() {
1515
$params = array();
1616
$uh = new URLHelper("securejackangers.imgix.net", "chester.png", "http", "Q61NvXIy", $params);
1717

18-
$this->assertEquals($uh->getURL(), "http://securejackangers.imgix.net/chester.png?s=cff7bdfd1b32d82e6b516f7fd3b4f1f4");
18+
$this->assertEquals("http://securejackangers.imgix.net/chester.png?&s=711dfe95b041008a3c6f460a40052282", $uh->getURL());
1919
}
2020

2121
public function testHelperBuildSignedURLWithHashSetterParams() {
2222
$uh = new URLHelper("securejackangers.imgix.net", "chester.png", "http", "Q61NvXIy");
2323
$uh->setParameter("w", 500);
24-
$this->assertEquals($uh->getURL(), "http://securejackangers.imgix.net/chester.png?w=500&s=0ddf97bf1a266a1da6c30c6ce327f917");
24+
$this->assertEquals("http://securejackangers.imgix.net/chester.png?w=500&s=0ddf97bf1a266a1da6c30c6ce327f917", $uh->getURL());
2525
}
2626

2727
public function testHelperBuildSignedURLWithHashSetterParamsHttps() {
2828
$uh = new URLHelper("securejackangers.imgix.net", "chester.png", "https", "Q61NvXIy");
2929
$uh->setParameter("w", 500);
30-
$this->assertEquals($uh->getURL(), "https://securejackangers.imgix.net/chester.png?w=500&s=0ddf97bf1a266a1da6c30c6ce327f917");
30+
$this->assertEquals("https://securejackangers.imgix.net/chester.png?w=500&s=0ddf97bf1a266a1da6c30c6ce327f917", $uh->getURL());
3131
}
3232
}
3333

0 commit comments

Comments
 (0)