FIX oembed to avoid mixed media issues

This commit is contained in:
Hamish Friedlander 2013-10-16 10:49:04 +13:00
parent 7b1cbabadf
commit 8801a50704
4 changed files with 95 additions and 7 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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;

View File

@ -1,6 +1,16 @@
<?php
class OembedTest extends SapphireTest {
public function setUp() {
parent::setUp();
Config::nest();
}
public function tearDown() {
Config::unnest();
parent::tearDown();
}
public function testGetOembedFromUrl() {
Config::inst()->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');
}
}
}