Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
abemishler
Level 7

SSL "broke" my channel [SOLVED]

Hello all,

My channel is based on the "videoplayer" example found in the RokuSDK download.

The code to parse a feed is straight forward, yet I am having difficulty getting past the "Can't parse feed" error thrown by:


xml=CreateObject("roXMLElement")
if not xml.Parse(rsp) then
print "Can't parse feed"
return invalid
endif


starting on line 65 of "categoryFeed.brs". This wasn't always the case, however, and I believe I know the reason why. One thing that has changed recently on my server is that we default to serving all content through https. (I have verified the validity of my XML and know for certain the XML itself is not causing the error).

I believe the following line is the reason I can no longer load/parse my feed:

http = NewHttp(conn.UrlCategoryFeed)


Does anyone have experience connecting with https? I've tried searching The Documentation but the search feature doesn't return very useful results. Google doesn't return very useful results either.

I'm hoping to find a method/function I could call similar to:


NewHttps(conn.UrlCategoryFeed)


Thanks in advance,
Abe

edit: marked as [SOLVED] in subject
0 Kudos
11 Replies
Roku Employee
Roku Employee

Re: SSL "broke" my channel

To make a request with SSL, be sure you're setting a certificate file on your roURLTransfer object.

http://sdkdocs.roku.com/display/sdkdoc/roUrlTransfer

The URL Transfer object authenticates your web server by calling SetCertificatesFile()with a .pem file that includes the certificate authority cert for the authority (like Verisign, Thawte, etc… or your own with OpenSSL) that signed your web server certificate before making the https request. You can use the Roku standard cert bundle (similar to Mozilla) stored in common:/certs/ca-bundle.crt.
Your web server can authenticate that the requested connection is from a Roku Streaming Player and that the request is from your application by taking the following actions:

Add the Roku CA certificate to the web server's certificate authorities keychain. The Roku CA certificate is available in the SDK distribution package, in certs/cacert.pem
Configure your web server to reject any connection that does not have a valid client certificate.
Check the X-Roku-Reserved-Dev-Id header in the request. It should contain the Developer ID of your application. If it does not, another application on the Roku is attempting to access the server, so the request should be rejected.

In order for your web server to perform the steps above to authenticate your Roku Streaming Player, your application needs to call the following functions before performing any https requests:


Example
object.SetCertificatesFile("common:/certs/ca-bundle.crt")
object.AddHeader("X-Roku-Reserved-Dev-Id", "")
object.InitClientCertificates()
0 Kudos
abemishler
Level 7

Re: SSL "broke" my channel

Thanks for the reply. Unfortunately, I'm not enough of a brightscript wizard to fully wrap my head around the implementation details. I don't see that I _have_ a "roUrlTransfer" object, and I don't understand what to do with one since it looks like I need an "roXMLElement". So, wondering if "roXMLElement" was a child of "roUrlTransfer" I tried the code pasted below (it didn't work).

So I'm wondering how to convert/cast? an "roUrlTransfer" object into an "roXMLElement" object? Or, how do I provide the context of a new "roUrlTransfer" object to the "roXMLElement" object that I need to do the parsing?

Also, at this point, I don't care about validating that the request is coming from my particular application.


Function load_category_feed(conn As Object) As Dynamic

'---- putting this here doesn't seem to do anything useful.
'---- Probably because I'm not using secObj later
secObj = CreateObject("roUrlTransfer")
secObj.SetCertificatesFile("common:/certs/ca-bundle.crt")
secObj.AddHeader("X-Roku-Reserved-Dev-Id", "")
secObj.InitClientCertificates()

http = NewHttp(conn.UrlCategoryFeed)

Dbg("url: ", http.Http.GetUrl())

m.Timer.Mark()
rsp = http.GetToStringWithRetry()
Dbg("Took: ", m.Timer)

m.Timer.Mark()
xml=CreateObject("roXMLElement")
'---- --------------------------------------
'---- begin failed experiment
xml.SetCertificatesFile("common:/certs/ca-bundle.crt")
xml.AddHeader("X-Roku-Reserved-Dev-Id", "")
xml.InitClientCertificates()
'---- end failed experiment
'---- --------------------------------------
if not xml.Parse(rsp) then
print "Can't parse feed"
return invalid
endif
Dbg("Parse Took: ", m.Timer)

...


Thanks for reading this far.

Best,
Abe
0 Kudos
abemishler
Level 7

Re: SSL "broke" my channel [SOLVED]

It took me a while to figure out the structure of the API documentation. Once I figured out that the actual API calls were available via the links under "Supported Interfaces", I caught on quickly.

For future devs struggling with this issue, here's what I did. As I mentioned before, my channel is based on the "videoplayer" example. The following code is based on the "categoryFeed.brs" file. You will notice stark similarities upon comparison.

The following code is great for loading unencrypted resources, but not encrypted resources, so comment it out or delete it.


Function load_category_feed(conn As Object) As Dynamic

'** Make an http object to retrieve the unencrypted resource
'http = NewHttp(conn.UrlCategoryFeed)
'Dbg("url: ", http.Http.GetUrl())


I wanted access to an encrypted resource. Here is where setting up the roUrlTransfer object is necessary:


'** Make the category feed work with an encrypted resource
https = CreateObject("roUrlTransfer")
https.SetUrl(conn.UrlCategoryFeed)
https.SetCertificatesFile("common:/certs/ca-bundle.crt")
https.AddHeader("X-Roku-Reserved-Dev-Id", "")
https.InitClientCertificates()


Then it is quite necessary to use it. Notice the API call is slightly different on the roUrlTransfer object. There is no "GetToStringWithRetry" function, just "GetToString".


m.Timer.Mark()
'** The unencrypted response
'rsp = http.GetToStringWithRetry()
'** The encrypted response
rsps = https.GetToString()
Dbg("Took: ", m.Timer)


Previously, I overlooked what the roXMLElement was doing. It takes a response as an argument and parses the response. So I changed it to parse my new encrypted response (rsps) instead of the unencrypted response (rsp).


m.Timer.Mark()
xml=CreateObject("roXMLElement")
'** Parse the encrypted response (rsps) or unencrypted response (rsp)
if not xml.Parse(rsps) then
print "Can't parse feed"
return invalid
endif
Dbg("Parse Took: ", m.Timer)


There are other files you will need to modify if you too base your channel on the "videoplayer" example. roPosterScreen objects also support the ifHttpAgent interface. If you load banner ads from an encrypted resource,


sdAdUrl = "https:// ..."
hdAdUrl = "https:// ..."
screen.SetAdUrl(sdAdUrl, hdAdUrl)

'** Make the screen work with encrypted resources
screen.SetCertificatesFile("common:/certs/ca-bundle.crt")
screen.AddHeader("X-Roku-Reserved-Dev-Id", "")
screen.InitClientCertificates()

screen.setAdDisplayMode("scale-to-fit")
screen.Show()


In total, I made similar changes in categoryFeed.brs, appPosterScreen.brs, appHomeScreen.brs, and showFeed.brs. Hopefully this helps you out if you are currently facing the same questions I was.

Abe
0 Kudos
moz-peterbe
Level 7

Re: SSL "broke" my channel [SOLVED]

This is great! It helped me get mine working too.

However, my categories.xml and mychannel.xml contain references to images that are on our HTTPS CDN too.
You can see our categories.xml on https://air.mozilla.org/roku/categories.xml

How do you tell Roku about the certs for downloading images on HTTPS?
0 Kudos
destruk
Level 10

Re: SSL "broke" my channel [SOLVED]

Images won't work with https on gridscreens so you'll need to use http for those - but for other screens you set the certificates file before showing the screen.
http://sdkdocs.roku.com/display/sdkdoc/ifHttpAgent
(as posted in the reply above yours)
0 Kudos
moz-peterbe
Level 7

Re: SSL "broke" my channel [SOLVED]

That is sad.
Does the Roku simply not support any kind of HTTPS for images?
0 Kudos
destruk
Level 10

Re: SSL "broke" my channel [SOLVED]

It does if you load the certificate for most all the screens and files - just the gridscreen is a known longstanding bug they haven't tackled yet.
0 Kudos
moz-peterbe
Level 7

Re: SSL "broke" my channel [SOLVED]

Good. So there is hope.

I'm not sure what the "gridscreen" is to be honest.

Right now I don't have my Roku device available but when I do I'll sprinkle the code with things like
screen.SetCertificatesFile("common:/certs/ca-bundle.crt")
screen.InitClientCertificates()
0 Kudos
moz-peterbe
Level 7

Re: SSL "broke" my channel [SOLVED]

\o/ Yay!

By adding:

screen.SetCertificatesFile("common:/certs/ca-bundle.crt")
screen.InitClientCertificates()

to the appHomeScreen.brs file fixed it. Now it works.
0 Kudos