OWASP O2 Platform Blog

O2 Script: Downloading File

Here is a script that simpifies the process of downloading a file which consumes an old Form Control that I created ages ago in O2

Its really amazing how much the new version of O2 and its API dramatically simplity the code created (for reference look at the original code ascx_DownloadFile.cs to see how much more padding I had to add when I was not using Lamda funtions and extension methods)


Func<Uri, string,string> downloadFile =
    (uri, targetFile)=> {
                            "Downloading file {0} to location:{1}".info(uri.str(), targetFile);
                            if (targetFile.fileExists())        // don't download if file already exists
                            {
                                "File already existed, so skipping download".debug();
                                return targetFile;
                            }
                            var sync = new System.Threading.AutoResetEvent(false);
                                var downloadControl = O2Gui.open<ascx_DownloadFile>("Downloading: {0}".format(uri.str()), 455  ,170 );                           
                                downloadControl.setAutoCloseOnDownload(true);                           
                                downloadControl.setCallBackWhenCompleted((file)=>    downloadControl.parentForm().close());
                                downloadControl.onClosed(()=>sync.Set());
                                downloadControl.setDownloadDetails(uri.str(), targetFile);                           
                                downloadControl.downloadFile();
                            sync.WaitOne();                         // wait for download complete or form to be closed
                            if (targetFile.fileExists())       
                                return targetFile;
                            return null;
                        };

Func<Uri, string> downloadFileToTempLocation =
    (uri) => {
                var fileName = uri.Segments.Last();
                if (fileName.valid())
                {
                    var targetFile = "".tempDir().pathCombine(fileName);
                    Files.deleteFile(targetFile);
                    return downloadFile(uri, targetFile);
                }
                else
                    "Could not extract filename from provided uri: {0}".error(uri.str());
                return null;                   
             };
            
var fileToDownload = http://s3.amazonaws.com/O2_Downloads/nikto-2.1.3.zip;
return downloadFileToTempLocation(fileToDownload.uri());
//var localFile = "nikto-2.1.3.zip".tempFile();
//return downloadFile(fileToDownload.uri(), localFile);

//using O2.Views.ASCX.CoreControls

Once I had the code above running (in O2’s Quick Development GUI), it was a simple process to make it into the following extension methods:

public static class DownloadFiles_ExtensionMethods
    {       
        public static string download(this string fileToDownload)
        {
            return fileToDownload.uri().download();
        }
       
        public static string download(this Uri uri)
        {
            return uri.downloadFile();
        }
        public static string downloadFile(this Uri uri)
        {
            if (uri.isNull())
                return null;
            var fileName = uri.Segments.Last();
            if (fileName.valid())
            {
                var targetFile = "".tempDir().pathCombine(fileName);
                Files.deleteFile(targetFile);
                return downloadFile(uri, targetFile);
            }
            else
                "Could not extract filename from provided uri: {0}".error(uri.str());
            return null;                   
        }
       
        public static string downloadFile(this Uri uri, string targetFile)
        {
            if (uri.isNull())
                return null;
            "Downloading file {0} to location:{1}".info(uri.str(), targetFile);
            if (targetFile.fileExists())        // don't download if file already exists
            {
                "File already existed, so skipping download".debug();
                return targetFile;
            }
            var sync = new System.Threading.AutoResetEvent(false);
                var downloadControl = O2Gui.open<ascx_DownloadFile>("Downloading: {0}".format(uri.str()), 455  ,170 );                           
                downloadControl.setAutoCloseOnDownload(true);                           
                downloadControl.setCallBackWhenCompleted((file)=>    downloadControl.parentForm().close());
                downloadControl.onClosed(()=>sync.Set());
                downloadControl.setDownloadDetails(uri.str(), targetFile);                           
                downloadControl.downloadFile();
            sync.WaitOne();                         // wait for download complete or form to be closed
            if (targetFile.fileExists())       
                return targetFile;
            return null;
        }       
    }

which can now be easily consumed in O2 using:

var fileToDownload = "http://s3.amazonaws.com/O2_Downloads/nikto-2.1.3.zip";
return fileToDownload.download();

or just

return "http://s3.amazonaws.com/O2_Downloads/nikto-2.1.3.zip".download();

March 6, 2011 Posted by | O2 Internals | Leave a comment