ShifterFilms
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-30-2012
09:59 PM
CloudFront Secure streaming
We've had a bit of an issue figuring out how to use CloudFront for a protected stream. We have preview episodes which are okay to use public, not https url's, but for all full catalog, we need to have security in place.
Can someone who uses Amazon CloudFront point us in the right direction as to what exactly we need to do to get our Roku channel to authenticate with our private CloudFront URLs? Where in the code do we deal with SSL certificates?
Can someone who uses Amazon CloudFront point us in the right direction as to what exactly we need to do to get our Roku channel to authenticate with our private CloudFront URLs? Where in the code do we deal with SSL certificates?
14 REPLIES 14
ShifterFilms
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-10-2012
11:23 AM
Re: CloudFront Secure streaming
I found somewhat of a solution for this with expiring URLs. I'd like a better solution.
It appears if you have a ? in the URL, the Roku will not read the URL correctly. So after I generate the expiring URL with authentication keys, I'm using a URL shortener hosted on my server to create a new URL. Then I'm having the XML file written dynamically and updated through a cron job.
Hope this helps someone. Or if somebody has a better solution, let me know.
It appears if you have a ? in the URL, the Roku will not read the URL correctly. So after I generate the expiring URL with authentication keys, I'm using a URL shortener hosted on my server to create a new URL. Then I'm having the XML file written dynamically and updated through a cron job.
Hope this helps someone. Or if somebody has a better solution, let me know.

RokuJoel
Binge Watcher
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-10-2012
01:32 PM
Re: CloudFront Secure streaming
I don't believe there is any reason why a ? in a url would cause any problems whatsoever. What might cause problems is a failure to urlencode the parameters in the URL after the ?.
- Joel
- Joel
ShifterFilms
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-11-2012
12:04 PM
Re: CloudFront Secure streaming
Joel -
Can you provide an example of how that would be structured?
Can you provide an example of how that would be structured?

RokuMarkn
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-11-2012
01:15 PM
Re: CloudFront Secure streaming
Just to be clear, the question mark in your URL is the marker that begins the URL parameters, correct? Not some other question mark embedded in the parameters or anything like that? Can you provide an example of the kind of URL you are using?
--Mark
--Mark

RokuJoel
Binge Watcher
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-11-2012
01:40 PM
Re: CloudFront Secure streaming
"ShifterFilms" wrote:
Joel -
Can you provide an example of how that would be structured?
you might create your url like this:
url="http://myserver.com/restAPI?getPopSongs="+urlencode("Justin Bieber")+"&grammyNominated=true"
with a urlencode function like this:
function urlencode(text as string) as string
xfer=createobject("roUrlTransfer")
return xfer.urlencode(text)
end function
ShifterFilms
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-11-2012
04:24 PM
Re: CloudFront Secure streaming
The URL would be something like this:
http://d34TCSSDs9r8qxa.cloudfront.net/VIDEONAME.mp4?Expires=4340056027&Signature=xxce456iLCc5phPnt8NrH~orflXZs34rljsgfnkjx5sntPXj7Ov~YQ50ZOHsdafeTTfawoiLG1ndNxB5C3uh8Zsv2qil6Z2QGradEA34M9y8y-kNZ2lSbiwaVOEYt0UYh3TIvpKIpS9Mz15TSrsksioDSS~rC-U_&Key-Pair-Id=A45RRTQASD456LDF
http://d34TCSSDs9r8qxa.cloudfront.net/VIDEONAME.mp4?Expires=4340056027&Signature=xxce456iLCc5phPnt8NrH~orflXZs34rljsgfnkjx5sntPXj7Ov~YQ50ZOHsdafeTTfawoiLG1ndNxB5C3uh8Zsv2qil6Z2QGradEA34M9y8y-kNZ2lSbiwaVOEYt0UYh3TIvpKIpS9Mz15TSrsksioDSS~rC-U_&Key-Pair-Id=A45RRTQASD456LDF

RokuMarkn
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-11-2012
04:33 PM
Re: CloudFront Secure streaming
Since there are tildes in the parameters, they need to be encoded as RokuJoel said. There are three parameters (Expires, Signature, and Key-Pair-Id), so each of the 3 values should be URL encoded.
--Mark
--Mark
belltown
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-11-2012
05:40 PM
Re: CloudFront Secure streaming
"RokuMarkn" wrote:
Since there are tildes in the parameters, they need to be encoded as RokuJoel said. There are three parameters (Expires, Signature, and Key-Pair-Id), so each of the 3 values should be URL encoded.
--Mark
Yes, tildes ("~") should be encoded, according to RFC 1738. However, it appears that UrlEncode () does not encode tildes.
I ran the following code snippet:
ut = CreateObject ("roUrlTransfer")
For c = 0 To 127
ch = Chr (c)
urlEncode = ut.UrlEncode (ch)
If Len (urlEncode) = 1 And ch = urlEncode
Print "Did not encode: " + ch
EndIf
End For
and got the following result:
------ Running ------
Did not encode: -
Did not encode: .
Did not encode: 0
Did not encode: 1
Did not encode: 2
Did not encode: 3
Did not encode: 4
Did not encode: 5
Did not encode: 6
Did not encode: 7
Did not encode: 8
Did not encode: 9
Did not encode: A
Did not encode: B
Did not encode: C
Did not encode: D
Did not encode: E
Did not encode: F
Did not encode: G
Did not encode: H
Did not encode: I
Did not encode: J
Did not encode: K
Did not encode: L
Did not encode: M
Did not encode: N
Did not encode: O
Did not encode: P
Did not encode: Q
Did not encode: R
Did not encode: S
Did not encode: T
Did not encode: U
Did not encode: V
Did not encode: W
Did not encode: X
Did not encode: Y
Did not encode: Z
Did not encode: _
Did not encode: a
Did not encode: b
Did not encode: c
Did not encode: d
Did not encode: e
Did not encode: f
Did not encode: g
Did not encode: h
Did not encode: i
Did not encode: j
Did not encode: k
Did not encode: l
Did not encode: m
Did not encode: n
Did not encode: o
Did not encode: p
Did not encode: q
Did not encode: r
Did not encode: s
Did not encode: t
Did not encode: u
Did not encode: v
Did not encode: w
Did not encode: x
Did not encode: y
Did not encode: z
Did not encode: ~
So it looks like UrlEncode encodes all characters except: hyphen ("-"), underscore ("_"), period ("."), alphanumerics and tilde ("~").
I don't believe this is the correct behavior according to RFC 1738.
Also, when I run the above code using Escape () instead of UrlEncode () I get the exact same output even though they are supposed to encode differently.
Is this a bug, or am I missing something here?
ShifterFilms
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-12-2012
01:12 AM
Re: CloudFront Secure streaming
This is the partial solution to creating the CloudFront URLs needed. This PHP function will create valid expiring URL's CloudFront likes:
My solution was to take this function and use it in conjunction with a URL shorterning script. That way I didn't have to deal with any BrightScript to format the URL's properly. The other solutions presented are probably cleaner, but if you're a little BrightScript retarded like myself, this could be a solution for you.
function getSignedURL($resource, $timeout)
{
//This comes from key pair you generated for cloudfront
$keyPairId = "YOURKEYPAIRIDHERE1";
$expires = time() + $timeout; //Time out in seconds
$json = '{"Statement":[{"Resource":"'.$resource.'","Condition":{"DateLessThan":{"AWS:EpochTime":'.$expires.'}}}]}';
//Read Cloudfront Private Key Pair
$fp=fopen("your-keyfile.pem","r");
$priv_key=fread($fp,8192);
fclose($fp);
//Create the private key
$key = openssl_get_privatekey($priv_key);
if(!$key)
{
echo "<p>Failed to load private key!</p>";
return;
}
//Sign the policy with the private key
if(!openssl_sign($json, $signed_policy, $key, OPENSSL_ALGO_SHA1))
{
echo '<p>Failed to sign policy: '.openssl_error_string().'</p>';
return;
}
//Create url safe signed policy
$base64_signed_policy = base64_encode($signed_policy);
$signature = str_replace(array('+','=','/'), array('-','_','~'), $base64_signed_policy);
//Construct the URL
$url = $resource.'?Expires='.$expires.'&Signature='.$signature.'&Key-Pair-Id='.$keyPairId;
return $url;
}
My solution was to take this function and use it in conjunction with a URL shorterning script. That way I didn't have to deal with any BrightScript to format the URL's properly. The other solutions presented are probably cleaner, but if you're a little BrightScript retarded like myself, this could be a solution for you.