Your Digital Media Has Never Looked So Good

 
shibuyashadows
Topic Author
Posts: 27
Joined: Sat Nov 12, 2016 1:43 am

AddHeader bug in context of videoPlayer (prevents using CloudFront for HLS)

Wed Nov 16, 2016 8:42 pm

AWS cloudfront requires 3 cookie headers to be set in the request in order to authorize

curl -v -H 'Cookie: CloudFront-Policy=xxxx' -H 'Cookie: CloudFront-Signature=xxxx' -H 'Cookie: CloudFront-Key-Pair-Id=xxxx' https://xxxx.cloudfront.net/index.m3u

in roku

request.AddHeader("Cookie","CloudFront-Policy=xxxx")
request.AddHeader("Cookie","CloudFront-Signature=xxxx")
request.AddHeader("Cookie","CloudFront-Key-Pair-Id=xxx")

This works fine with a roUrlTransfer object and authorizes correctly, however when using a VideoPlayer object AddHeader always replaces any header with the same name, this behavior also happens when setting via an setHttpAgent command.

Add Cookies also doesn't work with CloudFront as although it sends the headers across it seems in a format not recognized by CloudFront, the delimiters in the header are ";" rather than "," which I think is the standard.

httpAgent.EnableCookies()
httpAgent.AddCookies(cookies)
    cookies = [
        {Path:"/", Domain:"xxxx.cloudfront.net", Name: "CloudFront-Policy",Value:"xxxx"},
        {Path:"/", Domain:"xxxx.cloudfront.net", Name:"CloudFront-Signature",Value:"xxxx"},
        {Path:"/", Domain:"xxxx.cloudfront.net", Name:"CloudFront-Key-Pair-Id",Value:"xxxx"}
    ]
 
EnTerr
** Valued Community Member **
Posts: 3834
Joined: Sun Jan 02, 2011 2:41 am

Re: AddHeader bug in context of videoPlayer (prevents using CloudFront for HLS)

Wed Nov 16, 2016 10:20 pm

The correct separator is ";".
Naturally, your code will work better if you reverse the order of setting and using the variable, i.e. 
httpAgent.EnableCookies()
cookies = [
    {Name: "CloudFront-Policy", Value: "xxxx"},
    {Name: "CloudFront-Signature", Value: "xxxx"},
    {Name: "CloudFront-Key-Pair-Id", Value: "xxxx"}
]
httpAgent.AddCookies(cookies)

Also, i don't think there is a point to setting anything else but Name and Value for the request (don't quote be on that "because, Roku" - but FWIW the other keys are when coming back from the server)
 
shibuyashadows
Topic Author
Posts: 27
Joined: Sat Nov 12, 2016 1:43 am

Re: AddHeader bug in context of videoPlayer (prevents using CloudFront for HLS)

Wed Nov 16, 2016 11:11 pm

Thanks for the reply. I think I can rule out that cookies are the issue then. 

The problem is CloudFront expects 3 distinct http headers each named  "Cookie", and VideoPlayer objects don't support this. 
 
EnTerr
** Valued Community Member **
Posts: 3834
Joined: Sun Jan 02, 2011 2:41 am

Re: AddHeader bug in context of videoPlayer (prevents using CloudFront for HLS)

Wed Nov 16, 2016 11:40 pm

shibuyashadows wrote:
The problem is CloudFront expects 3 distinct http headers each named  "Cookie", and VideoPlayer objects don't support this. 

If true, this would be most unusual. 
Because it would fly in the face of https://tools.ietf.org/html/rfc6265#section-5.4 which says
5.4.  The Cookie Header
  The user agent includes stored cookies in the Cookie HTTP request header.
  When the user agent generates an HTTP request, the user agent MUST NOT attach more than one Cookie header field.


Call it leap of faith if you will, but no way CloudFront would demand breaking the RFC.
Last edited by EnTerr on Wed Nov 16, 2016 11:50 pm, edited 1 time in total.
 
shibuyashadows
Topic Author
Posts: 27
Joined: Sat Nov 12, 2016 1:43 am

Re: AddHeader bug in context of videoPlayer (prevents using CloudFront for HLS)

Wed Nov 16, 2016 11:47 pm

It could well be non-standards compliant

Here is the reference from Amazon:
https://aws.amazon.com/premiumsupport/k ... s3-origin/

In any case there is inconsistent behavior in Roku between the VideoPlayer and roUrlTransfer components. roUrlTransfer allows multiple headers with the same name and VideoPlayer doesn't.
 
EnTerr
** Valued Community Member **
Posts: 3834
Joined: Sun Jan 02, 2011 2:41 am

Re: AddHeader bug in context of videoPlayer (prevents using CloudFront for HLS)

Thu Nov 17, 2016 12:01 am

shibuyashadows wrote:
It could well be non-standards compliant

Here is the reference from Amazon:
https://aws.amazon.com/premiumsupport/k ... s3-origin/

That's not reference - that is an example. But note if a RFC-broken request works, it does not mean a RFC-compliant cookie header won't work! Odds are both work. To determine what the case is, try a corrected one - i.e. instead of:
curl -v -H 'Cookie: CloudFront-Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kM2J4Y2k1emplNGJvNi5jbG91ZGZyb250Lm5ldC9pbmRleC5odG1sIiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNDQyMTgwMTYxfX19XX0_' -H 'Cookie: CloudFront-Signature=ZmKpEDq0AyMwhW6V-seB61zvpGvEsQo2HdOBJQs2qdblimiwtY9clXk4N9odyKu4ACl8nmYQ2ufBXsHcZTecGFS7apNWttORlKYiDJGlgBVQ8XGXF3SXO~buiR3UdqHd6K5-YdwZL1UZMFMSpZb3HNKYetT5Su5Koeq0Vl11smNrz76dsbY-ialGsVYkf4seoMR65UJhLq7TrspHZLEXl7I6SEA7FC7gKQP7-g8vACuZ1jpvniqaJoQphzcV4VWfxLZKifLA9GzjtARJaGqYjNrWkWmTIJ3wFTurMmwTId9~MFfDGwcNULerMKkgKotY630c~T4TpVQFpmwijCoQbg__' -H 'Cookie: CloudFront-Key-Pair-Id=XXXXXXXXXXXXXXXXXXX' https://d123example.cloudfront.net/index.html

do a "monocooque" 8)
curl -v -H 'Cookie: CloudFront-Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kM2J4Y2k1emplNGJvNi5jbG91ZGZyb250Lm5ldC9pbmRleC5odG1sIiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNDQyMTgwMTYxfX19XX0_; CloudFront-Signature=ZmKpEDq0AyMwhW6V-seB61zvpGvEsQo2HdOBJQs2qdblimiwtY9clXk4N9odyKu4ACl8nmYQ2ufBXsHcZTecGFS7apNWttORlKYiDJGlgBVQ8XGXF3SXO~buiR3UdqHd6K5-YdwZL1UZMFMSpZb3HNKYetT5Su5Koeq0Vl11smNrz76dsbY-ialGsVYkf4seoMR65UJhLq7TrspHZLEXl7I6SEA7FC7gKQP7-g8vACuZ1jpvniqaJoQphzcV4VWfxLZKifLA9GzjtARJaGqYjNrWkWmTIJ3wFTurMmwTId9~MFfDGwcNULerMKkgKotY630c~T4TpVQFpmwijCoQbg__; CloudFront-Key-Pair-Id=XXXXXXXXXXXXXXXXXXX' https://d123example.cloudfront.net/index.html


Notice the cookie separator is "; " - semicolon and space, not just semicolon. If Roku is sending ";" without space, that would be a bug, let us know?

On side note - why signed cookie and not signed URL?
 
shibuyashadows
Topic Author
Posts: 27
Joined: Sat Nov 12, 2016 1:43 am

Re: AddHeader bug in context of videoPlayer (prevents using CloudFront for HLS)

Thu Nov 17, 2016 2:45 am

you are absolutely right, the curl command worked with the " ;" delimiter, I did the same in a single Cookie http header:


    policy = "CloudFront-Policy=xxxx"
    sig = "CloudFront-Signature=xxxx"
    pairid = "CloudFront-Key-Pair-Id=xxx"
    httpAgent.AddHeader("Cookie",policy + "; " + sig + "; " + pairid)


And it now works correctly. Many thanks for your help on this!


On side note - why signed cookie and not signed URL?

I am using the cookie header so that the subsequent requests for the .ts files will also have the header on the request, I assumed this wasn't possible with the URL property of the VideoPlayer.
 
EnTerr
** Valued Community Member **
Posts: 3834
Joined: Sun Jan 02, 2011 2:41 am

Re: AddHeader bug in context of videoPlayer (prevents using CloudFront for HLS)

Thu Nov 17, 2016 8:58 am

shibuyashadows wrote:
you are absolutely right, the curl command worked with the " ;" delimiter, I did the same in a single Cookie http header:
... And it now works correctly. Many thanks for your help on this!

Ah, this is interesting - why is .AddCookies() failing then?! There might be a bug in Roku's implementation after all. Can you see with a packet sniffer what is going on? I have this gut feeling that maybe they are using ";" as separator instead of the "; " RFC mandate?

Let's exorcise this demon while the iron is hot! :twisted: 
 
shibuyashadows
Topic Author
Posts: 27
Joined: Sat Nov 12, 2016 1:43 am

Re: AddHeader bug in context of videoPlayer (prevents using CloudFront for HLS)

Thu Nov 17, 2016 4:14 pm

I managed to get AddCookies working also, I had to include the path as "/" and the domain, otherwise roku doesn't send the header. This seems sensible to me from a security point of view, so that if the httpagent calls out to a different domain, the headers won't get sent. I will use this method in my implementation.


    cookies = [
        {Name: "CloudFront-Policy",Value:"xxx",Path:"/", Domain:"xxx.cloudfront.net"},
        {Name:"CloudFront-Signature",Value:"xxx",Path:"/", Domain:"xxx.cloudfront.net"},
        {Name:"CloudFront-Key-Pair-Id",Value:"xxx", Path:"/", Domain:"xxx.cloudfront.net"}
    ]

    httpAgent.EnableCookies()
    httpAgent.AddCookies(cookies)
 
EnTerr
** Valued Community Member **
Posts: 3834
Joined: Sun Jan 02, 2011 2:41 am

Re: AddHeader bug in context of videoPlayer (prevents using CloudFront for HLS)

Thu Nov 17, 2016 4:24 pm

shibuyashadows wrote:
I managed to get AddCookies working also, I had to include the path as "/" and the domain, otherwise roku doesn't send the header. This seems sensible to me from a security point of view, so that if the httpagent calls out to a different domain, the headers won't get sent. I will use this method in my implementation.

Huh, amusing. Weird but okay. Great news.
Sorry for giving bad advice earlier of skipping the path and domain... albeit i disclaimed "don't quote me on that" :mrgreen:
 
bmbudai
Posts: 8
Joined: Thu Jun 20, 2019 9:54 am

Re: AddHeader bug in context of videoPlayer (prevents using CloudFront for HLS)

Thu Jun 20, 2019 11:33 am

This may be a long shot since it's been a while since this thread was active, but I'm trying to get the same scenario working. How are you generating the signature? I am sha1 hashing a string version of the access policy, and then rsa signing it. I'm getting an "Access Denied" error every time. I was not able to get the signature right with URL signing either. I always got "Access Denied" with that as well. I am able to use Amazon's URL-signing perl script to sign URLs and get temporary access to my content, but I can't run perl code in my Roku channel... Unfortunately, the hashing/signing process I do in brightscript doesn't come up with a working signature.

Who is online

Users browsing this forum: No registered users and 2 guests