/// <summary> /// Object constructor. /// </summary> public BugTrapService(bool interactiveMode) { this.interactiveMode = interactiveMode; this.acceptCompleted = new ManualResetEvent(false); this.stopServiceEvent = new ManualResetEvent(false); this.endRequestEvent = new AutoResetEvent(false); this.applicationSettings = (ApplicationSettings)ConfigurationManager.GetSection("applicationSettings"); this.AutoLog = this.applicationSettings.LogEvents; this.InitializeComponent(); this.LoadDirectories(); }
/// <summary> /// Send notification e-mail. /// </summary> /// <param name="applicationSettings">Application settings.</param> /// <param name="email">Notification e-mail address.</param> /// <param name="appTitle">Application title.</param> private void SendEMail(ApplicationSettings applicationSettings, string email, string appTitle) { if (!string.IsNullOrEmpty(applicationSettings.SmtpHost) && !string.IsNullOrEmpty(email)) { string senderAddress = applicationSettings.SenderAddress ?? string.Empty; MailMessage message = new MailMessage(senderAddress, email); message.Subject = '\"' + appTitle + "\" error report"; message.Body = "BugTrap server received error report of \"" + appTitle + "\" on " + DateTime.Now.ToString(); SmtpClient smtpClient; if (applicationSettings.SmtpPort > 0) smtpClient = new SmtpClient(applicationSettings.SmtpHost, applicationSettings.SmtpPort); else smtpClient = new SmtpClient(applicationSettings.SmtpHost); if (applicationSettings.SmtpUser != null) smtpClient.Credentials = new NetworkCredential(applicationSettings.SmtpUser, applicationSettings.SmtpPassword); smtpClient.Send(message); } }
/// <summary> /// Find application entry in the application item list. /// </summary> /// <param name="applicationSettings">Application settings.</param> /// <param name="appEntry">Application entry to search for.</param> /// <returns>True if appropriate entry was found and false otherwise.</returns> private bool FindAppEntry(ApplicationSettings applicationSettings, AppEntry appEntry) { Set<AppEntry> applicationList = applicationSettings.ApplicationList; if (applicationList == null || applicationList.Count == 0) return true; if (applicationList.Contains(appEntry)) return true; if (appEntry.Version != null) { AppEntry appEntry2 = new AppEntry(appEntry.Name); if (applicationList.Contains(appEntry2)) return true; } return false; }
/// <summary> /// Find report file extension in the list of accepted extensions. /// </summary> /// <param name="applicationSettings">Application settings.</param> /// <param name="extension">Report file extension.</param> /// <returns>True if appropriate extension was found and false otherwise.</returns> private bool FindReportFileExtension(ApplicationSettings applicationSettings, string extension) { Set<string> reportFileExtensions = applicationSettings.ReportFileExtensions; if (reportFileExtensions == null || reportFileExtensions.Count == 0) return true; return reportFileExtensions.Contains(extension); }
/// <summary> /// Handle client request. /// </summary> private void HandleRequest() { ApplicationSettings applicationSettings = (ApplicationSettings)this.Application["applicationSettings"]; Dictionary <string, AppDirInfo> lastReportNumbers = (Dictionary <string, AppDirInfo>) this.Application["lastReportNumbers"]; if (this.Request.Form["protocolSignature"] != RequestHandler.protocolSignature) { throw new ApplicationException("Unsupported protocol version"); } MessageType messageType = (MessageType)byte.Parse(this.Request.Form["messageType"]); if (messageType != MessageType.CompundMessage) { throw new Exception("Unsupported message type"); } CompoundMessageFlags messageFlags = (CompoundMessageFlags)uint.Parse(this.Request.Form["messageFlags"]); if (messageFlags != CompoundMessageFlags.None) { throw new Exception("Unsupported message flags"); } string appName = this.Request.Form["appName"]; string appVersion = this.Request.Form["appVersion"]; if (appName == string.Empty) { appName = "(UNTITLED)"; } string appTitle = appVersion == string.Empty ? appName : appName + ' ' + appVersion; AppEntry appEntry = new AppEntry(appName, appVersion); if (!this.FindAppEntry(applicationSettings, appEntry)) { throw new Exception("Report excluded by filter"); } string extension = this.Request.Form["reportFileExtension"]; if (!this.FindReportFileExtension(applicationSettings, extension)) { throw new Exception("Invalid report file extension"); } HttpPostedFile reportDataFile = this.Request.Files["reportData"]; if (reportDataFile == null) { throw new Exception("Invalid report data"); } int reportSize = reportDataFile.ContentLength; if ((applicationSettings.MaxReportSize >= 0 && reportSize > applicationSettings.MaxReportSize) || reportSize <= 0) { throw new Exception("Report exceeds size limit"); } string email = this.Request.Form["notificationEMail"]; string dirName = GetAppDirName(appTitle); int maxReportNumber = 0, numReports = 0; lock (lastReportNumbers) { AppDirInfo appDirInfo; if (lastReportNumbers.TryGetValue(dirName, out appDirInfo)) { maxReportNumber = appDirInfo.MaxReportNumber; numReports = appDirInfo.NumReports; } if (applicationSettings.ReportsLimit >= 0 && numReports > applicationSettings.ReportsLimit) { throw new ApplicationException("Number of reports exceeds the limit"); } if (appDirInfo == null) { appDirInfo = new AppDirInfo(); lastReportNumbers[dirName] = appDirInfo; } appDirInfo.NumReports = ++numReports; appDirInfo.MaxReportNumber = ++maxReportNumber; } string reportDir = Path.Combine(applicationSettings.ReportPath, dirName); Directory.CreateDirectory(reportDir); string fileName = Global.GetReportName(applicationSettings, maxReportNumber, extension); string filePath = Path.Combine(reportDir, fileName); Stream inputStream = null; FileStream outputStream = null; try { inputStream = reportDataFile.InputStream; outputStream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None); byte[] reportData = new byte[1024]; while (reportSize > 0) { int chunkSize = Math.Min(reportSize, reportData.Length); inputStream.Read(reportData, 0, chunkSize); outputStream.Write(reportData, 0, chunkSize); reportSize -= chunkSize; } this.SendEMail(applicationSettings, email, appTitle); } finally { if (inputStream != null) { inputStream.Close(); } if (outputStream != null) { outputStream.Close(); } } }