/// <summary>
        /// Note! This will propogate network exceptions, so client can catch them and warn or not warn the user.
        /// </summary>
        /// <returns></returns>
        public string GetAppcastUrl()
        {
            if (string.IsNullOrEmpty(TextContentsOfTable))
            {
                var client = new WebClient();
                {
                    TextContentsOfTable = client.DownloadString(URLOfTable);
                }
            }
            if (RunningVersion == default(Version))
            {
                RunningVersion = Assembly.GetExecutingAssembly().GetName().Version;
            }

            //NB Programmers: don't change this to some OS-specific line ending, this is  file read by both OS's. '\n' is common to files edited on linux and windows.
            foreach (var line in TextContentsOfTable.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries))
            {
                if (line.TrimStart().StartsWith("#"))
                {
                    continue;                     //comment
                }
                var parts = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length != 3)
                {
                    throw new ApplicationException("Could not parse a line of the UpdateVersionTable on " + URLOfTable + " '" + line + "'");
                }
                var lower = Version.Parse(parts[0]);
                var upper = Version.Parse(parts[1]);
                if (lower <= RunningVersion && upper >= RunningVersion)
                {
                    return(parts[2].Trim());
                }
            }
            return(string.Empty);
        }
Esempio n. 2
0
        private void LogTableContents()
        {
            //html may have javascript which has braces which will kill the string.format in WriteEvent
            var safeContents = TextContentsOfTable.Replace("{", "{{").Replace("}", "}}");

            Logger.WriteEvent("***UpdateVersionTable contents are " + Environment.NewLine + safeContents);
        }
Esempio n. 3
0
        /// <summary>
        /// If we can successfully download the update version table for the current channel,
        /// we return true and set the TextContentsOfTable property. Otherwise we return false and
        /// an UpdateTableLookupResult with an embedded error as an 'out' param.
        /// This internal method enables testing of captive portal situations
        /// </summary>
        /// <param name="client"></param>
        /// <param name="errorResult"></param>
        /// <returns></returns>
        internal bool CanGetVersionTableFromWeb(IBloomWebClient client, out UpdateTableLookupResult errorResult)
        {
            errorResult = null;
            try
            {
                Logger.WriteEvent("Channel is '" + ApplicationUpdateSupport.ChannelName + "'");
                Logger.WriteEvent("UpdateVersionTable looking for UpdateVersionTable URL: " + GetUrlOfTable());
                TextContentsOfTable = client.DownloadString(GetUrlOfTable());

                //things like captive portals will return an html page rather than the text file what we asked for, if the user isn't
                //logged in.
                if (TextContentsOfTable.ToLower().Contains("<html"))
                {
                    LogTableContents();
                    var msg = "Internet connection did not allow check for update.";
                    NonFatalProblem.Report(ModalIf.Alpha, PassiveIf.All, msg);                     // hopefully this will just 'toast'
                    errorResult = new UpdateTableLookupResult {
                        URL = string.Empty, Error = new WebException(msg)
                    };
                    return(false);
                }
            }
            catch (WebException e)
            {
                Logger.WriteEvent("***Error (WebException) in CanGetVersionTableFromWeb: " + e.Message);
                if (e.Status == WebExceptionStatus.ProtocolError)
                {
                    if (e.Response is HttpWebResponse resp && resp.StatusCode == HttpStatusCode.NotFound)
                    {
                        Logger.WriteEvent(
                            $"***Error: UpdateVersionTable failed to find a file at {GetUrlOfTable()} (channel='{ApplicationUpdateSupport.ChannelName}'");
                    }
                }
                else if (IsConnectionError(e))
                {
                    Logger.WriteEvent("***Error: UpdateVersionTable could not connect to the server");
                }
                errorResult = new UpdateTableLookupResult()
                {
                    Error = e
                };
                return(false);
            }
            catch (Exception e)
            {
                // We're getting some kind of exception thrown on some alpha users' machines, but we don't know why (BL-9211).
                // It isn't a WebException. I'm adding this catch block at least long enough to diagnose the problem,
                // but it is probably better to be here, anyway, since without it, Bloom crashes silently.
                Logger.WriteError("***Error (Exception) in CanGetVersionTableFromWeb:", e);

                errorResult = new UpdateTableLookupResult()
                {
                    Error = new WebException(e.Message)
                };
                return(false);
            }
            return(true);            // no error yet anyway!
        }
        /// <summary>
        /// If we can successfully download the update version table for the current channel,
        /// we return true and set the TextContentsOfTable property. Otherwise we return false and
        /// an UpdateTableLookupResult with an embedded error as an 'out' param.
        /// This internal method enables testing of captive portal situations
        /// </summary>
        /// <param name="client"></param>
        /// <param name="errorResult"></param>
        /// <returns></returns>
        internal bool CanGetVersionTableFromWeb(IBloomWebClient client, out UpdateTableLookupResult errorResult)
        {
            errorResult = null;
            try
            {
                Logger.WriteEvent("Channel is '" + ApplicationUpdateSupport.ChannelName + "'");
                Logger.WriteEvent("UpdateVersionTable looking for UpdateVersionTable URL: " + GetUrlOfTable());
                TextContentsOfTable = client.DownloadString(GetUrlOfTable());

                //things like captive portals will return an html page rather than the text file what we asked for, if the user isn't
                //logged in.
                if (TextContentsOfTable.ToLower().Contains("<html"))
                {
                    LogTableContents();
                    var msg = "Internet connection did not allow check for update.";
                    NonFatalProblem.Report(ModalIf.Alpha, PassiveIf.All, msg);                     // hopefully this will just 'toast'
                    errorResult = new UpdateTableLookupResult {
                        URL = string.Empty, Error = new WebException(msg)
                    };
                    return(false);
                }
            }
            catch (WebException e)
            {
                Logger.WriteEvent("***Error in LookupURLOfUpdate: " + e.Message);
                if (e.Status == WebExceptionStatus.ProtocolError)
                {
                    var resp = e.Response as HttpWebResponse;
                    if (resp != null && resp.StatusCode == HttpStatusCode.NotFound)
                    {
                        Logger.WriteEvent(String.Format("***Error: UpdateVersionTable failed to find a file at {0} (channel='{1}'",
                                                        GetUrlOfTable(), ApplicationUpdateSupport.ChannelName));
                    }
                }
                else if (IsConnectionError(e))
                {
                    Logger.WriteEvent("***Error: UpdateVersionTable could not connect to the server");
                }
                errorResult = new UpdateTableLookupResult()
                {
                    Error = e
                };
                return(false);
            }
            return(true);            // no error yet anyway!
        }
Esempio n. 5
0
        /// <summary>
        /// Note! This will propagate network exceptions, so client can catch them and warn or not warn the user.
        /// </summary>
        /// <returns></returns>
        public UpdateTableLookupResult LookupURLOfUpdate(bool forceReload = false)
        {
            if (string.IsNullOrEmpty(TextContentsOfTable) || forceReload)
            {
                Logger.WriteEvent("Enter LookupURLOfUpdate()");
                var client = new BloomWebClient();
                {
                    UpdateTableLookupResult errorResult;
                    if (!CanGetVersionTableFromWeb(client, out errorResult))
                    {
                        return(errorResult);
                    }
                }
            }
            if (RunningVersion == default(Version))
            {
                RunningVersion = Assembly.GetExecutingAssembly().GetName().Version;
            }

            var parsingErrorMsg = String.Empty;

            try
            {
                //NB Programmers: don't change this to some OS-specific line ending, this is  file read by both OS's. '\n' is common to files edited on linux and windows.
                foreach (var line in TextContentsOfTable.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    if (line.TrimStart().StartsWith("#"))
                    {
                        continue;                         //comment
                    }
                    var parts = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Length != 3)
                    {
                        Logger.WriteEvent("***Error: UpdateVersionTable could not parse line {0} of this updateTableContent:", line);
                        LogTableContents();
                        throw new ApplicationException(line);
                    }
                    var lower = Version.Parse(parts[0]);
                    var upper = Version.Parse(parts[1]);
                    if (lower <= RunningVersion && upper >= RunningVersion)
                    {
                        return new UpdateTableLookupResult {
                                   URL = parts[2].Trim()
                        }
                    }
                    ;
                }
                parsingErrorMsg = string.Format("{0} contains no record for this version of Bloom", GetUrlOfTable());
            }
            catch (ApplicationException e)
            {
                // BL-2654 Failure when reading upgrade table should not give a crash
                // In this case, a line of the UpdateVersionTable was not parseable
                // Put a message in the log and don't upgrade (and return a message that will get into a 'toast')
                parsingErrorMsg = "Could not parse a line of the UpdateVersionTable" + e.Message;
                Logger.WriteEvent(parsingErrorMsg);
            }
            catch (ArgumentException e)
            {
                // BL-2654 Failure when reading upgrade table should not give a crash
                // In this case, a version number in the UpdateVersionTable was not parseable
                // Put a message in the log and don't upgrade (and return a message that will get into a 'toast')
                parsingErrorMsg = "Could not parse a version number in the UpdateVersionTable" + e.Message;
                Logger.WriteEvent(parsingErrorMsg);
            }
            return(new UpdateTableLookupResult {
                URL = String.Empty, Error = new WebException(parsingErrorMsg)
            });
        }
Esempio n. 6
0
        /// <summary>
        /// Note! This will propogate network exceptions, so client can catch them and warn or not warn the user.
        /// </summary>
        /// <returns></returns>
        public UpdateTableLookupResult LookupURLOfUpdate()
        {
            if (String.IsNullOrEmpty(TextContentsOfTable))
            {
                Logger.WriteEvent("Enter LookupURLOfUpdate()");
                var client = new WebClient();
                {
                    try
                    {
                        Logger.WriteEvent("Channel is '" + ApplicationUpdateSupport.ChannelName + "'");
                        Logger.WriteEvent("UpdateVersionTable looking for UpdateVersionTable URL: " + GetUrlOfTable());
                        TextContentsOfTable = client.DownloadString(GetUrlOfTable());

                        //things like captive portals will return an html page rather than the text file what we asked for, if the user isn't
                        //logged in.
                        if (TextContentsOfTable.ToLower().Contains("<html"))
                        {
                            LogTableContents();
                            return(new UpdateTableLookupResult()
                            {
                                Error = new WebException("Internet connection did not allow check for update.")
                            });
                        }
                    }
                    catch (WebException e)
                    {
                        Logger.WriteEvent("***Error in LookupURLOfUpdate: " + e.Message);
                        if (e.Status == WebExceptionStatus.ProtocolError)
                        {
                            var resp = e.Response as HttpWebResponse;
                            if (resp != null && resp.StatusCode == HttpStatusCode.NotFound)
                            {
                                Logger.WriteEvent(String.Format("***Error: UpdateVersionTable failed to find a file at {0} (channel='{1}'",
                                                                GetUrlOfTable(), ApplicationUpdateSupport.ChannelName));
                            }
                        }
                        else if (IsConnectionError(e))
                        {
                            Logger.WriteEvent("***Error: UpdateVersionTable could not connect to the server");
                        }
                        return(new UpdateTableLookupResult()
                        {
                            Error = e
                        });
                    }
                }
            }
            if (RunningVersion == default(Version))
            {
                RunningVersion = Assembly.GetExecutingAssembly().GetName().Version;
            }

            var parsingErrorMsg = String.Empty;

            try
            {
                //NB Programmers: don't change this to some OS-specific line ending, this is  file read by both OS's. '\n' is common to files edited on linux and windows.
                foreach (var line in TextContentsOfTable.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    if (line.TrimStart().StartsWith("#"))
                    {
                        continue;                         //comment
                    }
                    var parts = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Length != 3)
                    {
                        Logger.WriteEvent("***Error: UpdateVersionTable could not parse line {0} of this updateTableContent:", line);
                        LogTableContents();
                        throw new ApplicationException(line);
                    }
                    var lower = Version.Parse(parts[0]);
                    var upper = Version.Parse(parts[1]);
                    if (lower <= RunningVersion && upper >= RunningVersion)
                    {
                        return new UpdateTableLookupResult()
                               {
                                   URL = parts[2].Trim()
                               }
                    }
                    ;
                }
                parsingErrorMsg = string.Format("{0} contains no record for this version of Bloom", GetUrlOfTable());
            }
            catch (ApplicationException e)
            {
                // BL-2654 Failure when reading upgrade table should not give a crash
                // In this case, a line of the UpdateVersionTable was not parseable
                // Put a message in the log and don't upgrade (and return a message that will get into a 'toast')
                parsingErrorMsg = "Could not parse a line of the UpdateVersionTable" + e.Message;
                Logger.WriteEvent(parsingErrorMsg);
            }
            catch (ArgumentException e)
            {
                // BL-2654 Failure when reading upgrade table should not give a crash
                // In this case, a version number in the UpdateVersionTable was not parseable
                // Put a message in the log and don't upgrade (and return a message that will get into a 'toast')
                parsingErrorMsg = "Could not parse a version number in the UpdateVersionTable" + e.Message;
                Logger.WriteEvent(parsingErrorMsg);
            }
            return(new UpdateTableLookupResult()
            {
                URL = String.Empty, Error = new WebException(parsingErrorMsg)
            });
        }