Download and wait over SSL

Hello
 
I was originally using the code below to download files for my app, the download would start, get the file and continue on.
 
[lua]local http = require(“socket.http”)
local ltn12 = require(“ltn12”)

local path = system.pathForFile( “truth.db”, system.DocumentsDirectory )
local myFile = io.open( path, “w+b” )
http.request{ url = “https://ssl.domain-name-removed.com/app-name/4/truth.db”, sink = ltn12.sink.file(myFile),}[/lua]
 
 
I decided to upgrade to SSL and make all communications secure (API keys etc in post data) but this broke socket.http.
 
I upgraded to Async network.download as it had no troubles with SSL.  I am using this code.

[lua]local function networkListener( event )
if ( event.isError ) then
print( “Network error!”)
elseif ( event.phase == “began” ) then
print(“3”)
if event.bytesEstimated <= 0 then
print( “Download starting, size unknown” )
else
print( "Download starting, estimated size: " … event.bytesEstimated )
end
elseif ( event.phase == “progress” ) then
print(“4”)
if event.bytesEstimated <= 0 then
print( "Download progress: " … event.bytesTransferred )
else
print( "Download progress: " … event.bytesTransferred … " of estimated: " … event.bytesEstimated )
end
elseif ( event.phase == “ended” ) then
print( “Download complete (” … event.response.filename … "), total bytes transferred: " … event.bytesTransferred )
print(“5”)
bIsDownloading = false
end
end

print(“1”)
local params = {}
params.progress = “download”
params.response = {filename = “helloworld.png”,baseDirectory = system.DocumentsDirectory}
print(“2”)
bIsDownloading = true
network.request( “https://ssl.domain-name-removed.com/app-name/4/helloworld.png”, “GET”, networkListener, params)

print(“6”)[/lua]

This downloads the file ok but because it is Async the code moves on and out of my GetFile function before the file has downloaded?

See Output from code above (note “6” gets fired before step 3,4,5).

2013-09-03 06:18:59.213 Corona Simulator[6345:707] 1

2013-09-03 06:18:59.213 Corona Simulator[6345:707] 2

2013-09-03 06:18:59.213 Corona Simulator[6345:707] 6

2013-09-03 06:19:00.910 Corona Simulator[6345:707] 3

2013-09-03 06:19:00.911 Corona Simulator[6345:707] Download starting, estimated size: 2796

2013-09-03 06:19:00.911 Corona Simulator[6345:707] 4

2013-09-03 06:19:00.912 Corona Simulator[6345:707] Download progress: 2796 of estimated: 2796

2013-09-03 06:19:00.913 Corona Simulator[6345:707] Download complete (corona.jpg), total bytes transferred: 2796

2013-09-03 06:19:00.913 Corona Simulator[6345:707] 5

How should I download the file file but pause the code from moving on until the file has downloaded.  

Should I create a local var called bIsBusyDownloading and create a loop after the download is triggered and check to see when the file has been downloaded?

If should I not use Async for SSL?  Is there a simpler way to download over SSL?

I only need one file downloaded at time.

Thanks In Advance

I am trying to build a reusable function that 

  • Works with SSL.
  • Check for network availabiltiy.
  • Check the file exists (HEAD 200).
  • Downloads the file.
  • Displays activity indicator.
  • Reports any errors.
  • Does not allow the code to move on until the file has downloaded (or error handled).

Anyone?

Heya FearTec,

A general suggestion regarding async file downloading… With something like corona (an event driven environment), you DON’T want to “pause” your code until the download completes…

There’s probably a dozen ways to handle this type of issue, but one of the more straightforward to explain would be to advise you to create your custom download function, but include a “callback” pointer in the arguments. Basically the callback pointer is a function to callback on download events and/or download completion.  (You might need to manage a small stack to maintain a list of callback pointers/url that was called for lookup).

To do this you would create your generic download handler various parts of your code call, and when corona finally sends the “complete” or failed event to the handler, it would call back the calling code to inform it of the download status. There’s a bunch of ways to write this depending on what you want as generic functionality (status bars, etc) versus what you want handled by the calling code, but overall the concept isn’t too foreign if you’re getting the hang of event driven coding.

For your code that is currently downloading files and processing them, you would need to break it into two parts basically. One part makes the calls for downloading specific files and then exits. The second part is called back when the download(s) are complete. In the middle is the generic download handler, showing status bars or whatever…

Thanks for the reply mpappas.
 
My files download happens on app startup and it downloads a 9 line file that has a hash value for each further file that could be downloaded.  further files are only downloaded if different, checks only happen ever xx minutes (saving polling).
 
 [lua] DoPrint(“GetTruthDB()”)
local path = system.pathForFile( “truth.db”, system.DocumentsDirectory )
local myFile = io.open( path, “w+b” )
http.request{ url = “https://sssl.domainnameremoved.com/folder/truth.json”, sink = ltn12.sink.file(myFile),}[/lua]
 
Since I upgraded to SSL I have to have call backs instead of httpsink that was working (with a short pause).  network.download required a callback.
 

[lua]

    local params = {}

    params.progress = “download”

    params.response = {

        filename = “truth.db”,

        baseDirectory = system.DocumentsDirectory

        }

    network.request( “https://ssl.domainnameremoved.com/folder/truth.json”, “GET”, networkListenerGetFileFromSSL,  params )

[/lua]

Ideally I would like to download a small file over SSL and have the function do the waiting for me

I see you have the progress listener enabled too. Like I said in the post above, you’ll probably want to start out making your download code (you posted above) into a function that is called, passing in the filename and a callback function that it will call when the download is complete.

You probably want this new general download function to handle your status bars (you set the progress parameter in your code above, which hints that you want to show download progress updates). So, for most progress events, your generci download function will just show the status bar update. When the ended event occurs, that’s when your download function will use the callback to inform your main code to continue onward (probably to start the next file).

As I mentioned in my above post, you will need to break that main code into several function, that generally flows like this

function1 - call to download file 1, pass function2 pointer as callback (called back when download of file1 is complete)

function2 - call to download file2, pass function3 as callback

function3 - call to download file 3

etc

etc

I am trying to build a reusable function that 

  • Works with SSL.
  • Check for network availabiltiy.
  • Check the file exists (HEAD 200).
  • Downloads the file.
  • Displays activity indicator.
  • Reports any errors.
  • Does not allow the code to move on until the file has downloaded (or error handled).

Anyone?

Heya FearTec,

A general suggestion regarding async file downloading… With something like corona (an event driven environment), you DON’T want to “pause” your code until the download completes…

There’s probably a dozen ways to handle this type of issue, but one of the more straightforward to explain would be to advise you to create your custom download function, but include a “callback” pointer in the arguments. Basically the callback pointer is a function to callback on download events and/or download completion.  (You might need to manage a small stack to maintain a list of callback pointers/url that was called for lookup).

To do this you would create your generic download handler various parts of your code call, and when corona finally sends the “complete” or failed event to the handler, it would call back the calling code to inform it of the download status. There’s a bunch of ways to write this depending on what you want as generic functionality (status bars, etc) versus what you want handled by the calling code, but overall the concept isn’t too foreign if you’re getting the hang of event driven coding.

For your code that is currently downloading files and processing them, you would need to break it into two parts basically. One part makes the calls for downloading specific files and then exits. The second part is called back when the download(s) are complete. In the middle is the generic download handler, showing status bars or whatever…

Thanks for the reply mpappas.
 
My files download happens on app startup and it downloads a 9 line file that has a hash value for each further file that could be downloaded.  further files are only downloaded if different, checks only happen ever xx minutes (saving polling).
 
 [lua] DoPrint(“GetTruthDB()”)
local path = system.pathForFile( “truth.db”, system.DocumentsDirectory )
local myFile = io.open( path, “w+b” )
http.request{ url = “https://sssl.domainnameremoved.com/folder/truth.json”, sink = ltn12.sink.file(myFile),}[/lua]
 
Since I upgraded to SSL I have to have call backs instead of httpsink that was working (with a short pause).  network.download required a callback.
 

[lua]

    local params = {}

    params.progress = “download”

    params.response = {

        filename = “truth.db”,

        baseDirectory = system.DocumentsDirectory

        }

    network.request( “https://ssl.domainnameremoved.com/folder/truth.json”, “GET”, networkListenerGetFileFromSSL,  params )

[/lua]

Ideally I would like to download a small file over SSL and have the function do the waiting for me

I see you have the progress listener enabled too. Like I said in the post above, you’ll probably want to start out making your download code (you posted above) into a function that is called, passing in the filename and a callback function that it will call when the download is complete.

You probably want this new general download function to handle your status bars (you set the progress parameter in your code above, which hints that you want to show download progress updates). So, for most progress events, your generci download function will just show the status bar update. When the ended event occurs, that’s when your download function will use the callback to inform your main code to continue onward (probably to start the next file).

As I mentioned in my above post, you will need to break that main code into several function, that generally flows like this

function1 - call to download file 1, pass function2 pointer as callback (called back when download of file1 is complete)

function2 - call to download file2, pass function3 as callback

function3 - call to download file 3

etc

etc