Forum Discussion

malort's avatar
malort
Visitor
11 years ago

roTextureManager and HTTPS (lag)

Per the docs (http://sdkdocs.roku.com/pages/viewpage. ... Id=3114344) it states to create an HTTPS roTextureRequest, you must set the certificate, however the roTextureManager seems to function properly without it. When you set the cert, it causes quite a bit of lag.

Below is a sample how to test performance. It doesn't actually make the request, but I have verified the requests do work with or without "request.SetCertificatesFile".

sub main()
m.tm = CreateObject("roTextureManager")
m.RunTest = tmRunTest

print "Create roTextureRequests without a certificate"
m.RunTest(false, 20)

print "Create roTextureRequests with certificate"
m.RunTest(true, 20)
end sub

sub tmRunTest(setCertificate=false as boolean, total=20 as integer)
url = "https://image.roku.com/blog/wp-content/uploads/2014/03/Roku-watch_standalone_BLOG_resize.png"

timer = CreateObject("roTimespan")
for num = 1 to total
request = CreateObject("roTextureRequest", url)
if setCertificate then
request.SetCertificatesFile("common:/certs/ca-bundle.crt")
request.InitClientCertificates()
end if
' we don't actually have to create the request to experience the lag
' m.tm.RequestTexture(request)
end for
ms = timer.TotalMilliseconds()

print " setCertificate: "; setCertificate
print " total requests: "; total
print " requests took: "; ms; "ms"
print " "
end sub


The output (from a Roku 3)

------ Running ------
Create roTextureRequests without a certificate
setCertificate: false
total requests: 20
requests took: 1ms

Create roTextureRequests with certificate
setCertificate: true
total requests: 20
requests took: 1565ms


Other than the possibility of fixing this lag in the firmware, is it valid to NOT set the certificate? Will the ifHttpAgent interface handle HTTPS without it? If so, it seems like a valid workaround for now.

8 Replies

  • I just confirmed the same lag here with the call to SetCertificatesFile on roTextureRequest. It takes over twice as long on the Roku TV.
    "malort" wrote:
    is it valid to NOT set the certificate? Will the ifHttpAgent interface handle HTTPS without it?

    In every other component, the answer to that question is no (no clue why Roku chose to make it a requirement instead of defaulting to the common certs). It's possible they added default certificates to the roTextureRequest, but I don't know if I'd trust that. If it works for you, then I suppose you could take the risk. Otherwise, you could potentially use roUrlTransfer to asynchronously download the image to tmp:, then load the tmp: path with an roTextureRequest. roUrlTransfer definitely requires the SetCertificatesFile(), but it doesn't experience anywhere near the lag that roTextureRequest exhibits.

    Roku*, I'd love to know why the SetCertificatesFile() call on roTextureRequest takes over 100ms. The fact that that call blocks execution for that long seriously undermines one of the primary uses for roTextureManager (asynchronous image loading).
  • "TheEndless" wrote:
    I just confirmed the same lag here with the call to SetCertificatesFile on roTextureRequest. It takes over twice as long on the Roku TV.
    "malort" wrote:
    is it valid to NOT set the certificate? Will the ifHttpAgent interface handle HTTPS without it?

    In every other component, the answer to that question is no (no clue why Roku chose to make it a requirement instead of defaulting to the common certs). It's possible they added default certificates to the roTextureRequest, but I don't know if I'd trust that. If it works for you, then I suppose you could take the risk. Otherwise, you could potentially use roUrlTransfer to asynchronously download the image to tmp:, then load the tmp: path with an roTextureRequest. roUrlTransfer definitely requires the SetCertificatesFile(), but it doesn't experience anywhere near the lag that roTextureRequest exhibits.


    It looks like you can get way with not setting the cert in roUrlTransfer, if you set EnablePeerVerification false. Of course, that isn't optimal, and it's probably moot because roUrlTransfer, as you said, doesn't experience the lag. I am wondering though, by not setting the cert in roTextureRequest, is defaulting to EnablePeerVerification=false or is it actually secure using the default certs?

    > obj = CreateObject("roUrlTransfer")
    > obj.SetUrl("https://roku.com")
    > ?len(obj.gettostring())
    0

    > obj.EnablePeerVerification(false)
    > ?len(obj.gettostring())
    39177


    "TheEndless" wrote:

    Roku*, I'd love to know why the SetCertificatesFile() call on roTextureRequest takes over 100ms. The fact that that call blocks execution for that long seriously undermines one of the primary uses for roTextureManager (asynchronous image loading).


    Just some more tests, to confirm the lag and show that roUrlTransfer isn't affected.


    roTextureRequest with and without "SetCertificatesFile"

    > for i = 0 to 5 : timer = CreateObject("roTimeSpan"): request = CreateObject("roTextureRequest", "https://roku.com"): ?timer.TotalMilliseconds() : end for
    0
    1
    0
    0
    0
    0
    > for i = 0 to 5 : timer = CreateObject("roTimeSpan"): request = CreateObject("roTextureRequest", "https://roku.com"): request.SetCertificatesFile("common:/certs/ca-bundle.crt") : ?timer.TotalMilliseconds() : end for
    76
    73
    72
    73
    73
    73


    roUrlTransfer with and without "SetCertificatesFile"

    > for i = 0 to 5: timer = CreateObject("roTimeSpan"): obj = CreateObject("roUrlTransfer") : ?timer.TotalMilliseconds() : end for
    1
    0
    1
    0
    1
    0

    > for i = 0 to 5 : timer = CreateObject("roTimeSpan"): obj = CreateObject("roUrlTransfer") : obj.SetCertificatesFile("common:/certs/ca-bundle.crt") : ?timer.TotalMilliseconds() : end for
    1
    1
    1
    0
    1
    0



    On a TCL Roku TV, as you stated, it's even worse. I don't even want to break out a Roku 1 or LT.

    for i = 0 to 5 : timer = CreateObject("roTimeSpan"): request = CreateObject("roTextureRequest", "https://roku.com"): request.SetCertificatesFile("common:/certs/ca-bundle.crt") : ?timer.TotalMilliseconds() : end for
    110
    130
    132
    133
    132
    130
  • Ok, I just had to share how it behaves on a Roku 2 (2720x)
    for i = 0 to 5 : timer = CreateObject("roTimeSpan"):  request = CreateObject("roTextureRequest", "https://roku.com"):  request.SetCertificatesFile("common:/certs/ca-bundle.crt") : ?timer.TotalMilliseconds() : end for
    315
    324
    313
    386
    325
    319
  • RokuSDK allows you to control trusted root CAs per http connection (SetCertificatesFile). The default ca-bundle contains lot of trusted CAs and loading it may take some time. If you know exactly which server you will be talking to you can use your own certificate file to minimize the delay. Following steps describe how to do it.

    1) Download CA certificate for the target website.
    2) Convert this PEM format (if it is in DER format. See below on how to do it)
    3) Copy PEM file (digicert.crt) to your package, and load it from the package (instead of using default ca bundle).

    request.SetCertificatesFile("pkg:/certs/digicert.crt")


    You can convert a DER cert to PEM format using openssl


    $ openssl x509 -inform DER -outform PEM -in digicert.cer > digicert.crt
    $ cat digicert.crt
    -----BEGIN CERTIFICATE-----
    MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
    MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
    d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
    ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
    MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
    LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
    RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
    +9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
    PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
    xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
    Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
    hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
    EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
    MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
    FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
    nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
    eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
    hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
    Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
    vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
    +OkuE6N36B9K
    -----END CERTIFICATE-----
  • "RokuIsrar" wrote:
    RokuSDK allows you to control trusted root CAs per http connection (SetCertificatesFile). The default ca-bundle contains lot of trusted CAs and loading it may take some time.

    With all due respect, that doesn't explain why it takes over 100ms (on a Roku 3, no less) on roTextureRequest, and only a couple milliseconds on roUrlTransfer. Perhaps more importantly, it doesn't explain why the certificates are loaded synchronously on an asynchronous component.
  • As TheEndless mentioned, that doesn't explain the lag in the roTextureRequest vs a roUrlTransfer. Even if we set the specific cert, which doesn't seem like a valid workaround as the endpoint can be arbitrary, setting the cert still takes ~15ms on a Roku3.

    The main question I have is if it's valid to exclude setting the certificate on an roTextureRequest? That seems to work on a Roku 3 and works around the issue, but I'm wondering if that is valid on all models supporting the roTextureManger. I'm assuming the roTextureRequest already has the default certs, or maybe it's just defaulting to "EnablePeerVerification(false)"? UPDATE: the roku 2 (2720x) requires setCertificates

    Secondary to the question. Is it possible to get roTextureRequest in parity with roUrlTransfer in the firmware?

    Thanks!

    "RokuIsrar" wrote:
    RokuSDK allows you to control trusted root CAs per http connection (SetCertificatesFile). The default ca-bundle contains lot of trusted CAs and loading it may take some time. If you know exactly which server you will be talking to you can use your own certificate file to minimize the delay. Following steps describe how to do it.
    [/code]
  • Any update from Roku on this? I just tested again, and https seems to work without setting the certificates on a Roku 2 - 2720x (this was not the case back in May). It still takes ~200-300ms if I set the certificates on the roTextureRequest with the default bundle. Is it possible a firmware update in the past few months has added support for https urls without setting the certificates? This has been impacting our channel on basically anything other than the Roku 3, and 2015 Roku 2. If a firmware update has fixed it, great, we'd just like to know so we can safely drop SetCertificatesFile() from the roTextureRequest for models on that specific firmware. If not, can you get some further assistance finding a valid workaround?