Http.GetPort() is crashing my whole app?

We’re trying to call an external PHP script to log/register a Roku. When I call a certain URL I see the Roku request the URL, but it never gets to the response portion. Digging shows that Http.GetPort() is crashing and causing the whole app die. See the example code below for a test case:

conn = CreateObject("roAssociativeArray")

account_num = ShowAccountEnterScreen("Please enter your account number to register this STB.")

' Works
conn.Url = "http://www.perturb.org/id.html"
' Broken
'conn.Url = "http://www.perturb.org/cgitest.php"

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
http = NewHttp(conn.Url)

'add serial number (unique ID) to the feed request
sn = GetDeviceESN()
http.AddParam("s",sn)
http.AddParam("c",account_num)

Dbg("Url: ", http.Http.GetUrl())
rsp = http.GetToStringWithTimeout(3)
Dbg("Response: " + rsp)

return 0

Interestingly, if I remove the ShowAccountEnterScreen I can fetch the remote HTML all day.

Function ShowAccountEnterScreen(message As String) As Dynamic
    port = CreateObject("roMessagePort")
    screen = CreateObject("roKeyboardScreen")
    screen.SetMessagePort(port)

    screen.SetTitle("Account Registration")
    'screen.SetText("account#")
    screen.SetDisplayText(message)
    screen.SetMaxLength(20)
    screen.AddButton(1, "Submit")
    screen.AddButton(2, "Cancel")
    screen.Show()

    while true
        msg = wait(0, screen.GetMessagePort())
        print "message received"
        if type(msg) = "roKeyboardScreenEvent"
            if msg.isScreenClosed()
                return null
            else if msg.isButtonPressed() then
                print "Evt:"; msg.GetMessage ();" idx:"; msg.GetIndex()
                if msg.GetIndex() = 1
                    data_entered = screen.GetText()
                    print "inputed text: "; data_entered
                    return data_entered
                elseif msg.GetIndex() = 2
                    return null
                endif
            endif
        endif
    end while
End Function

You didn’t share the specifics of the crash you’re seeing, but my first guess is that the your http variable is not a roURLTransfer object. That would probably give an error like:

Member function not found in BrightScript Component or interface

Hi, I’ve been working on the same project with scottchiefbaker. Thanks for the reply.

“RokuChris” wrote:
You didn’t share the specifics of the crash you’re seeing, but my first guess is that the your http variable is not a roURLTransfer object. That would probably give an error like:

Member function not found in BrightScript Component or interface

That’s the thing, we’re not seeing an error in debug at all. We would’ve posted any debug information, but there isn’t any. The app just quits after trying GetPort() on the Http which IS an roUrlTransfer object. We are using the sample code for a video streamer with urlUtils.brs. Here’s where the object is created:


REM ******************************************************
REM Constucts a URL Transfer object
REM ******************************************************

Function CreateURLTransferObject(url As String) as Object
    obj = CreateObject("roUrlTransfer")
    obj.SetPort(CreateObject("roMessagePort"))
    obj.SetUrl(url)
    obj.AddHeader("Content-Type", "application/x-www-form-urlencoded")
    obj.EnableEncodings(true)
    return obj
End Function

REM ******************************************************
REM Url Query builder
REM so this is a quick and dirty name/value encoder/accumulator
REM ******************************************************

Function NewHttp(url As String) as Object
    obj = CreateObject("roAssociativeArray")
    obj.Http                        = CreateURLTransferObject(url)
    obj.FirstParam                  = true
    obj.AddParam                    = http_add_param
    obj.AddRawQuery                 = http_add_raw_query
    obj.GetToStringWithRetry        = http_get_to_string_with_retry
    obj.PrepareUrlForQuery          = http_prepare_url_for_query
    obj.GetToStringWithTimeout      = http_get_to_string_with_timeout
    obj.PostFromStringWithTimeout   = http_post_from_string_with_timeout
    obj.CancelHTTPAsync             = http_cancel_async

    if Instr(1, url, "?") > 0 then obj.FirstParam = false

    return obj
End Function

Here is the function where GetPort() is called in which the app just exits:

REM ******************************************************
REM Performs Http.AsyncGetToString() with a single timeout in seconds
REM To the outside world this appears as a synchronous API.
REM ******************************************************

Function http_get_to_string_with_timeout(seconds as Integer) as String
    timeout% = 1000 * seconds

    str = ""
    m.Http.EnableFreshConnection(true) 'Don't reuse existing connections
    if (m.Http.AsyncGetToString())
        event = wait(timeout%, m.Http.GetPort()) <<<<<<< this is the last thing it attempts
        if type(event) = "roUrlEvent"
            str = event.GetString()
        elseif event = invalid
            Dbg("AsyncGetToString timeout")
            m.Http.AsyncCancel()
        else
            Dbg("AsyncGetToString unknown event", event)
        endif
    endif
    return str
End Function

We’re at a loss as to why the app just quits. Especially because it seems to work fine on a simple html page. We’ve been able to get other php scripts to work but it seems to happen after the “ShowAccountEnterScreen” function returns. Could there be an issue creating multiple "roMessagePort"s within the same function?

If there’s nothing dumped to the console, then it’s probably not crashing. Could it be exiting normally because you’re closing all the screens in the channel? You should open a facade screen at the bottom of your stack to keep that from happening.

viewtopic.php?f=34&t=50590&p=343312

“RokuChris” wrote:
If there’s nothing dumped to the console, then it’s probably not crashing. Could it be exiting normally because you’re closing all the screens in the channel? You should open a facade screen at the bottom of your stack to keep that from happening.

viewtopic.php?f=34&t=50590&p=343312

This fixed the issue immediately!! We’ve been banging our heads over this for hours! :slightly_smiling_face:

I think I understand why this has prevented the app from closing. Does it just keep a “screen” open throughout the app because it needs to be there otherwise it closes without one?

Oh man… what a weird issue. That totally fixed our issue. Weird that it was dying so repeatedly at the same line of code, that wasn’t related to the screen.

Thanks for the help.