From 8801a50704e857e5844e5b362eb2fedf941ec37f Mon Sep 17 00:00:00 2001 From: Hamish Friedlander Date: Wed, 16 Oct 2013 10:49:04 +1300 Subject: [PATCH] FIX oembed to avoid mixed media issues --- _config/Oembed.yml | 20 +++++++++---- control/Director.php | 15 +++++++++- oembed/Oembed.php | 8 +++++ tests/oembed/OembedTest.php | 59 +++++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 7 deletions(-) diff --git a/_config/Oembed.yml b/_config/Oembed.yml index 4aa87b061..659d0f3d6 100644 --- a/_config/Oembed.yml +++ b/_config/Oembed.yml @@ -3,9 +3,11 @@ name: Oembed Oembed: providers: 'http://*.youtube.com/watch*': - 'http://www.youtube.com/oembed/' + http: 'http://www.youtube.com/oembed/', + https: 'https://www.youtube.com/oembed/?scheme=https' 'https://*.youtube.com/watch*': - 'https://www.youtube.com/oembed/?scheme=https' + http: 'http://www.youtube.com/oembed/', + https: 'https://www.youtube.com/oembed/?scheme=https' 'http://*.flickr.com/*': 'http://www.flickr.com/services/oembed/' 'http://*.viddler.com/*': @@ -15,11 +17,17 @@ Oembed: 'http://*.hulu.com/watch/*': 'http://www.hulu.com/api/oembed.json' 'http://*.vimeo.com/*': - 'http://www.vimeo.com/api/oembed.json' - 'https://twitter.com/*': - 'https://api.twitter.com/1/statuses/oembed.json' + http: 'http://www.vimeo.com/api/oembed.json', + https: 'https://www.vimeo.com/api/oembed.json' + 'https://*.vimeo.com/*': + http: 'http://www.vimeo.com/api/oembed.json', + https: 'https://www.vimeo.com/api/oembed.json' 'http://twitter.com/*': - 'https://api.twitter.com/1/statuses/oembed.json' + http: 'https://api.twitter.com/1/statuses/oembed.json', + https: 'https://api.twitter.com/1/statuses/oembed.json' + 'https://twitter.com/*': + http: 'https://api.twitter.com/1/statuses/oembed.json', + https: 'https://api.twitter.com/1/statuses/oembed.json' autodiscover: true enabled: diff --git a/control/Director.php b/control/Director.php index afb3335d5..2a0af4150 100644 --- a/control/Director.php +++ b/control/Director.php @@ -42,7 +42,16 @@ class Director implements TemplateGlobalProvider { * @var array */ private static $test_servers = array(); - + + /** + * Setting this explicitly specifies the protocol (http or https) used, overriding + * the normal behaviour of Director::is_https introspecting it from the request + * + * @config + * @var string - "http" or "https" to force the protocol, or false-ish to use default introspection from request + */ + private static $alternate_protocol; + /** * @config * @var string @@ -458,6 +467,10 @@ class Director implements TemplateGlobalProvider { * @return boolean */ public static function is_https() { + if ($protocol = Config::inst()->get('Director', 'alternate_protocol')) { + return $protocol == 'https'; + } + if(isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])) { if(strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) == 'https') { return true; diff --git a/oembed/Oembed.php b/oembed/Oembed.php index e598b4a59..3a2c067c4 100644 --- a/oembed/Oembed.php +++ b/oembed/Oembed.php @@ -50,6 +50,13 @@ class Oembed { protected static function find_endpoint($url) { foreach(self::get_providers() as $scheme=>$endpoint) { if(self::matches_scheme($url, $scheme)) { + $protocol = Director::is_https() ? 'https' : 'http'; + + if (is_array($endpoint)) { + if (array_key_exists($protocol, $endpoint)) $endpoint = $endpoint[$protocol]; + else $endpoint = reset($endpoint); + } + return $endpoint; } } @@ -66,6 +73,7 @@ class Oembed { protected static function matches_scheme($url, $scheme) { $urlInfo = parse_url($url); $schemeInfo = parse_url($scheme); + foreach($schemeInfo as $k=>$v) { if(!array_key_exists($k, $urlInfo)) { return false; diff --git a/tests/oembed/OembedTest.php b/tests/oembed/OembedTest.php index c8f684b2f..3570f7bb6 100644 --- a/tests/oembed/OembedTest.php +++ b/tests/oembed/OembedTest.php @@ -1,6 +1,16 @@ update('Oembed', 'providers', array( 'http://*.silverstripe.com/watch*'=>'http://www.silverstripe.com/oembed/' @@ -37,4 +47,53 @@ class OembedTest extends SapphireTest { $this->assertEquals($query['maxheight'], 'foo', 'Magically creates maxheight option'); $this->assertEquals($query['maxwidth'], 'bar', 'Magically creates maxwidth option'); } + + public function testRequestProtocolReflectedInGetOembedFromUrl() { + Config::inst()->update('Oembed', 'providers', array( + 'http://*.silverstripe.com/watch*'=> array( + 'http' => 'http://www.silverstripe.com/oembed/', + 'https' => 'https://www.silverstripe.com/oembed/?scheme=https', + ), + 'https://*.silverstripe.com/watch*'=> array( + 'http' => 'http://www.silverstripe.com/oembed/', + 'https' => 'https://www.silverstripe.com/oembed/?scheme=https', + ) + )); + + Config::inst()->update('Director', 'alternate_protocol', 'http'); + + foreach(array('http', 'https') as $protocol) { + $url = $protocol.'://www.silverstripe.com/watch12345'; + $result = Oembed::get_oembed_from_url($url); + + $this->assertInstanceOf('Oembed_Result', $result); + $this->assertEquals($result->getOembedURL(), + 'http://www.silverstripe.com/oembed/?format=json&url='.urlencode($url), + 'Returns http based URLs when request is over http, regardless of source URL'); + } + + Config::inst()->update('Director', 'alternate_protocol', 'https'); + + foreach(array('http', 'https') as $protocol) { + $url = $protocol.'://www.silverstripe.com/watch12345'; + $result = Oembed::get_oembed_from_url($url); + + $this->assertInstanceOf('Oembed_Result', $result); + $this->assertEquals($result->getOembedURL(), + 'https://www.silverstripe.com/oembed/?scheme=https&format=json&url='.urlencode($url), + 'Returns https based URLs when request is over https, regardless of source URL'); + } + + Config::inst()->update('Director', 'alternate_protocol', 'foo'); + + foreach(array('http', 'https') as $protocol) { + $url = $protocol.'://www.silverstripe.com/watch12345'; + $result = Oembed::get_oembed_from_url($url); + + $this->assertInstanceOf('Oembed_Result', $result); + $this->assertEquals($result->getOembedURL(), + 'http://www.silverstripe.com/oembed/?format=json&url='.urlencode($url), + 'When request protocol doesn\'t have specific handler, fall back to first option'); + } + } }