Changeset 2725


Ignore:
Timestamp:
6/27/2012 2:33:12 AM (2 years ago)
Author:
lowjoel
Message:

Forward-port from Eraser 6.0:

  • Implement manual redirections. Automatic redirections are dropping the content-disposition header we need for the request.
  • Handle cancellations by users who dismiss the UAC dialog.
  • Handle non-zero exit codes from the installer processes.
Location:
trunk/eraser
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser

  • trunk/eraser/Eraser/UpdateForm.cs

    r2516 r2725  
    3434using System.Net.Mime; 
    3535using System.Globalization; 
     36using System.ComponentModel; 
    3637 
    3738using Eraser.Util; 
     
    3940 
    4041using DoWorkEventArgs = System.ComponentModel.DoWorkEventArgs; 
     42using ProgressChangedEventArgs = Eraser.Plugins.ProgressChangedEventArgs; 
    4143using ProgressChangedEventHandler = Eraser.Plugins.ProgressChangedEventHandler; 
    4244using RunWorkerCompletedEventArgs = System.ComponentModel.RunWorkerCompletedEventArgs; 
     
    715717            try 
    716718            { 
    717                 //Request the download. 
    718                 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Link); 
    719                 using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
    720                 { 
    721                     //Do the progress calculations 
    722                     progress.Total = response.ContentLength; 
    723  
    724                     //Check for a suggested filename. 
    725                     ContentDisposition contentDisposition = null; 
    726                     foreach (string header in response.Headers.AllKeys) 
    727                         if (header.ToUpperInvariant() == "CONTENT-DISPOSITION") 
    728                             contentDisposition = new ContentDisposition(response.Headers[header]); 
    729  
    730                     //Create the file name. 
    731                     DownloadedFile = new FileInfo(Path.Combine( 
    732                         TempPath.FullName, string.Format(CultureInfo.InvariantCulture, 
    733                             "{0:00}-{1}", ++DownloadFileIndex, contentDisposition == null ? 
    734                                 Path.GetFileName(Link.GetComponents(UriComponents.Path, UriFormat.Unescaped)) : 
    735                                 contentDisposition.FileName))); 
    736  
    737                     using (Stream responseStream = response.GetResponseStream()) 
    738                     using (FileStream fileStream = DownloadedFile.OpenWrite()) 
     719                Uri downloadLink = Link; 
     720                ContentDisposition contentDisposition = null; 
     721                for (int redirects = 0; redirects < 20; ++redirects) 
     722                { 
     723                    //Request the download. 
     724                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(downloadLink); 
     725                    request.AllowAutoRedirect = false; 
     726                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
    739727                    { 
    740                         //Copy the information into the file stream 
    741                         int lastRead = 0; 
    742                         byte[] buffer = new byte[16384]; 
    743                         while ((lastRead = responseStream.Read(buffer, 0, buffer.Length)) != 0) 
     728                        //Check for a suggested filename. Store this until we get the final URI. 
     729                        foreach (string header in response.Headers.AllKeys) 
     730                            if (header.ToUpperInvariant() == "CONTENT-DISPOSITION") 
     731                                contentDisposition = new ContentDisposition(response.Headers[header]); 
     732 
     733                        //Handle 3xx series response codes. 
     734                        if ((int)response.StatusCode >= 300 && (int)response.StatusCode <= 399) 
    744735                        { 
    745                             fileStream.Write(buffer, 0, lastRead); 
    746  
    747                             //Compute progress 
    748                             progress.Completed = fileStream.Position; 
    749  
    750                             //Call the progress handler 
    751                             if (handler != null) 
    752                                 handler(this, new ProgressChangedEventArgs(progress, null)); 
     736                            //Redirect. 
     737                            bool locationHeader = false; 
     738                            foreach (string header in response.Headers.AllKeys) 
     739                                if (header.ToUpperInvariant() == "LOCATION") 
     740                                { 
     741                                    locationHeader = true; 
     742                                    downloadLink = new Uri(response.Headers[header]); 
     743                                    break; 
     744                                } 
     745 
     746                            if (!locationHeader) 
     747                                throw new WebException("A redirect response was received but no redirection" + 
     748                                    "URI was provided."); 
     749 
     750                            continue; 
    753751                        } 
     752 
     753                        //Do the progress calculations 
     754                        progress.Total = response.ContentLength; 
     755 
     756                        //Create the file name. 
     757                        DownloadedFile = new FileInfo(Path.Combine( 
     758                            TempPath.FullName, string.Format(CultureInfo.InvariantCulture, 
     759                                "{0:00}-{1}", ++DownloadFileIndex, contentDisposition == null ? 
     760                                    Path.GetFileName(downloadLink.GetComponents(UriComponents.Path, UriFormat.Unescaped)) : 
     761                                    contentDisposition.FileName))); 
     762 
     763                        using (Stream responseStream = response.GetResponseStream()) 
     764                        using (FileStream fileStream = DownloadedFile.OpenWrite()) 
     765                        { 
     766                            //Copy the information into the file stream 
     767                            int lastRead = 0; 
     768                            byte[] buffer = new byte[16384]; 
     769                            while ((lastRead = responseStream.Read(buffer, 0, buffer.Length)) != 0) 
     770                            { 
     771                                fileStream.Write(buffer, 0, lastRead); 
     772 
     773                                //Compute progress 
     774                                progress.Completed = fileStream.Position; 
     775 
     776                                //Call the progress handler 
     777                                if (handler != null) 
     778                                    handler(this, new ProgressChangedEventArgs(progress, null)); 
     779                            } 
     780                        } 
     781 
     782                        //Let the event handler know the download is complete. 
     783                        progress.MarkComplete(); 
     784                        if (handler != null) 
     785                            handler(this, new ProgressChangedEventArgs(progress, null)); 
     786                        return; 
    754787                    } 
    755788 
    756                     //Let the event handler know the download is complete. 
    757                     progress.MarkComplete(); 
    758                     if (handler != null) 
    759                         handler(this, new ProgressChangedEventArgs(progress, null)); 
     789                    throw new WebException("The server is not redirecting properly."); 
    760790                } 
    761791            } 
     
    781811            info.UseShellExecute = true; 
    782812 
    783             Process process = Process.Start(info); 
    784             process.WaitForExit(Int32.MaxValue); 
     813            try 
     814            { 
     815                Process process = Process.Start(info); 
     816                process.WaitForExit(Int32.MaxValue); 
     817 
     818                if (process.ExitCode != 0) 
     819                    throw new ApplicationException(S._("Installation failed with exit code {0}", 
     820                        process.ExitCode)); 
     821            } 
     822            catch (Win32Exception e) 
     823            { 
     824                if (e.ErrorCode != 1223) 
     825                    throw; 
     826 
     827                throw new OperationCanceledException(S._("Installation cancelled"), e); 
     828            } 
     829 
    785830        } 
    786831 
Note: See TracChangeset for help on using the changeset viewer.