From 0565da75d93f31b1237a4a2a64dcc907705efb91 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle Date: Wed, 18 Jun 2014 15:54:19 +1200 Subject: [PATCH 01/28] Added additional Raygun settings. --- Mindscape.Raygun4Net/RaygunSettings.cs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Mindscape.Raygun4Net/RaygunSettings.cs b/Mindscape.Raygun4Net/RaygunSettings.cs index 0f6b144c..230bbdd0 100644 --- a/Mindscape.Raygun4Net/RaygunSettings.cs +++ b/Mindscape.Raygun4Net/RaygunSettings.cs @@ -64,5 +64,26 @@ public string IgnoreFormDataNames get { return (string)this["ignoreFormDataNames"]; } set { this["ignoreFormDataNames"] = value; } } + + [ConfigurationProperty("ignoreHeaderNames", IsRequired = false, DefaultValue = "")] + public string IgnoreHeaderNames + { + get { return (string)this["ignoreHeaderNames"]; } + set { this["ignoreHeaderNames"] = value; } + } + + [ConfigurationProperty("ignoreCookieNames", IsRequired = false, DefaultValue = "")] + public string IgnoreCookieNames + { + get { return (string)this["ignoreCookieNames"]; } + set { this["ignoreCookieNames"] = value; } + } + + [ConfigurationProperty("ignoreServerVariableNames", IsRequired = false, DefaultValue = "")] + public string IgnoreServerVariableNames + { + get { return (string)this["ignoreServerVariableNames"]; } + set { this["ignoreServerVariableNames"] = value; } + } } } From 6653d2aecaf1025041f48dd1d7bcab5ed9a02cb4 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle Date: Wed, 18 Jun 2014 17:17:26 +1200 Subject: [PATCH 02/28] Added additional Ignore* RaygunClient methods. --- Mindscape.Raygun4Net/RaygunClient.cs | 67 +++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/Mindscape.Raygun4Net/RaygunClient.cs b/Mindscape.Raygun4Net/RaygunClient.cs index 9cc0be71..b120cc1a 100644 --- a/Mindscape.Raygun4Net/RaygunClient.cs +++ b/Mindscape.Raygun4Net/RaygunClient.cs @@ -17,7 +17,10 @@ public class RaygunClient { private readonly string _apiKey; private static List _wrapperExceptions; - private List _ignoredFormNames; + private List _ignoredFormNames = new List(); + private List _ignoreHeaderNames = new List(); + private List _ignoreCookieNames = new List(); + private List _ignoreServerVariableNames = new List(); internal const string SentKey = "AlreadySentByRaygun"; /// @@ -45,6 +48,21 @@ public RaygunClient() var ignoredNames = RaygunSettings.Settings.IgnoreFormDataNames.Split(','); IgnoreFormDataNames(ignoredNames); } + if (!string.IsNullOrEmpty(RaygunSettings.Settings.IgnoreHeaderNames)) + { + var ignoredNames = RaygunSettings.Settings.IgnoreHeaderNames.Split(','); + IgnoreHeaderNames(ignoredNames); + } + if (!string.IsNullOrEmpty(RaygunSettings.Settings.IgnoreCookieNames)) + { + var ignoredNames = RaygunSettings.Settings.IgnoreCookieNames.Split(','); + IgnoreCookieNames(ignoredNames); + } + if (!string.IsNullOrEmpty(RaygunSettings.Settings.IgnoreServerVariableNames)) + { + var ignoredNames = RaygunSettings.Settings.IgnoreServerVariableNames.Split(','); + IgnoreServerVariableNames(ignoredNames); + } } protected bool ValidateApiKey() @@ -116,17 +134,54 @@ public void AddWrapperExceptions(IEnumerable wrapperExceptions) /// you to remove sensitive data from the transmitted copy of the Form on the HttpRequest by specifying the keys you want removed. /// This method is only effective in a web context. /// - /// An enumerable list of keys (Names) to be stripped from the copy of the Form NameValueCollection when sending to Raygun. - public void IgnoreFormDataNames(IEnumerable names) + /// Keys to be stripped from the copy of the Form NameValueCollection when sending to Raygun. + public void IgnoreFormDataNames(params string[] names) { - if (_ignoredFormNames == null) + foreach (string name in names) { - _ignoredFormNames = new List(); + _ignoredFormNames.Add(name); } + } + /// + /// Adds a list of keys to ignore when attaching the headers of an HTTP POST request. This allows + /// you to remove sensitive data from the transmitted copy of the Headers on the HttpRequest by specifying the keys you want removed. + /// This method is only effective in a web context. + /// + /// Keys to be stripped from the copy of the Headers NameValueCollection when sending to Raygun. + public void IgnoreHeaderNames(params string[] names) + { foreach (string name in names) { - _ignoredFormNames.Add(name); + _ignoreHeaderNames.Add(name); + } + } + + /// + /// Adds a list of keys to ignore when attaching the cookies of an HTTP POST request. This allows + /// you to remove sensitive data from the transmitted copy of the Cookies on the HttpRequest by specifying the keys you want removed. + /// This method is only effective in a web context. + /// + /// Keys to be stripped from the copy of the Cookies NameValueCollection when sending to Raygun. + public void IgnoreCookieNames(params string[] names) + { + foreach (string name in names) + { + _ignoreCookieNames.Add(name); + } + } + + /// + /// Adds a list of keys to ignore when attaching the server variables of an HTTP POST request. This allows + /// you to remove sensitive data from the transmitted copy of the ServerVariables on the HttpRequest by specifying the keys you want removed. + /// This method is only effective in a web context. + /// + /// Keys to be stripped from the copy of the ServerVariables NameValueCollection when sending to Raygun. + public void IgnoreServerVariableNames(params string[] names) + { + foreach (string name in names) + { + _ignoreServerVariableNames.Add(name); } } From d2a75e9c754dd832cf06fa05ae2ef0e4534b9054 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle Date: Thu, 19 Jun 2014 16:49:47 +1200 Subject: [PATCH 03/28] Pass ignored lists to RaygunRequestMessage and support * for ignore all. --- .../Messages/RaygunRequestMessage.cs | 24 +++++++++++++------ Mindscape.Raygun4Net/RaygunClient.cs | 15 +++++------- Mindscape.Raygun4Net/RaygunMessageBuilder.cs | 4 ++-- .../Mindscape.Raygun4Net4.csproj | 1 + .../RaygunRequestMessageOptions.cs | 23 ++++++++++++++++++ 5 files changed, 49 insertions(+), 18 deletions(-) create mode 100644 Mindscape.Raygun4Net4/RaygunRequestMessageOptions.cs diff --git a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs index 642f804a..5941ac06 100644 --- a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs @@ -9,7 +9,7 @@ namespace Mindscape.Raygun4Net.Messages { public class RaygunRequestMessage { - public RaygunRequestMessage(HttpRequest request, List ignoredFormNames) + public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions options) { HostName = request.Url.Host; Url = request.Url.AbsolutePath; @@ -17,14 +17,14 @@ public RaygunRequestMessage(HttpRequest request, List ignoredFormNames) IPAddress = request.UserHostAddress; QueryString = ToDictionary(request.QueryString, Enumerable.Empty()); - Headers = ToDictionary(request.Headers, ignoredFormNames ?? Enumerable.Empty()); + Headers = ToDictionary(request.Headers, options.IgnoreHeaderNames); Headers.Remove("Cookie"); - Form = ToDictionary(request.Form, ignoredFormNames ?? Enumerable.Empty(), true); - Cookies = GetCookies(request.Cookies, ignoredFormNames ?? Enumerable.Empty()); + Form = ToDictionary(request.Form, options.IgnoreFormDataNames, true); + Cookies = GetCookies(request.Cookies, options.IgnoreCookieNames); // Remove ignored and duplicated variables - Data = ToDictionary(request.ServerVariables, ignoredFormNames ?? Enumerable.Empty()); + Data = ToDictionary(request.ServerVariables, options.IgnoreServerVariableNames); Data.Remove("ALL_HTTP"); Data.Remove("HTTP_COOKIE"); Data.Remove("ALL_RAW"); @@ -53,6 +53,11 @@ private IList GetCookies(HttpCookieCollection cookieCollection, IEnumerable s); + if (ignored.Count == 1 && ignored.Contains("*")) + { + return Enumerable.Empty().ToList(); + } + return Enumerable.Range(0, cookieCollection.Count) .Select(i => cookieCollection[i]) .Where(c => !ignored.Contains(c.Name)) @@ -62,6 +67,13 @@ private IList GetCookies(HttpCookieCollection cookieCollection, IEnumerable ignoreFields, bool truncateValues = false) { + var dictionary = new Dictionary(); + + if (ignoreFields.Count() == 1 && "*".Equals(ignoreFields.First())) + { + return dictionary; + } + IEnumerable keys; try @@ -73,8 +85,6 @@ private static IDictionary ToDictionary(NameValueCollection nameValueCollection, return new Dictionary { { "Values", "Not able to be retrieved" } }; } - var dictionary = new Dictionary(); - foreach (string key in keys) { try diff --git a/Mindscape.Raygun4Net/RaygunClient.cs b/Mindscape.Raygun4Net/RaygunClient.cs index b120cc1a..8a765b38 100644 --- a/Mindscape.Raygun4Net/RaygunClient.cs +++ b/Mindscape.Raygun4Net/RaygunClient.cs @@ -16,11 +16,8 @@ namespace Mindscape.Raygun4Net public class RaygunClient { private readonly string _apiKey; + private readonly RaygunRequestMessageOptions _requestMessageOptions = new RaygunRequestMessageOptions(); private static List _wrapperExceptions; - private List _ignoredFormNames = new List(); - private List _ignoreHeaderNames = new List(); - private List _ignoreCookieNames = new List(); - private List _ignoreServerVariableNames = new List(); internal const string SentKey = "AlreadySentByRaygun"; /// @@ -139,7 +136,7 @@ public void IgnoreFormDataNames(params string[] names) { foreach (string name in names) { - _ignoredFormNames.Add(name); + _requestMessageOptions.IgnoreFormDataNames.Add(name); } } @@ -153,7 +150,7 @@ public void IgnoreHeaderNames(params string[] names) { foreach (string name in names) { - _ignoreHeaderNames.Add(name); + _requestMessageOptions.IgnoreHeaderNames.Add(name); } } @@ -167,7 +164,7 @@ public void IgnoreCookieNames(params string[] names) { foreach (string name in names) { - _ignoreCookieNames.Add(name); + _requestMessageOptions.IgnoreCookieNames.Add(name); } } @@ -181,7 +178,7 @@ public void IgnoreServerVariableNames(params string[] names) { foreach (string name in names) { - _ignoreServerVariableNames.Add(name); + _requestMessageOptions.IgnoreServerVariableNames.Add(name); } } @@ -284,7 +281,7 @@ protected RaygunMessage BuildMessage(Exception exception, IList tags, ID exception = StripWrapperExceptions(exception); var message = RaygunMessageBuilder.New - .SetHttpDetails(HttpContext.Current, _ignoredFormNames) + .SetHttpDetails(HttpContext.Current, _requestMessageOptions) .SetEnvironmentDetails() .SetMachineName(Environment.MachineName) .SetExceptionDetails(exception) diff --git a/Mindscape.Raygun4Net/RaygunMessageBuilder.cs b/Mindscape.Raygun4Net/RaygunMessageBuilder.cs index 7f24522a..04b9b582 100644 --- a/Mindscape.Raygun4Net/RaygunMessageBuilder.cs +++ b/Mindscape.Raygun4Net/RaygunMessageBuilder.cs @@ -119,7 +119,7 @@ public IRaygunMessageBuilder SetUser(string user) return this; } - public IRaygunMessageBuilder SetHttpDetails(HttpContext context, List ignoredFormNames = null) + public IRaygunMessageBuilder SetHttpDetails(HttpContext context, RaygunRequestMessageOptions options = null) { if (context != null) { @@ -132,7 +132,7 @@ public IRaygunMessageBuilder SetHttpDetails(HttpContext context, List ig { return this; } - _raygunMessage.Details.Request = new RaygunRequestMessage(request, ignoredFormNames); + _raygunMessage.Details.Request = new RaygunRequestMessage(request, options ?? new RaygunRequestMessageOptions()); } return this; diff --git a/Mindscape.Raygun4Net4/Mindscape.Raygun4Net4.csproj b/Mindscape.Raygun4Net4/Mindscape.Raygun4Net4.csproj index 9fe2fd41..6c88e0ad 100644 --- a/Mindscape.Raygun4Net4/Mindscape.Raygun4Net4.csproj +++ b/Mindscape.Raygun4Net4/Mindscape.Raygun4Net4.csproj @@ -144,6 +144,7 @@ + diff --git a/Mindscape.Raygun4Net4/RaygunRequestMessageOptions.cs b/Mindscape.Raygun4Net4/RaygunRequestMessageOptions.cs new file mode 100644 index 00000000..604a62a6 --- /dev/null +++ b/Mindscape.Raygun4Net4/RaygunRequestMessageOptions.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Mindscape.Raygun4Net +{ + public class RaygunRequestMessageOptions + { + private readonly List _ignoredFormNames = new List(); + private readonly List _ignoreHeaderNames = new List(); + private readonly List _ignoreCookieNames = new List(); + private readonly List _ignoreServerVariableNames = new List(); + + public List IgnoreFormDataNames { get { return _ignoredFormNames; } } + + public List IgnoreHeaderNames { get { return _ignoreHeaderNames; } } + + public List IgnoreCookieNames { get { return _ignoreCookieNames; } } + + public List IgnoreServerVariableNames { get { return _ignoreServerVariableNames; } } + } +} From 92f47c4fec570e222e11b67b632c21636644c465 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle Date: Thu, 19 Jun 2014 16:57:31 +1200 Subject: [PATCH 04/28] Relocated the RaygunRequestMessageOptions class. --- Mindscape.Raygun4Net/Mindscape.Raygun4Net.csproj | 1 + .../RaygunRequestMessageOptions.cs | 0 Mindscape.Raygun4Net4/Mindscape.Raygun4Net4.csproj | 4 +++- 3 files changed, 4 insertions(+), 1 deletion(-) rename {Mindscape.Raygun4Net4 => Mindscape.Raygun4Net}/RaygunRequestMessageOptions.cs (100%) diff --git a/Mindscape.Raygun4Net/Mindscape.Raygun4Net.csproj b/Mindscape.Raygun4Net/Mindscape.Raygun4Net.csproj index 2478d17d..6fb8d1e6 100644 --- a/Mindscape.Raygun4Net/Mindscape.Raygun4Net.csproj +++ b/Mindscape.Raygun4Net/Mindscape.Raygun4Net.csproj @@ -74,6 +74,7 @@ + diff --git a/Mindscape.Raygun4Net4/RaygunRequestMessageOptions.cs b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs similarity index 100% rename from Mindscape.Raygun4Net4/RaygunRequestMessageOptions.cs rename to Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs diff --git a/Mindscape.Raygun4Net4/Mindscape.Raygun4Net4.csproj b/Mindscape.Raygun4Net4/Mindscape.Raygun4Net4.csproj index 6c88e0ad..55501e39 100644 --- a/Mindscape.Raygun4Net4/Mindscape.Raygun4Net4.csproj +++ b/Mindscape.Raygun4Net4/Mindscape.Raygun4Net4.csproj @@ -133,6 +133,9 @@ RaygunMessageBuilder.cs + + RaygunRequestMessageOptions.cs + RaygunSendingMessageEventArgs.cs @@ -144,7 +147,6 @@ - From 846ead3a72f09043b90fd4a5c133054cde722381 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle Date: Fri, 20 Jun 2014 14:44:30 +1200 Subject: [PATCH 05/28] Unit tests. --- .../RaygunRequestMessageTests.cs | 204 +++++++++++++++++- .../RaygunSettingsTests.cs | 18 ++ .../Messages/RaygunRequestMessage.cs | 10 + .../RaygunRequestMessageOptions.cs | 10 + 4 files changed, 235 insertions(+), 7 deletions(-) diff --git a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs index 1678b401..3f5df726 100644 --- a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs +++ b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs @@ -1,9 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Web; - using Mindscape.Raygun4Net.Messages; - using NUnit.Framework; namespace Mindscape.Raygun4Net.Tests @@ -28,7 +28,7 @@ public void SetUp() [Test] public void HostNameTest() { - var message = new RaygunRequestMessage(_defaultRequest, Enumerable.Empty().ToList()); + var message = new RaygunRequestMessage(_defaultRequest, new RaygunRequestMessageOptions()); Assert.That(message.HostName, Is.EqualTo("google.com")); } @@ -36,7 +36,7 @@ public void HostNameTest() [Test] public void UrlTest() { - var message = new RaygunRequestMessage(_defaultRequest, Enumerable.Empty().ToList()); + var message = new RaygunRequestMessage(_defaultRequest, new RaygunRequestMessageOptions()); Assert.That(message.Url, Is.EqualTo("/")); } @@ -44,7 +44,7 @@ public void UrlTest() [Test] public void HttpMethodTest() { - var message = new RaygunRequestMessage(_defaultRequest, Enumerable.Empty().ToList()); + var message = new RaygunRequestMessage(_defaultRequest, new RaygunRequestMessageOptions()); Assert.That(message.HttpMethod, Is.EqualTo("GET")); } @@ -54,9 +54,199 @@ public void QueryStringTest() { var request = new HttpRequest("test", "http://google.com", "test=test"); - var message = new RaygunRequestMessage(request, Enumerable.Empty().ToList()); + var message = new RaygunRequestMessage(request, new RaygunRequestMessageOptions()); Assert.That(message.QueryString, Contains.Item(new KeyValuePair("test", "test"))); } + + // Form data + + [Test] + public void FormData() + { + var request = CreateWritableRequest(); + + request.Form.Add("TestFormData1", "FormDataValue"); + request.Form.Add("TestFormData2", "FormDataValue"); + request.Form.Add("TestFormData3", "FormDataValue"); + Assert.AreEqual(3, request.Form.Count); + + var message = new RaygunRequestMessage(request, new RaygunRequestMessageOptions()); + + Assert.AreEqual(3, message.Form.Count); + Assert.IsTrue(message.Form.Contains("TestFormData1")); + Assert.IsTrue(message.Form.Contains("TestFormData2")); + Assert.IsTrue(message.Form.Contains("TestFormData3")); + } + + [Test] + public void IgnoreFormData() + { + var request = CreateWritableRequest(); + + request.Form.Add("TestFormData1", "FormDataValue"); + request.Form.Add("TestFormData2", "FormDataValue"); + request.Form.Add("TestFormData3", "FormDataValue"); + Assert.AreEqual(3, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "TestFormData2" }, Enumerable.Empty(), Enumerable.Empty(), Enumerable.Empty()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(2, message.Form.Count); + Assert.IsTrue(message.Form.Contains("TestFormData1")); + Assert.IsTrue(message.Form.Contains("TestFormData3")); + } + + [Test] + public void IgnoreMultipleFormData() + { + var request = CreateWritableRequest(); + + request.Form.Add("TestFormData1", "FormDataValue"); + request.Form.Add("TestFormData2", "FormDataValue"); + request.Form.Add("TestFormData3", "FormDataValue"); + Assert.AreEqual(3, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "TestFormData1", "TestFormData3" }, Enumerable.Empty(), Enumerable.Empty(), Enumerable.Empty()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Form.Count); + Assert.IsTrue(message.Form.Contains("TestFormData2")); + } + + [Test] + public void IgnoreAllFormData() + { + var request = CreateWritableRequest(); + + request.Form.Add("TestFormData1", "FormDataValue"); + request.Form.Add("TestFormData2", "FormDataValue"); + request.Form.Add("TestFormData3", "FormDataValue"); + Assert.AreEqual(3, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "*" }, Enumerable.Empty(), Enumerable.Empty(), Enumerable.Empty()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(0, message.Form.Count); + } + + private HttpRequest CreateWritableRequest() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + Type t = request.Form.GetType(); + PropertyInfo p = t.GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); + p.SetValue(request.Form, false, null); + return request; + } + + // Cookies + + [Test] + public void Cookies() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie3", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var message = new RaygunRequestMessage(request, new RaygunRequestMessageOptions()); + + Assert.AreEqual(3, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookie1")); + Assert.AreEqual(1, CookieCount(message, "TestCookie2")); + Assert.AreEqual(1, CookieCount(message, "TestCookie3")); + } + + [Test] + public void DuplicateCookies() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie", "CookieValue")); + Assert.AreEqual(2, request.Cookies.Count); + + var message = new RaygunRequestMessage(request, new RaygunRequestMessageOptions()); + + Assert.AreEqual(2, message.Cookies.Count); + Assert.AreEqual(2, CookieCount(message, "TestCookie")); + } + + [Test] + public void IgnoreCookie() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie3", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(Enumerable.Empty(), Enumerable.Empty(), new string[] { "TestCookie2" }, Enumerable.Empty()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(2, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookie1")); + Assert.AreEqual(1, CookieCount(message, "TestCookie3")); + } + + [Test] + public void IgnoreDuplicateCookie() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(Enumerable.Empty(), Enumerable.Empty(), new string[] { "TestCookie1" }, Enumerable.Empty()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookie2")); + } + + [Test] + public void IgnoreMultipleCookies() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie3", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(Enumerable.Empty(), Enumerable.Empty(), new string[] { "TestCookie1", "TestCookie3" }, Enumerable.Empty()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookie2")); + } + + [Test] + public void IgnoreAllCookies() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie3", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(Enumerable.Empty(), Enumerable.Empty(), new string[] { "*" }, Enumerable.Empty()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(0, message.Cookies.Count); + } + + private int CookieCount(RaygunRequestMessage message, string name) + { + int count = 0; + foreach(Mindscape.Raygun4Net.Messages.RaygunRequestMessage.Cookie cookie in message.Cookies) + { + if (name.Equals(cookie.Name)) + { + count++; + } + } + return count; + } } } diff --git a/Mindscape.Raygun4Net.Tests/RaygunSettingsTests.cs b/Mindscape.Raygun4Net.Tests/RaygunSettingsTests.cs index 0536c48e..eb0079a6 100644 --- a/Mindscape.Raygun4Net.Tests/RaygunSettingsTests.cs +++ b/Mindscape.Raygun4Net.Tests/RaygunSettingsTests.cs @@ -50,5 +50,23 @@ public void IgnoreFormDataNames_EmptyByDefault() { Assert.IsEmpty(RaygunSettings.Settings.IgnoreFormDataNames); } + + [Test] + public void IgnoreHeaderNames_EmptyByDefault() + { + Assert.IsEmpty(RaygunSettings.Settings.IgnoreHeaderNames); + } + + [Test] + public void IgnoreCookieNames_EmptyByDefault() + { + Assert.IsEmpty(RaygunSettings.Settings.IgnoreCookieNames); + } + + [Test] + public void IgnoreServerVariableNames_EmptyByDefault() + { + Assert.IsEmpty(RaygunSettings.Settings.IgnoreServerVariableNames); + } } } diff --git a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs index 5941ac06..473a36a3 100644 --- a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; @@ -9,8 +10,17 @@ namespace Mindscape.Raygun4Net.Messages { public class RaygunRequestMessage { + // TODO: making this obsolete doesn't help much because if the second parameter is null, there will be an ambiguous call. + [Obsolete("ignoredFormNames has now been split into 4 separate options. Use RaygunRequestMessage(HttpRequest, RaygunRequestMessageOptions)")] + public RaygunRequestMessage(HttpRequest request, List ignoredFormNames) + : this(request, new RaygunRequestMessageOptions(ignoredFormNames, ignoredFormNames, ignoredFormNames, ignoredFormNames)) + { + } + public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions options) { + options = options ?? new RaygunRequestMessageOptions(); + HostName = request.Url.Host; Url = request.Url.AbsolutePath; HttpMethod = request.RequestType; diff --git a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs index 604a62a6..d0e9b604 100644 --- a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs +++ b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs @@ -12,6 +12,16 @@ public class RaygunRequestMessageOptions private readonly List _ignoreCookieNames = new List(); private readonly List _ignoreServerVariableNames = new List(); + public RaygunRequestMessageOptions() { } + + public RaygunRequestMessageOptions(IEnumerable formNames, IEnumerable headerNames, IEnumerable cookieNames, IEnumerable serverVariableNames) + { + _ignoredFormNames.AddRange(formNames); + _ignoreHeaderNames.AddRange(headerNames); + _ignoreCookieNames.AddRange(cookieNames); + _ignoreServerVariableNames.AddRange(serverVariableNames); + } + public List IgnoreFormDataNames { get { return _ignoredFormNames; } } public List IgnoreHeaderNames { get { return _ignoreHeaderNames; } } From 2cd7cd2f06f4effd5c9032f2793dcbc250ce1d9f Mon Sep 17 00:00:00 2001 From: Jason Fauchelle Date: Fri, 20 Jun 2014 14:48:45 +1200 Subject: [PATCH 06/28] Increase the major version. --- AssemblyVersionInfo.cs | 4 ++-- Mindscape.Raygun4Net.Signed.nuspec | 2 +- Mindscape.Raygun4Net.nuspec | 2 +- XamarinComponent/Rakefile | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/AssemblyVersionInfo.cs b/AssemblyVersionInfo.cs index 690f5a9c..083ce473 100644 --- a/AssemblyVersionInfo.cs +++ b/AssemblyVersionInfo.cs @@ -12,5 +12,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.2.1.0")] -[assembly: AssemblyFileVersion("2.2.1.0")] +[assembly: AssemblyVersion("3.0.0.0")] +[assembly: AssemblyFileVersion("3.0.0.0")] diff --git a/Mindscape.Raygun4Net.Signed.nuspec b/Mindscape.Raygun4Net.Signed.nuspec index 02c8e2fc..8b82b3b2 100644 --- a/Mindscape.Raygun4Net.Signed.nuspec +++ b/Mindscape.Raygun4Net.Signed.nuspec @@ -2,7 +2,7 @@ Mindscape.Raygun4Net.Signed - 2.2.1 + 3.0.0 <authors>Mindscape</authors> <owners /> diff --git a/Mindscape.Raygun4Net.nuspec b/Mindscape.Raygun4Net.nuspec index b1eb9802..046af035 100644 --- a/Mindscape.Raygun4Net.nuspec +++ b/Mindscape.Raygun4Net.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata minClientVersion="2.5"> <id>Mindscape.Raygun4Net</id> - <version>2.2.1</version> + <version>3.0.0</version> <title /> <authors>Mindscape</authors> <owners /> diff --git a/XamarinComponent/Rakefile b/XamarinComponent/Rakefile index ba66826d..59c18c55 100644 --- a/XamarinComponent/Rakefile +++ b/XamarinComponent/Rakefile @@ -3,7 +3,7 @@ require "rake/clean" CLEAN.include "*.xam" CLEAN.include "xpkg" -COMPONENT = "raygun4net-2.2.1.xam" +COMPONENT = "raygun4net-3.0.0.xam" file "xpkg/xpkg.exe" do sh "if exist xpkg del /Q xpkg & rd xpkg" From 7dbd9babc04a9a640e40e4011414c1c199a73a29 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Fri, 20 Jun 2014 15:00:30 +1200 Subject: [PATCH 07/28] Deleted all obsolete methods and properties. --- .../Messages/RaygunEnvironmentMessage.cs | 19 -------- .../RaygunClient.cs | 44 ------------------- .../RaygunClient.cs | 44 ------------------- Mindscape.Raygun4Net/RaygunClient.cs | 44 ------------------- 4 files changed, 151 deletions(-) diff --git a/Mindscape.Raygun4Net.WindowsPhone/Messages/RaygunEnvironmentMessage.cs b/Mindscape.Raygun4Net.WindowsPhone/Messages/RaygunEnvironmentMessage.cs index 7251e8a2..0ff89b12 100644 --- a/Mindscape.Raygun4Net.WindowsPhone/Messages/RaygunEnvironmentMessage.cs +++ b/Mindscape.Raygun4Net.WindowsPhone/Messages/RaygunEnvironmentMessage.cs @@ -111,24 +111,5 @@ public RaygunEnvironmentMessage() public double UtcOffset { get; private set; } public string Locale { get; private set; } - - [Obsolete("This is never used")] - public ulong TotalVirtualMemory { get; private set; } - - [Obsolete("This is never used")] - public ulong AvailableVirtualMemory { get; private set; } - - [Obsolete("This is never used")] - public List<double> DiskSpaceFree - { - get { return _diskSpaceFree; } - set { _diskSpaceFree = value; } - } - - [Obsolete("This is never used")] - public ulong TotalPhysicalMemory { get; private set; } - - [Obsolete("This is never used")] - public ulong AvailablePhysicalMemory { get; private set; } } } \ No newline at end of file diff --git a/Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs b/Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs index b7601e9d..88bfb7f3 100644 --- a/Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs +++ b/Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs @@ -471,49 +471,5 @@ private void DeleteFile(File dir, string fileName) } } } - - /// <summary> - /// This method is obsolete. Use the ApplicationVersion property to set a custom version string. - /// Then use a Send method that does not accept a version. - /// </summary> - [Obsolete("Set the ApplicationVersion property instead, and then call a different Send method.")] - public void Send(Exception exception, IList<string> tags, string version) - { - Send(exception, tags, null, version); - } - - /// <summary> - /// This method is obsolete. Use the ApplicationVersion property to set a custom version string. - /// Then use a Send method that does not accept a version. - /// </summary> - [Obsolete("Set the ApplicationVersion property instead, and then call a different Send method.")] - public void Send(Exception exception, IList<string> tags, IDictionary userCustomData, string version) - { - var message = BuildMessage(exception, tags, userCustomData); - message.Details.Version = version; - Send(message); - } - - /// <summary> - /// This method is obsolete. Use the ApplicationVersion property to set a custom version string. - /// Then use a Send method that does not accept a version. - /// </summary> - [Obsolete("Set the ApplicationVersion property instead, and then call a different Send method.")] - public void SendInBackground(Exception exception, IList<string> tags, string version) - { - SendInBackground(exception, tags, null, version); - } - - /// <summary> - /// This method is obsolete. Use the ApplicationVersion property to set a custom version string. - /// Then use a Send method that does not accept a version. - /// </summary> - [Obsolete("Set the ApplicationVersion property instead, and then call a different Send method.")] - public void SendInBackground(Exception exception, IList<string> tags, IDictionary userCustomData, string version) - { - var message = BuildMessage(exception, tags, userCustomData); - message.Details.Version = version; - SendInBackground(message); - } } } diff --git a/Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs b/Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs index 903d0ff3..12acfff4 100644 --- a/Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs +++ b/Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs @@ -426,49 +426,5 @@ private void SaveMessage(string message) System.Diagnostics.Debug.WriteLine(string.Format("Error saving message to isolated storage {0}", ex.Message)); } } - - /// <summary> - /// This method is obsolete. Use the ApplicationVersion property to set a custom version string. - /// Then use a Send method that does not accept a version. - /// </summary> - [Obsolete("Set the ApplicationVersion property instead, and then call a different Send method.")] - public void Send(Exception exception, IList<string> tags, string version) - { - Send(exception, tags, null, version); - } - - /// <summary> - /// This method is obsolete. Use the ApplicationVersion property to set a custom version string. - /// Then use a Send method that does not accept a version. - /// </summary> - [Obsolete("Set the ApplicationVersion property instead, and then call a different Send method.")] - public void Send(Exception exception, IList<string> tags, IDictionary userCustomData, string version) - { - var message = BuildMessage(exception, tags, userCustomData); - message.Details.Version = version; - Send(message); - } - - /// <summary> - /// This method is obsolete. Use the ApplicationVersion property to set a custom version string. - /// Then use a Send method that does not accept a version. - /// </summary> - [Obsolete("Set the ApplicationVersion property instead, and then call a different Send method.")] - public void SendInBackground(Exception exception, IList<string> tags, string version) - { - SendInBackground(exception, tags, null, version); - } - - /// <summary> - /// This method is obsolete. Use the ApplicationVersion property to set a custom version string. - /// Then use a Send method that does not accept a version. - /// </summary> - [Obsolete("Set the ApplicationVersion property instead, and then call a different Send method.")] - public void SendInBackground(Exception exception, IList<string> tags, IDictionary userCustomData, string version) - { - var message = BuildMessage(exception, tags, userCustomData); - message.Details.Version = version; - SendInBackground(message); - } } } diff --git a/Mindscape.Raygun4Net/RaygunClient.cs b/Mindscape.Raygun4Net/RaygunClient.cs index 8a765b38..68d512de 100644 --- a/Mindscape.Raygun4Net/RaygunClient.cs +++ b/Mindscape.Raygun4Net/RaygunClient.cs @@ -357,49 +357,5 @@ public void Send(RaygunMessage raygunMessage) } } } - - /// <summary> - /// This method is obsolete. Use the ApplicationVersion property to set a custom version string. - /// Then use a Send method that does not accept a version. - /// </summary> - [Obsolete("Set the ApplicationVersion property instead, and then call a different Send method.")] - public void Send(Exception exception, IList<string> tags, string version) - { - Send(exception, tags, null, version); - } - - /// <summary> - /// This method is obsolete. Use the ApplicationVersion property to set a custom version string. - /// Then use a Send method that does not accept a version. - /// </summary> - [Obsolete("Set the ApplicationVersion property instead, and then call a different Send method.")] - public void Send(Exception exception, IList<string> tags, IDictionary userCustomData, string version) - { - var message = BuildMessage(exception, tags, userCustomData); - message.Details.Version = version; - Send(message); - } - - /// <summary> - /// This method is obsolete. Use the ApplicationVersion property to set a custom version string. - /// Then use a Send method that does not accept a version. - /// </summary> - [Obsolete("Set the ApplicationVersion property instead, and then call a different Send method.")] - public void SendInBackground(Exception exception, IList<string> tags, string version) - { - SendInBackground(exception, tags, null, version); - } - - /// <summary> - /// This method is obsolete. Use the ApplicationVersion property to set a custom version string. - /// Then use a Send method that does not accept a version. - /// </summary> - [Obsolete("Set the ApplicationVersion property instead, and then call a different Send method.")] - public void SendInBackground(Exception exception, IList<string> tags, IDictionary userCustomData, string version) - { - var message = BuildMessage(exception, tags, userCustomData); - message.Details.Version = version; - SendInBackground(message); - } } } From de4a510240b95ab32355cdb51093cca24c44fe6c Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Fri, 20 Jun 2014 15:21:00 +1200 Subject: [PATCH 08/28] Obsolete methods for version 3. --- Mindscape.Raygun4Net/RaygunClient.cs | 13 +++++++++++++ Mindscape.Raygun4Net/RaygunMessageBuilder.cs | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Mindscape.Raygun4Net/RaygunClient.cs b/Mindscape.Raygun4Net/RaygunClient.cs index 68d512de..71340f56 100644 --- a/Mindscape.Raygun4Net/RaygunClient.cs +++ b/Mindscape.Raygun4Net/RaygunClient.cs @@ -126,6 +126,19 @@ public void AddWrapperExceptions(IEnumerable<Type> wrapperExceptions) } } + /// <summary> + /// This method is obsolete. Use the multi parameter method instead. + /// </summary> + /// <param name="names">A list of form names to ignore.</param> + [Obsolete("Use multi parameter method instead")] + public void IgnoreFormDataNames(IEnumerable<string> names) + { + foreach (string name in names) + { + _requestMessageOptions.IgnoreFormDataNames.Add(name); + } + } + /// <summary> /// Adds a list of keys to ignore when attaching the Form data of an HTTP POST request. This allows /// you to remove sensitive data from the transmitted copy of the Form on the HttpRequest by specifying the keys you want removed. diff --git a/Mindscape.Raygun4Net/RaygunMessageBuilder.cs b/Mindscape.Raygun4Net/RaygunMessageBuilder.cs index 04b9b582..b677406a 100644 --- a/Mindscape.Raygun4Net/RaygunMessageBuilder.cs +++ b/Mindscape.Raygun4Net/RaygunMessageBuilder.cs @@ -119,6 +119,19 @@ public IRaygunMessageBuilder SetUser(string user) return this; } + /// <summary> + /// This method is obsolete. Use SetHttpDetails(HttpContext, RaygunRequestMessageOptions) so that you can specify seperate ignore lists + /// for form data, headers, cookies and server variables. + /// </summary> + /// <param name="context">The HttpContext</param> + /// <param name="ignoredNames">A list of form data, headers, cookies and server variables to ignore.</param> + /// <returns>The message builder.</returns> + [Obsolete("ignoredFormNames has now been split into 4 separate options. Use SetHttpDetails(HttpContext, RaygunRequestMessageOptions)")] + public IRaygunMessageBuilder SetHttpDetails(HttpContext context, List<string> ignoredNames = null) + { + return SetHttpDetails(context, new RaygunRequestMessageOptions(ignoredNames, ignoredNames, ignoredNames, ignoredNames)); + } + public IRaygunMessageBuilder SetHttpDetails(HttpContext context, RaygunRequestMessageOptions options = null) { if (context != null) From 60c692c25285e490c472a813b285a0aac67e0414 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Mon, 23 Jun 2014 13:42:33 +1200 Subject: [PATCH 09/28] Support regular expressions to ignore form data, headers and server variables. --- .../RaygunRequestMessageTests.cs | 53 +++++++++++++++++++ .../Messages/RaygunRequestMessage.cs | 39 +++++++++++++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs index 3f5df726..d6bb0e7b 100644 --- a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs +++ b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs @@ -130,6 +130,59 @@ public void IgnoreAllFormData() Assert.AreEqual(0, message.Form.Count); } + [Test] + public void HandleInvalidRegex() + { + var request = CreateWritableRequest(); + + request.Form.Add("+", "FormDataValue"); // Not a valid form name, but useful for this test. + Assert.AreEqual(1, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "+" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); + RaygunRequestMessage message = null; + // Make sure the invalid regex "+" does not cause an exception: + Assert.DoesNotThrow(() => + { + message = new RaygunRequestMessage(request, options); + }); + + Assert.AreEqual(0, message.Form.Count); + } + + [Test] + public void UseRegex() + { + var request = CreateWritableRequest(); + + request.Form.Add("TestFormData1", "FormDataValue"); + request.Form.Add("TestFormData2", "FormDataValue"); + request.Form.Add("TestFormData3", "FormDataValue"); + Assert.AreEqual(3, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "TestFormData[1-2]" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Form.Count); + Assert.IsTrue(message.Form.Contains("TestFormData3")); + } + + [Test] + public void UseCaseInsensitiveRegex() + { + var request = CreateWritableRequest(); + + request.Form.Add("TestFormData1", "FormDataValue"); + request.Form.Add("TestFormData2", "FormDataValue"); + request.Form.Add("AnotherFormData", "FormDataValue"); + Assert.AreEqual(3, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "(?i)testformdata" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Form.Count); + Assert.IsTrue(message.Form.Contains("AnotherFormData")); + } + private HttpRequest CreateWritableRequest() { var request = new HttpRequest("test", "http://google.com", "test=test"); diff --git a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs index 473a36a3..b9c4cb0b 100644 --- a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs @@ -4,6 +4,7 @@ using System.Collections.Specialized; using System.IO; using System.Linq; +using System.Text.RegularExpressions; using System.Web; namespace Mindscape.Raygun4Net.Messages @@ -88,7 +89,7 @@ private static IDictionary ToDictionary(NameValueCollection nameValueCollection, try { - keys = nameValueCollection.AllKeys.Where(k => k != null).Except(ignoreFields); + keys = Filter(nameValueCollection, ignoreFields); } catch (HttpRequestValidationException) { @@ -139,6 +140,42 @@ private static IDictionary ToDictionary(NameValueCollection nameValueCollection, return dictionary; } + private static IEnumerable<string> Filter(NameValueCollection nameValueCollection, IEnumerable<string> ignoreFields) + { + List<string> pureIgnores = new List<string>(); + List<Regex> regexs = new List<Regex>(); + foreach (string ignore in ignoreFields) + { + try + { + Regex regex = new Regex(ignore); + regexs.Add(regex); + } + catch + { + pureIgnores.Add(ignore); + } + } + + foreach (string key in nameValueCollection.AllKeys.Where(k => k != null).Except(pureIgnores)) + { + bool send = true; + foreach (Regex regex in regexs) + { + Match match = regex.Match(key); + if (match != null && match.Success) + { + send = false; + break; + } + } + if (send) + { + yield return key; + } + } + } + public class Cookie { public Cookie(string name, string value) From c76389fd21f5c088a48d6a6a15dcc06bc88a1463 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Mon, 23 Jun 2014 14:06:57 +1200 Subject: [PATCH 10/28] Support regular expressions to ignore cookies. --- .../RaygunRequestMessageTests.cs | 56 ++++++++++++++++++- .../Messages/RaygunRequestMessage.cs | 43 +++++++++++--- 2 files changed, 88 insertions(+), 11 deletions(-) diff --git a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs index d6bb0e7b..4e4b9d8f 100644 --- a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs +++ b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs @@ -131,7 +131,7 @@ public void IgnoreAllFormData() } [Test] - public void HandleInvalidRegex() + public void HandleInvalidFormRegex() { var request = CreateWritableRequest(); @@ -150,7 +150,7 @@ public void HandleInvalidRegex() } [Test] - public void UseRegex() + public void UseFormRegex() { var request = CreateWritableRequest(); @@ -167,7 +167,7 @@ public void UseRegex() } [Test] - public void UseCaseInsensitiveRegex() + public void UseCaseInsensitiveFormRegex() { var request = CreateWritableRequest(); @@ -289,6 +289,56 @@ public void IgnoreAllCookies() Assert.AreEqual(0, message.Cookies.Count); } + [Test] + public void HandleInvalidCookieRegex() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("+", "CookieValue")); + Assert.AreEqual(1, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(Enumerable.Empty<string>(), Enumerable.Empty<string>(), new string[] { "+" }, Enumerable.Empty<string>()); + RaygunRequestMessage message = null; + // Make sure the invalid regex "+" does not cause an exception: + Assert.DoesNotThrow(() => + { + message = new RaygunRequestMessage(request, options); + }); + + Assert.AreEqual(0, message.Cookies.Count); + } + + [Test] + public void UseCookieRegex() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie3", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(Enumerable.Empty<string>(), Enumerable.Empty<string>(), new string[] { "TestCookie[1-2]" }, Enumerable.Empty<string>()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookie3")); + } + + [Test] + public void UseCaseInsensitiveCookieRegex() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + request.Cookies.Add(new HttpCookie("AnotherCookie", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(Enumerable.Empty<string>(), Enumerable.Empty<string>(), new string[] { "(?i)testcookie" }, Enumerable.Empty<string>()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "AnotherCookie")); + } + private int CookieCount(RaygunRequestMessage message, string name) { int count = 0; diff --git a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs index b9c4cb0b..53d7d286 100644 --- a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs @@ -60,22 +60,49 @@ public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions opt } } - private IList GetCookies(HttpCookieCollection cookieCollection, IEnumerable<string> ignoredFormNames) + private IList GetCookies(HttpCookieCollection cookieCollection, IEnumerable<string> ignoredCookies) { - var ignored = ignoredFormNames.ToLookup(s => s); - - if (ignored.Count == 1 && ignored.Contains("*")) + if (ignoredCookies.Count() == 1 && ignoredCookies.Contains("*")) { return Enumerable.Empty<Cookie>().ToList(); } + HashSet<string> pureIgnores = new HashSet<string>(); + List<Regex> expressions = new List<Regex>(); + foreach (string ignore in ignoredCookies) + { + try + { + Regex regex = new Regex(ignore); + expressions.Add(regex); + } + catch + { + pureIgnores.Add(ignore); + } + } + return Enumerable.Range(0, cookieCollection.Count) .Select(i => cookieCollection[i]) - .Where(c => !ignored.Contains(c.Name)) + .Where(c => !pureIgnores.Contains(c.Name)) + .Where(c => !IgnoreCookie(c, expressions)) .Select(c => new Cookie(c.Name, c.Value)) .ToList(); } + private bool IgnoreCookie(HttpCookie cookie, List<Regex> expressions) + { + foreach (Regex regex in expressions) + { + Match match = regex.Match(cookie.Name); + if (match != null && match.Success) + { + return true; + } + } + return false; + } + private static IDictionary ToDictionary(NameValueCollection nameValueCollection, IEnumerable<string> ignoreFields, bool truncateValues = false) { var dictionary = new Dictionary<string, string>(); @@ -143,13 +170,13 @@ private static IDictionary ToDictionary(NameValueCollection nameValueCollection, private static IEnumerable<string> Filter(NameValueCollection nameValueCollection, IEnumerable<string> ignoreFields) { List<string> pureIgnores = new List<string>(); - List<Regex> regexs = new List<Regex>(); + List<Regex> expressions = new List<Regex>(); foreach (string ignore in ignoreFields) { try { Regex regex = new Regex(ignore); - regexs.Add(regex); + expressions.Add(regex); } catch { @@ -160,7 +187,7 @@ private static IEnumerable<string> Filter(NameValueCollection nameValueCollectio foreach (string key in nameValueCollection.AllKeys.Where(k => k != null).Except(pureIgnores)) { bool send = true; - foreach (Regex regex in regexs) + foreach (Regex regex in expressions) { Match match = regex.Match(key); if (match != null && match.Success) From 0eef09b3abfcec961b3b1a60447095e5c5ce5e80 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Mon, 23 Jun 2014 14:36:17 +1200 Subject: [PATCH 11/28] Removed pointless obsolete members. --- .../Messages/RaygunRequestMessage.cs | 7 ------- Mindscape.Raygun4Net/RaygunClient.cs | 13 ------------- Mindscape.Raygun4Net/RaygunMessageBuilder.cs | 13 ------------- 3 files changed, 33 deletions(-) diff --git a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs index 53d7d286..3dc0a1c3 100644 --- a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs @@ -11,13 +11,6 @@ namespace Mindscape.Raygun4Net.Messages { public class RaygunRequestMessage { - // TODO: making this obsolete doesn't help much because if the second parameter is null, there will be an ambiguous call. - [Obsolete("ignoredFormNames has now been split into 4 separate options. Use RaygunRequestMessage(HttpRequest, RaygunRequestMessageOptions)")] - public RaygunRequestMessage(HttpRequest request, List<string> ignoredFormNames) - : this(request, new RaygunRequestMessageOptions(ignoredFormNames, ignoredFormNames, ignoredFormNames, ignoredFormNames)) - { - } - public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions options) { options = options ?? new RaygunRequestMessageOptions(); diff --git a/Mindscape.Raygun4Net/RaygunClient.cs b/Mindscape.Raygun4Net/RaygunClient.cs index 71340f56..68d512de 100644 --- a/Mindscape.Raygun4Net/RaygunClient.cs +++ b/Mindscape.Raygun4Net/RaygunClient.cs @@ -126,19 +126,6 @@ public void AddWrapperExceptions(IEnumerable<Type> wrapperExceptions) } } - /// <summary> - /// This method is obsolete. Use the multi parameter method instead. - /// </summary> - /// <param name="names">A list of form names to ignore.</param> - [Obsolete("Use multi parameter method instead")] - public void IgnoreFormDataNames(IEnumerable<string> names) - { - foreach (string name in names) - { - _requestMessageOptions.IgnoreFormDataNames.Add(name); - } - } - /// <summary> /// Adds a list of keys to ignore when attaching the Form data of an HTTP POST request. This allows /// you to remove sensitive data from the transmitted copy of the Form on the HttpRequest by specifying the keys you want removed. diff --git a/Mindscape.Raygun4Net/RaygunMessageBuilder.cs b/Mindscape.Raygun4Net/RaygunMessageBuilder.cs index b677406a..04b9b582 100644 --- a/Mindscape.Raygun4Net/RaygunMessageBuilder.cs +++ b/Mindscape.Raygun4Net/RaygunMessageBuilder.cs @@ -119,19 +119,6 @@ public IRaygunMessageBuilder SetUser(string user) return this; } - /// <summary> - /// This method is obsolete. Use SetHttpDetails(HttpContext, RaygunRequestMessageOptions) so that you can specify seperate ignore lists - /// for form data, headers, cookies and server variables. - /// </summary> - /// <param name="context">The HttpContext</param> - /// <param name="ignoredNames">A list of form data, headers, cookies and server variables to ignore.</param> - /// <returns>The message builder.</returns> - [Obsolete("ignoredFormNames has now been split into 4 separate options. Use SetHttpDetails(HttpContext, RaygunRequestMessageOptions)")] - public IRaygunMessageBuilder SetHttpDetails(HttpContext context, List<string> ignoredNames = null) - { - return SetHttpDetails(context, new RaygunRequestMessageOptions(ignoredNames, ignoredNames, ignoredNames, ignoredNames)); - } - public IRaygunMessageBuilder SetHttpDetails(HttpContext context, RaygunRequestMessageOptions options = null) { if (context != null) From 8c449241c8ab2a619b8a3fe91cc5f2fc4cfe7c48 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Mon, 23 Jun 2014 14:54:35 +1200 Subject: [PATCH 12/28] Renamed FormData to FormField --- .../RaygunRequestMessageTests.cs | 76 +++++++++---------- .../RaygunSettingsTests.cs | 4 +- .../Messages/RaygunRequestMessage.cs | 2 +- Mindscape.Raygun4Net/RaygunClient.cs | 10 +-- .../RaygunRequestMessageOptions.cs | 8 +- Mindscape.Raygun4Net/RaygunSettings.cs | 8 +- 6 files changed, 54 insertions(+), 54 deletions(-) diff --git a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs index 4e4b9d8f..27abef21 100644 --- a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs +++ b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs @@ -62,66 +62,66 @@ public void QueryStringTest() // Form data [Test] - public void FormData() + public void FormFields() { var request = CreateWritableRequest(); - request.Form.Add("TestFormData1", "FormDataValue"); - request.Form.Add("TestFormData2", "FormDataValue"); - request.Form.Add("TestFormData3", "FormDataValue"); + request.Form.Add("TestFormField1", "FormFieldValue"); + request.Form.Add("TestFormField2", "FormFieldValue"); + request.Form.Add("TestFormField3", "FormFieldValue"); Assert.AreEqual(3, request.Form.Count); var message = new RaygunRequestMessage(request, new RaygunRequestMessageOptions()); Assert.AreEqual(3, message.Form.Count); - Assert.IsTrue(message.Form.Contains("TestFormData1")); - Assert.IsTrue(message.Form.Contains("TestFormData2")); - Assert.IsTrue(message.Form.Contains("TestFormData3")); + Assert.IsTrue(message.Form.Contains("TestFormField1")); + Assert.IsTrue(message.Form.Contains("TestFormField2")); + Assert.IsTrue(message.Form.Contains("TestFormField3")); } [Test] - public void IgnoreFormData() + public void IgnoreFormFields() { var request = CreateWritableRequest(); - request.Form.Add("TestFormData1", "FormDataValue"); - request.Form.Add("TestFormData2", "FormDataValue"); - request.Form.Add("TestFormData3", "FormDataValue"); + request.Form.Add("TestFormField1", "FormFieldValue"); + request.Form.Add("TestFormField2", "FormFieldValue"); + request.Form.Add("TestFormField3", "FormFieldValue"); Assert.AreEqual(3, request.Form.Count); - var options = new RaygunRequestMessageOptions(new string[] { "TestFormData2" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); + var options = new RaygunRequestMessageOptions(new string[] { "TestFormField2" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); var message = new RaygunRequestMessage(request, options); Assert.AreEqual(2, message.Form.Count); - Assert.IsTrue(message.Form.Contains("TestFormData1")); - Assert.IsTrue(message.Form.Contains("TestFormData3")); + Assert.IsTrue(message.Form.Contains("TestFormField1")); + Assert.IsTrue(message.Form.Contains("TestFormField3")); } [Test] - public void IgnoreMultipleFormData() + public void IgnoreMultipleFormFields() { var request = CreateWritableRequest(); - request.Form.Add("TestFormData1", "FormDataValue"); - request.Form.Add("TestFormData2", "FormDataValue"); - request.Form.Add("TestFormData3", "FormDataValue"); + request.Form.Add("TestFormField1", "FormFieldValue"); + request.Form.Add("TestFormField2", "FormFieldValue"); + request.Form.Add("TestFormField3", "FormFieldValue"); Assert.AreEqual(3, request.Form.Count); - var options = new RaygunRequestMessageOptions(new string[] { "TestFormData1", "TestFormData3" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); + var options = new RaygunRequestMessageOptions(new string[] { "TestFormField1", "TestFormField3" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); var message = new RaygunRequestMessage(request, options); Assert.AreEqual(1, message.Form.Count); - Assert.IsTrue(message.Form.Contains("TestFormData2")); + Assert.IsTrue(message.Form.Contains("TestFormField2")); } [Test] - public void IgnoreAllFormData() + public void IgnoreAllFormFields() { var request = CreateWritableRequest(); - request.Form.Add("TestFormData1", "FormDataValue"); - request.Form.Add("TestFormData2", "FormDataValue"); - request.Form.Add("TestFormData3", "FormDataValue"); + request.Form.Add("TestFormField1", "FormFieldValue"); + request.Form.Add("TestFormField2", "FormFieldValue"); + request.Form.Add("TestFormField3", "FormFieldValue"); Assert.AreEqual(3, request.Form.Count); var options = new RaygunRequestMessageOptions(new string[] { "*" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); @@ -131,11 +131,11 @@ public void IgnoreAllFormData() } [Test] - public void HandleInvalidFormRegex() + public void HandleInvalidFormFieldRegex() { var request = CreateWritableRequest(); - request.Form.Add("+", "FormDataValue"); // Not a valid form name, but useful for this test. + request.Form.Add("+", "FormFieldValue"); // Not a valid form name, but useful for this test. Assert.AreEqual(1, request.Form.Count); var options = new RaygunRequestMessageOptions(new string[] { "+" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); @@ -150,37 +150,37 @@ public void HandleInvalidFormRegex() } [Test] - public void UseFormRegex() + public void UseFormFieldRegex() { var request = CreateWritableRequest(); - request.Form.Add("TestFormData1", "FormDataValue"); - request.Form.Add("TestFormData2", "FormDataValue"); - request.Form.Add("TestFormData3", "FormDataValue"); + request.Form.Add("TestFormField1", "FormFieldValue"); + request.Form.Add("TestFormField2", "FormFieldValue"); + request.Form.Add("TestFormField3", "FormFieldValue"); Assert.AreEqual(3, request.Form.Count); - var options = new RaygunRequestMessageOptions(new string[] { "TestFormData[1-2]" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); + var options = new RaygunRequestMessageOptions(new string[] { "TestFormField[1-2]" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); var message = new RaygunRequestMessage(request, options); Assert.AreEqual(1, message.Form.Count); - Assert.IsTrue(message.Form.Contains("TestFormData3")); + Assert.IsTrue(message.Form.Contains("TestFormField3")); } [Test] - public void UseCaseInsensitiveFormRegex() + public void UseCaseInsensitiveFormFieldRegex() { var request = CreateWritableRequest(); - request.Form.Add("TestFormData1", "FormDataValue"); - request.Form.Add("TestFormData2", "FormDataValue"); - request.Form.Add("AnotherFormData", "FormDataValue"); + request.Form.Add("TestFormField1", "FormFieldValue"); + request.Form.Add("TestFormField2", "FormFieldValue"); + request.Form.Add("AnotherFormField", "FormFieldValue"); Assert.AreEqual(3, request.Form.Count); - var options = new RaygunRequestMessageOptions(new string[] { "(?i)testformdata" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); + var options = new RaygunRequestMessageOptions(new string[] { "(?i)testformfield" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); var message = new RaygunRequestMessage(request, options); Assert.AreEqual(1, message.Form.Count); - Assert.IsTrue(message.Form.Contains("AnotherFormData")); + Assert.IsTrue(message.Form.Contains("AnotherFormField")); } private HttpRequest CreateWritableRequest() diff --git a/Mindscape.Raygun4Net.Tests/RaygunSettingsTests.cs b/Mindscape.Raygun4Net.Tests/RaygunSettingsTests.cs index eb0079a6..c145ccf2 100644 --- a/Mindscape.Raygun4Net.Tests/RaygunSettingsTests.cs +++ b/Mindscape.Raygun4Net.Tests/RaygunSettingsTests.cs @@ -46,9 +46,9 @@ public void ExcludeErrorsFromLocal_FalseByDefault() } [Test] - public void IgnoreFormDataNames_EmptyByDefault() + public void IgnoreFormFieldNames_EmptyByDefault() { - Assert.IsEmpty(RaygunSettings.Settings.IgnoreFormDataNames); + Assert.IsEmpty(RaygunSettings.Settings.IgnoreFormFieldNames); } [Test] diff --git a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs index 3dc0a1c3..6aacf7a7 100644 --- a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs @@ -24,7 +24,7 @@ public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions opt Headers = ToDictionary(request.Headers, options.IgnoreHeaderNames); Headers.Remove("Cookie"); - Form = ToDictionary(request.Form, options.IgnoreFormDataNames, true); + Form = ToDictionary(request.Form, options.IgnoreFormFieldNames, true); Cookies = GetCookies(request.Cookies, options.IgnoreCookieNames); // Remove ignored and duplicated variables diff --git a/Mindscape.Raygun4Net/RaygunClient.cs b/Mindscape.Raygun4Net/RaygunClient.cs index 68d512de..620fd117 100644 --- a/Mindscape.Raygun4Net/RaygunClient.cs +++ b/Mindscape.Raygun4Net/RaygunClient.cs @@ -40,10 +40,10 @@ public RaygunClient(string apiKey) public RaygunClient() : this(RaygunSettings.Settings.ApiKey) { - if (!string.IsNullOrEmpty(RaygunSettings.Settings.IgnoreFormDataNames)) + if (!string.IsNullOrEmpty(RaygunSettings.Settings.IgnoreFormFieldNames)) { - var ignoredNames = RaygunSettings.Settings.IgnoreFormDataNames.Split(','); - IgnoreFormDataNames(ignoredNames); + var ignoredNames = RaygunSettings.Settings.IgnoreFormFieldNames.Split(','); + IgnoreFormFieldNames(ignoredNames); } if (!string.IsNullOrEmpty(RaygunSettings.Settings.IgnoreHeaderNames)) { @@ -132,11 +132,11 @@ public void AddWrapperExceptions(IEnumerable<Type> wrapperExceptions) /// This method is only effective in a web context. /// </summary> /// <param name="names">Keys to be stripped from the copy of the Form NameValueCollection when sending to Raygun.</param> - public void IgnoreFormDataNames(params string[] names) + public void IgnoreFormFieldNames(params string[] names) { foreach (string name in names) { - _requestMessageOptions.IgnoreFormDataNames.Add(name); + _requestMessageOptions.IgnoreFormFieldNames.Add(name); } } diff --git a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs index d0e9b604..1caeab86 100644 --- a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs +++ b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs @@ -7,22 +7,22 @@ namespace Mindscape.Raygun4Net { public class RaygunRequestMessageOptions { - private readonly List<string> _ignoredFormNames = new List<string>(); + private readonly List<string> _ignoredFormFieldNames = new List<string>(); private readonly List<string> _ignoreHeaderNames = new List<string>(); private readonly List<string> _ignoreCookieNames = new List<string>(); private readonly List<string> _ignoreServerVariableNames = new List<string>(); public RaygunRequestMessageOptions() { } - public RaygunRequestMessageOptions(IEnumerable<string> formNames, IEnumerable<string> headerNames, IEnumerable<string> cookieNames, IEnumerable<string> serverVariableNames) + public RaygunRequestMessageOptions(IEnumerable<string> formFieldNames, IEnumerable<string> headerNames, IEnumerable<string> cookieNames, IEnumerable<string> serverVariableNames) { - _ignoredFormNames.AddRange(formNames); + _ignoredFormFieldNames.AddRange(formFieldNames); _ignoreHeaderNames.AddRange(headerNames); _ignoreCookieNames.AddRange(cookieNames); _ignoreServerVariableNames.AddRange(serverVariableNames); } - public List<string> IgnoreFormDataNames { get { return _ignoredFormNames; } } + public List<string> IgnoreFormFieldNames { get { return _ignoredFormFieldNames; } } public List<string> IgnoreHeaderNames { get { return _ignoreHeaderNames; } } diff --git a/Mindscape.Raygun4Net/RaygunSettings.cs b/Mindscape.Raygun4Net/RaygunSettings.cs index 230bbdd0..d6e3796a 100644 --- a/Mindscape.Raygun4Net/RaygunSettings.cs +++ b/Mindscape.Raygun4Net/RaygunSettings.cs @@ -58,11 +58,11 @@ public bool ExcludeErrorsFromLocal set { this["excludeErrorsFromLocal"] = value; } } - [ConfigurationProperty("ignoreFormDataNames", IsRequired = false, DefaultValue = "")] - public string IgnoreFormDataNames + [ConfigurationProperty("ignoreFormFieldNames", IsRequired = false, DefaultValue = "")] + public string IgnoreFormFieldNames { - get { return (string)this["ignoreFormDataNames"]; } - set { this["ignoreFormDataNames"] = value; } + get { return (string)this["ignoreFormFieldNames"]; } + set { this["ignoreFormFieldNames"] = value; } } [ConfigurationProperty("ignoreHeaderNames", IsRequired = false, DefaultValue = "")] From 728a6aed160f4b37f30ec683e7f2b7482ed42921 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Mon, 23 Jun 2014 14:58:17 +1200 Subject: [PATCH 13/28] Load the ignored lists in the non-default constructor of RaygunClient. --- Mindscape.Raygun4Net/RaygunClient.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Mindscape.Raygun4Net/RaygunClient.cs b/Mindscape.Raygun4Net/RaygunClient.cs index 620fd117..e1d2b176 100644 --- a/Mindscape.Raygun4Net/RaygunClient.cs +++ b/Mindscape.Raygun4Net/RaygunClient.cs @@ -31,15 +31,7 @@ public RaygunClient(string apiKey) _wrapperExceptions.Add(typeof(TargetInvocationException)); _wrapperExceptions.Add(typeof(HttpUnhandledException)); - } - /// <summary> - /// Initializes a new instance of the <see cref="RaygunClient" /> class. - /// Uses the ApiKey specified in the config file. - /// </summary> - public RaygunClient() - : this(RaygunSettings.Settings.ApiKey) - { if (!string.IsNullOrEmpty(RaygunSettings.Settings.IgnoreFormFieldNames)) { var ignoredNames = RaygunSettings.Settings.IgnoreFormFieldNames.Split(','); @@ -62,6 +54,15 @@ public RaygunClient() } } + /// <summary> + /// Initializes a new instance of the <see cref="RaygunClient" /> class. + /// Uses the ApiKey specified in the config file. + /// </summary> + public RaygunClient() + : this(RaygunSettings.Settings.ApiKey) + { + } + protected bool ValidateApiKey() { if (string.IsNullOrEmpty(_apiKey)) From 5f847defc123631f226d8191b3eeccf6b69f8443 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Mon, 23 Jun 2014 16:25:42 +1200 Subject: [PATCH 14/28] Ported improvements to Raygun for .Net 2.0 --- .../RaygunRequestMessageTests.cs | 10 +- .../Messages/RaygunRequestMessage.cs | 12 +- .../RaygunRequestMessageOptions.cs | 1 - .../RaygunRequestMessageTests.cs | 304 +++++++++++++++++- .../RaygunSettingsTests.cs | 22 +- .../Messages/RaygunRequestMessage.cs | 132 ++++++-- .../Mindscape.Raygun4Net2.csproj | 3 + Mindscape.Raygun4Net2/RaygunClient.cs | 77 ++++- Mindscape.Raygun4Net2/RaygunMessageBuilder.cs | 4 +- Mindscape.Raygun4Net2/RaygunSettings.cs | 29 +- 10 files changed, 533 insertions(+), 61 deletions(-) diff --git a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs index 27abef21..46e60bd8 100644 --- a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs +++ b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs @@ -28,7 +28,7 @@ public void SetUp() [Test] public void HostNameTest() { - var message = new RaygunRequestMessage(_defaultRequest, new RaygunRequestMessageOptions()); + var message = new RaygunRequestMessage(_defaultRequest, null); Assert.That(message.HostName, Is.EqualTo("google.com")); } @@ -36,7 +36,7 @@ public void HostNameTest() [Test] public void UrlTest() { - var message = new RaygunRequestMessage(_defaultRequest, new RaygunRequestMessageOptions()); + var message = new RaygunRequestMessage(_defaultRequest, null); Assert.That(message.Url, Is.EqualTo("/")); } @@ -44,7 +44,7 @@ public void UrlTest() [Test] public void HttpMethodTest() { - var message = new RaygunRequestMessage(_defaultRequest, new RaygunRequestMessageOptions()); + var message = new RaygunRequestMessage(_defaultRequest, null); Assert.That(message.HttpMethod, Is.EqualTo("GET")); } @@ -54,12 +54,12 @@ public void QueryStringTest() { var request = new HttpRequest("test", "http://google.com", "test=test"); - var message = new RaygunRequestMessage(request, new RaygunRequestMessageOptions()); + var message = new RaygunRequestMessage(request, null); Assert.That(message.QueryString, Contains.Item(new KeyValuePair<string, string>("test", "test"))); } - // Form data + // Form fields [Test] public void FormFields() diff --git a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs index 6aacf7a7..17e93456 100644 --- a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs @@ -78,16 +78,16 @@ private IList GetCookies(HttpCookieCollection cookieCollection, IEnumerable<stri return Enumerable.Range(0, cookieCollection.Count) .Select(i => cookieCollection[i]) .Where(c => !pureIgnores.Contains(c.Name)) - .Where(c => !IgnoreCookie(c, expressions)) + .Where(c => !IgnoreCookie(c.Name, expressions)) .Select(c => new Cookie(c.Name, c.Value)) .ToList(); } - private bool IgnoreCookie(HttpCookie cookie, List<Regex> expressions) + private bool IgnoreCookie(string name, List<Regex> expressions) { foreach (Regex regex in expressions) { - Match match = regex.Match(cookie.Name); + Match match = regex.Match(name); if (match != null && match.Success) { return true; @@ -96,11 +96,11 @@ private bool IgnoreCookie(HttpCookie cookie, List<Regex> expressions) return false; } - private static IDictionary ToDictionary(NameValueCollection nameValueCollection, IEnumerable<string> ignoreFields, bool truncateValues = false) + private static IDictionary ToDictionary(NameValueCollection nameValueCollection, IEnumerable<string> ignoreKeys, bool truncateValues = false) { var dictionary = new Dictionary<string, string>(); - if (ignoreFields.Count() == 1 && "*".Equals(ignoreFields.First())) + if (ignoreKeys.Count() == 1 && "*".Equals(ignoreKeys.First())) { return dictionary; } @@ -109,7 +109,7 @@ private static IDictionary ToDictionary(NameValueCollection nameValueCollection, try { - keys = Filter(nameValueCollection, ignoreFields); + keys = Filter(nameValueCollection, ignoreKeys); } catch (HttpRequestValidationException) { diff --git a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs index 1caeab86..cdf20db8 100644 --- a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs +++ b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Text; namespace Mindscape.Raygun4Net diff --git a/Mindscape.Raygun4Net2.Tests/RaygunRequestMessageTests.cs b/Mindscape.Raygun4Net2.Tests/RaygunRequestMessageTests.cs index d656e1b9..790d9e74 100644 --- a/Mindscape.Raygun4Net2.Tests/RaygunRequestMessageTests.cs +++ b/Mindscape.Raygun4Net2.Tests/RaygunRequestMessageTests.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; +using System.Reflection; using System.Text; using System.Web; +using Mindscape.Raygun4Net; using Mindscape.Raygun4Net.Messages; using NUnit.Framework; @@ -11,6 +13,7 @@ namespace Mindscape.Raygun4Net2.Tests public class RaygunRequestMessageTests { private HttpRequest _defaultRequest; + private List<string> _empty = new List<string>(); [SetUp] public void SetUp() @@ -21,7 +24,7 @@ public void SetUp() [Test] public void HostNameTest() { - var message = new RaygunRequestMessage(_defaultRequest, new List<string>()); + var message = new RaygunRequestMessage(_defaultRequest, null); Assert.That(message.HostName, Is.EqualTo("google.com")); } @@ -29,7 +32,7 @@ public void HostNameTest() [Test] public void UrlTest() { - var message = new RaygunRequestMessage(_defaultRequest, new List<string>()); + var message = new RaygunRequestMessage(_defaultRequest, null); Assert.That(message.Url, Is.EqualTo("/")); } @@ -37,7 +40,7 @@ public void UrlTest() [Test] public void HttpMethodTest() { - var message = new RaygunRequestMessage(_defaultRequest, new List<string>()); + var message = new RaygunRequestMessage(_defaultRequest, null); Assert.That(message.HttpMethod, Is.EqualTo("GET")); } @@ -47,9 +50,302 @@ public void QueryStringTest() { var request = new HttpRequest("test", "http://google.com", "test=test"); - var message = new RaygunRequestMessage(request, new List<string>()); + var message = new RaygunRequestMessage(request, null); Assert.That(message.QueryString, Contains.Item(new KeyValuePair<string, string>("test", "test"))); } + + // Form fields + + [Test] + public void FormFields() + { + var request = CreateWritableRequest(); + + request.Form.Add("TestFormField1", "FormFieldValue"); + request.Form.Add("TestFormField2", "FormFieldValue"); + request.Form.Add("TestFormField3", "FormFieldValue"); + Assert.AreEqual(3, request.Form.Count); + + var message = new RaygunRequestMessage(request, new RaygunRequestMessageOptions()); + + Assert.AreEqual(3, message.Form.Count); + Assert.IsTrue(message.Form.Contains("TestFormField1")); + Assert.IsTrue(message.Form.Contains("TestFormField2")); + Assert.IsTrue(message.Form.Contains("TestFormField3")); + } + + [Test] + public void IgnoreFormFields() + { + var request = CreateWritableRequest(); + + request.Form.Add("TestFormField1", "FormFieldValue"); + request.Form.Add("TestFormField2", "FormFieldValue"); + request.Form.Add("TestFormField3", "FormFieldValue"); + Assert.AreEqual(3, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "TestFormField2" }, _empty, _empty, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(2, message.Form.Count); + Assert.IsTrue(message.Form.Contains("TestFormField1")); + Assert.IsTrue(message.Form.Contains("TestFormField3")); + } + + [Test] + public void IgnoreMultipleFormFields() + { + var request = CreateWritableRequest(); + + request.Form.Add("TestFormField1", "FormFieldValue"); + request.Form.Add("TestFormField2", "FormFieldValue"); + request.Form.Add("TestFormField3", "FormFieldValue"); + Assert.AreEqual(3, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "TestFormField1", "TestFormField3" }, _empty, _empty, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Form.Count); + Assert.IsTrue(message.Form.Contains("TestFormField2")); + } + + [Test] + public void IgnoreAllFormFields() + { + var request = CreateWritableRequest(); + + request.Form.Add("TestFormField1", "FormFieldValue"); + request.Form.Add("TestFormField2", "FormFieldValue"); + request.Form.Add("TestFormField3", "FormFieldValue"); + Assert.AreEqual(3, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "*" }, _empty, _empty, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(0, message.Form.Count); + } + + [Test] + public void HandleInvalidFormFieldRegex() + { + var request = CreateWritableRequest(); + + request.Form.Add("+", "FormFieldValue"); // Not a valid form name, but useful for this test. + Assert.AreEqual(1, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "+" }, _empty, _empty, _empty); + RaygunRequestMessage message = null; + // Make sure the invalid regex "+" does not cause an exception: + Assert.DoesNotThrow(() => + { + message = new RaygunRequestMessage(request, options); + }); + + Assert.AreEqual(0, message.Form.Count); + } + + [Test] + public void UseFormFieldRegex() + { + var request = CreateWritableRequest(); + + request.Form.Add("TestFormField1", "FormFieldValue"); + request.Form.Add("TestFormField2", "FormFieldValue"); + request.Form.Add("TestFormField3", "FormFieldValue"); + Assert.AreEqual(3, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "TestFormField[1-2]" }, _empty, _empty, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Form.Count); + Assert.IsTrue(message.Form.Contains("TestFormField3")); + } + + [Test] + public void UseCaseInsensitiveFormFieldRegex() + { + var request = CreateWritableRequest(); + + request.Form.Add("TestFormField1", "FormFieldValue"); + request.Form.Add("TestFormField2", "FormFieldValue"); + request.Form.Add("AnotherFormField", "FormFieldValue"); + Assert.AreEqual(3, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "(?i)testformfield" }, _empty, _empty, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Form.Count); + Assert.IsTrue(message.Form.Contains("AnotherFormField")); + } + + private HttpRequest CreateWritableRequest() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + Type t = request.Form.GetType(); + PropertyInfo p = t.GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); + p.SetValue(request.Form, false, null); + return request; + } + + // Cookies + + [Test] + public void Cookies() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie3", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var message = new RaygunRequestMessage(request, new RaygunRequestMessageOptions()); + + Assert.AreEqual(3, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookie1")); + Assert.AreEqual(1, CookieCount(message, "TestCookie2")); + Assert.AreEqual(1, CookieCount(message, "TestCookie3")); + } + + [Test] + public void DuplicateCookies() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie", "CookieValue")); + Assert.AreEqual(2, request.Cookies.Count); + + var message = new RaygunRequestMessage(request, new RaygunRequestMessageOptions()); + + Assert.AreEqual(2, message.Cookies.Count); + Assert.AreEqual(2, CookieCount(message, "TestCookie")); + } + + [Test] + public void IgnoreCookie() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie3", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "TestCookie2" }, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(2, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookie1")); + Assert.AreEqual(1, CookieCount(message, "TestCookie3")); + } + + [Test] + public void IgnoreDuplicateCookie() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "TestCookie1" }, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookie2")); + } + + [Test] + public void IgnoreMultipleCookies() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie3", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "TestCookie1", "TestCookie3" }, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookie2")); + } + + [Test] + public void IgnoreAllCookies() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie3", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "*" }, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(0, message.Cookies.Count); + } + + [Test] + public void HandleInvalidCookieRegex() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("+", "CookieValue")); + Assert.AreEqual(1, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "+" }, _empty); + RaygunRequestMessage message = null; + // Make sure the invalid regex "+" does not cause an exception: + Assert.DoesNotThrow(() => + { + message = new RaygunRequestMessage(request, options); + }); + + Assert.AreEqual(0, message.Cookies.Count); + } + + [Test] + public void UseCookieRegex() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie3", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "TestCookie[1-2]" }, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookie3")); + } + + [Test] + public void UseCaseInsensitiveCookieRegex() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); + request.Cookies.Add(new HttpCookie("AnotherCookie", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "(?i)testcookie" }, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(1, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "AnotherCookie")); + } + + private int CookieCount(RaygunRequestMessage message, string name) + { + int count = 0; + foreach (Mindscape.Raygun4Net.Messages.RaygunRequestMessage.Cookie cookie in message.Cookies) + { + if (name.Equals(cookie.Name)) + { + count++; + } + } + return count; + } } } diff --git a/Mindscape.Raygun4Net2.Tests/RaygunSettingsTests.cs b/Mindscape.Raygun4Net2.Tests/RaygunSettingsTests.cs index 0b03a927..05785352 100644 --- a/Mindscape.Raygun4Net2.Tests/RaygunSettingsTests.cs +++ b/Mindscape.Raygun4Net2.Tests/RaygunSettingsTests.cs @@ -34,9 +34,27 @@ public void ExcludeErrorsFromLocal_FalseByDefault() } [Test] - public void IgnoreFormDataNames_EmptyByDefault() + public void IgnoreFormFieldNames_EmptyByDefault() { - Assert.IsEmpty(RaygunSettings.Settings.IgnoreFormDataNames); + Assert.IsEmpty(RaygunSettings.Settings.IgnoreFormFieldNames); + } + + [Test] + public void IgnoreHeaderNames_EmptyByDefault() + { + Assert.IsEmpty(RaygunSettings.Settings.IgnoreHeaderNames); + } + + [Test] + public void IgnoreCookieNames_EmptyByDefault() + { + Assert.IsEmpty(RaygunSettings.Settings.IgnoreCookieNames); + } + + [Test] + public void IgnoreServerVariableNames_EmptyByDefault() + { + Assert.IsEmpty(RaygunSettings.Settings.IgnoreServerVariableNames); } } } diff --git a/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs index a92c016e..6d9a8547 100644 --- a/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs @@ -4,14 +4,17 @@ using System.Collections.Specialized; using System.Diagnostics; using System.IO; +using System.Text.RegularExpressions; using System.Web; namespace Mindscape.Raygun4Net.Messages { public class RaygunRequestMessage { - public RaygunRequestMessage(HttpRequest request, List<string> ignoredFormNames) + public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions options) { + options = options ?? new RaygunRequestMessageOptions(); + HostName = request.Url.Host; Url = request.Url.AbsolutePath; HttpMethod = request.RequestType; @@ -19,14 +22,14 @@ public RaygunRequestMessage(HttpRequest request, List<string> ignoredFormNames) IEnumerable<string> empty = new List<string>(); QueryString = ToDictionary(request.QueryString, empty); - Headers = ToDictionary(request.Headers, ignoredFormNames ?? empty); + Headers = ToDictionary(request.Headers, options.IgnoreHeaderNames); Headers.Remove("Cookie"); - Form = ToDictionary(request.Form, ignoredFormNames ?? empty, true); - Cookies = GetCookies(request.Cookies, ignoredFormNames ?? empty); + Form = ToDictionary(request.Form, options.IgnoreFormFieldNames, true); + Cookies = GetCookies(request.Cookies, options.IgnoreCookieNames); // Remove ignored and duplicated variables - Data = ToDictionary(request.ServerVariables, ignoredFormNames ?? empty); + Data = ToDictionary(request.ServerVariables, options.IgnoreServerVariableNames); Data.Remove("ALL_HTTP"); Data.Remove("HTTP_COOKIE"); Data.Remove("ALL_RAW"); @@ -51,19 +54,33 @@ public RaygunRequestMessage(HttpRequest request, List<string> ignoredFormNames) } } - private IList GetCookies(HttpCookieCollection cookieCollection, IEnumerable<string> ignoredFormNames) + private IList GetCookies(HttpCookieCollection cookieCollection, IEnumerable<string> ignoredCookies) { - Dictionary<string, string> ignored = new Dictionary<string, string>(); - foreach(string key in ignoredFormNames) + IList cookies = new List<Cookie>(); + + if (IgnoreAll(ignoredCookies)) { - ignored[key] = key; + return cookies; } - IList cookies = new List<Cookie>(); + List<string> pureIgnores = new List<string>(); + List<Regex> expressions = new List<Regex>(); + foreach (string ignore in ignoredCookies) + { + try + { + Regex regex = new Regex(ignore); + expressions.Add(regex); + } + catch + { + pureIgnores.Add(ignore); + } + } foreach (string key in cookieCollection.Keys) { - if (!ignored.ContainsKey(key)) + if (!pureIgnores.Contains(key) && !IgnoreCookie(key, expressions)) { cookies.Add(new Cookie(cookieCollection[key].Name, cookieCollection[key].Value)); } @@ -72,33 +89,39 @@ private IList GetCookies(HttpCookieCollection cookieCollection, IEnumerable<stri return cookies; } - private static IDictionary ToDictionary(NameValueCollection nameValueCollection, IEnumerable<string> ignoreFields, bool truncateValues = false) + private bool IgnoreCookie(string name, List<Regex> expressions) + { + foreach (Regex regex in expressions) + { + Match match = regex.Match(name); + if (match != null && match.Success) + { + return true; + } + } + return false; + } + + private static IDictionary ToDictionary(NameValueCollection nameValueCollection, IEnumerable<string> ignoreKeys, bool truncateValues = false) { - Dictionary<string, string> ignored = new Dictionary<string, string>(); - foreach (string key in ignoreFields) + var dictionary = new Dictionary<string, string>(); + + if (IgnoreAll(ignoreKeys)) { - ignored[key] = key; + return dictionary; } - List<string> keys = new List<string>(); + IEnumerable<string> keys; try { - foreach (string key in nameValueCollection) - { - if (!ignored.ContainsKey(key)) - { - keys.Add(key); - } - } + keys = Filter(nameValueCollection, ignoreKeys); } catch (HttpRequestValidationException) { return new Dictionary<string, string> { { "Values", "Not able to be retrieved" } }; } - var dictionary = new Dictionary<string, string>(); - foreach (string key in keys) { try @@ -143,6 +166,65 @@ private static IDictionary ToDictionary(NameValueCollection nameValueCollection, return dictionary; } + private static bool IgnoreAll(IEnumerable<string> ignoreKeys) + { + bool ignoreAll = false; + int count = 0; + foreach (string ignore in ignoreKeys) + { + if ("*".Equals(ignore)) + { + ignoreAll = true; + } + count++; + if (count == 2) + { + ignoreAll = false; + break; + } + } + return ignoreAll; + } + + private static IEnumerable<string> Filter(NameValueCollection nameValueCollection, IEnumerable<string> ignoreFields) + { + List<string> pureIgnores = new List<string>(); + List<Regex> expressions = new List<Regex>(); + foreach (string ignore in ignoreFields) + { + try + { + Regex regex = new Regex(ignore); + expressions.Add(regex); + } + catch + { + pureIgnores.Add(ignore); + } + } + + foreach (string key in nameValueCollection) + { + if (key != null && !pureIgnores.Contains(key)) + { + bool send = true; + foreach (Regex regex in expressions) + { + Match match = regex.Match(key); + if (match != null && match.Success) + { + send = false; + break; + } + } + if (send) + { + yield return key; + } + } + } + } + public class Cookie { public Cookie(string name, string value) diff --git a/Mindscape.Raygun4Net2/Mindscape.Raygun4Net2.csproj b/Mindscape.Raygun4Net2/Mindscape.Raygun4Net2.csproj index 46cdd00a..f24c254c 100644 --- a/Mindscape.Raygun4Net2/Mindscape.Raygun4Net2.csproj +++ b/Mindscape.Raygun4Net2/Mindscape.Raygun4Net2.csproj @@ -75,6 +75,9 @@ <Compile Include="..\Mindscape.Raygun4Net\Messages\RaygunResponseMessage.cs"> <Link>Messages\RaygunResponseMessage.cs</Link> </Compile> + <Compile Include="..\Mindscape.Raygun4Net\RaygunRequestMessageOptions.cs"> + <Link>RaygunRequestMessageOptions.cs</Link> + </Compile> <Compile Include="..\Mindscape.Raygun4Net\SimpleJson.cs"> <Link>SimpleJson.cs</Link> </Compile> diff --git a/Mindscape.Raygun4Net2/RaygunClient.cs b/Mindscape.Raygun4Net2/RaygunClient.cs index a76d9332..f42bab60 100644 --- a/Mindscape.Raygun4Net2/RaygunClient.cs +++ b/Mindscape.Raygun4Net2/RaygunClient.cs @@ -13,8 +13,8 @@ namespace Mindscape.Raygun4Net public class RaygunClient { private readonly string _apiKey; + private readonly RaygunRequestMessageOptions _requestMessageOptions = new RaygunRequestMessageOptions(); private static List<Type> _wrapperExceptions; - private List<string> _ignoredFormNames; /// <summary> /// Initializes a new instance of the <see cref="RaygunClient" /> class. @@ -27,6 +27,27 @@ public RaygunClient(string apiKey) _wrapperExceptions.Add(typeof(TargetInvocationException)); _wrapperExceptions.Add(typeof(HttpUnhandledException)); + + if (!string.IsNullOrEmpty(RaygunSettings.Settings.IgnoreFormFieldNames)) + { + var ignoredNames = RaygunSettings.Settings.IgnoreFormFieldNames.Split(','); + IgnoreFormFieldNames(ignoredNames); + } + if (!string.IsNullOrEmpty(RaygunSettings.Settings.IgnoreHeaderNames)) + { + var ignoredNames = RaygunSettings.Settings.IgnoreHeaderNames.Split(','); + IgnoreHeaderNames(ignoredNames); + } + if (!string.IsNullOrEmpty(RaygunSettings.Settings.IgnoreCookieNames)) + { + var ignoredNames = RaygunSettings.Settings.IgnoreCookieNames.Split(','); + IgnoreCookieNames(ignoredNames); + } + if (!string.IsNullOrEmpty(RaygunSettings.Settings.IgnoreServerVariableNames)) + { + var ignoredNames = RaygunSettings.Settings.IgnoreServerVariableNames.Split(','); + IgnoreServerVariableNames(ignoredNames); + } } /// <summary> @@ -36,11 +57,6 @@ public RaygunClient(string apiKey) public RaygunClient() : this(RaygunSettings.Settings.ApiKey) { - if (!string.IsNullOrEmpty(RaygunSettings.Settings.IgnoreFormDataNames)) - { - var ignoredNames = RaygunSettings.Settings.IgnoreFormDataNames.Split(','); - IgnoreFormDataNames(ignoredNames); - } } protected bool ValidateApiKey() @@ -105,17 +121,54 @@ public void AddWrapperExceptions(IEnumerable<Type> wrapperExceptions) /// you to remove sensitive data from the transmitted copy of the Form on the HttpRequest by specifying the keys you want removed. /// This method is only effective in a web context. /// </summary> - /// <param name="names">An enumerable list of keys (Names) to be stripped from the copy of the Form NameValueCollection when sending to Raygun.</param> - public void IgnoreFormDataNames(IEnumerable<string> names) + /// <param name="names">Keys to be stripped from the copy of the Form NameValueCollection when sending to Raygun.</param> + public void IgnoreFormFieldNames(params string[] names) { - if (_ignoredFormNames == null) + foreach (string name in names) { - _ignoredFormNames = new List<string>(); + _requestMessageOptions.IgnoreFormFieldNames.Add(name); } + } + /// <summary> + /// Adds a list of keys to ignore when attaching the headers of an HTTP POST request. This allows + /// you to remove sensitive data from the transmitted copy of the Headers on the HttpRequest by specifying the keys you want removed. + /// This method is only effective in a web context. + /// </summary> + /// <param name="names">Keys to be stripped from the copy of the Headers NameValueCollection when sending to Raygun.</param> + public void IgnoreHeaderNames(params string[] names) + { + foreach (string name in names) + { + _requestMessageOptions.IgnoreHeaderNames.Add(name); + } + } + + /// <summary> + /// Adds a list of keys to ignore when attaching the cookies of an HTTP POST request. This allows + /// you to remove sensitive data from the transmitted copy of the Cookies on the HttpRequest by specifying the keys you want removed. + /// This method is only effective in a web context. + /// </summary> + /// <param name="names">Keys to be stripped from the copy of the Cookies NameValueCollection when sending to Raygun.</param> + public void IgnoreCookieNames(params string[] names) + { + foreach (string name in names) + { + _requestMessageOptions.IgnoreCookieNames.Add(name); + } + } + + /// <summary> + /// Adds a list of keys to ignore when attaching the server variables of an HTTP POST request. This allows + /// you to remove sensitive data from the transmitted copy of the ServerVariables on the HttpRequest by specifying the keys you want removed. + /// This method is only effective in a web context. + /// </summary> + /// <param name="names">Keys to be stripped from the copy of the ServerVariables NameValueCollection when sending to Raygun.</param> + public void IgnoreServerVariableNames(params string[] names) + { foreach (string name in names) { - _ignoredFormNames.Add(name); + _requestMessageOptions.IgnoreServerVariableNames.Add(name); } } @@ -196,7 +249,7 @@ protected RaygunMessage BuildMessage(Exception exception, IList<string> tags, ID exception = StripWrapperExceptions(exception); var message = RaygunMessageBuilder.New - .SetHttpDetails(HttpContext.Current, _ignoredFormNames) + .SetHttpDetails(HttpContext.Current, _requestMessageOptions) .SetEnvironmentDetails() .SetMachineName(Environment.MachineName) .SetExceptionDetails(exception) diff --git a/Mindscape.Raygun4Net2/RaygunMessageBuilder.cs b/Mindscape.Raygun4Net2/RaygunMessageBuilder.cs index d79610df..9c05bfa5 100644 --- a/Mindscape.Raygun4Net2/RaygunMessageBuilder.cs +++ b/Mindscape.Raygun4Net2/RaygunMessageBuilder.cs @@ -106,7 +106,7 @@ public IRaygunMessageBuilder SetUser(string user) return this; } - public IRaygunMessageBuilder SetHttpDetails(HttpContext context, List<string> ignoredFormNames = null) + public IRaygunMessageBuilder SetHttpDetails(HttpContext context, RaygunRequestMessageOptions options = null) { if (context != null) { @@ -119,7 +119,7 @@ public IRaygunMessageBuilder SetHttpDetails(HttpContext context, List<string> ig { return this; } - _raygunMessage.Details.Request = new RaygunRequestMessage(request, ignoredFormNames); + _raygunMessage.Details.Request = new RaygunRequestMessage(request, options ?? new RaygunRequestMessageOptions()); } return this; diff --git a/Mindscape.Raygun4Net2/RaygunSettings.cs b/Mindscape.Raygun4Net2/RaygunSettings.cs index 4b03a39f..0ba65432 100644 --- a/Mindscape.Raygun4Net2/RaygunSettings.cs +++ b/Mindscape.Raygun4Net2/RaygunSettings.cs @@ -46,11 +46,32 @@ public bool ExcludeErrorsFromLocal set { this["excludeErrorsFromLocal"] = value; } } - [ConfigurationProperty("ignoreFormDataNames", IsRequired = false, DefaultValue = "")] - public string IgnoreFormDataNames + [ConfigurationProperty("ignoreFormFieldNames", IsRequired = false, DefaultValue = "")] + public string IgnoreFormFieldNames { - get { return (string)this["ignoreFormDataNames"]; } - set { this["ignoreFormDataNames"] = value; } + get { return (string)this["ignoreFormFieldNames"]; } + set { this["ignoreFormFieldNames"] = value; } + } + + [ConfigurationProperty("ignoreHeaderNames", IsRequired = false, DefaultValue = "")] + public string IgnoreHeaderNames + { + get { return (string)this["ignoreHeaderNames"]; } + set { this["ignoreHeaderNames"] = value; } + } + + [ConfigurationProperty("ignoreCookieNames", IsRequired = false, DefaultValue = "")] + public string IgnoreCookieNames + { + get { return (string)this["ignoreCookieNames"]; } + set { this["ignoreCookieNames"] = value; } + } + + [ConfigurationProperty("ignoreServerVariableNames", IsRequired = false, DefaultValue = "")] + public string IgnoreServerVariableNames + { + get { return (string)this["ignoreServerVariableNames"]; } + set { this["ignoreServerVariableNames"] = value; } } } } From 838728ca9e86eb6dadfb3b441d99354d95c5f629 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Tue, 24 Jun 2014 12:39:20 +1200 Subject: [PATCH 15/28] Beginning to refactor the ignore-fields feature. --- .../Messages/RaygunRequestMessage.cs | 13 ++--- Mindscape.Raygun4Net/RaygunClient.cs | 5 +- .../RaygunRequestMessageOptions.cs | 53 ++++++++++++++++++- .../Messages/RaygunRequestMessage.cs | 13 +++-- Mindscape.Raygun4Net2/RaygunClient.cs | 5 +- 5 files changed, 72 insertions(+), 17 deletions(-) diff --git a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs index 17e93456..e51dfb9d 100644 --- a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs @@ -25,7 +25,7 @@ public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions opt Headers.Remove("Cookie"); Form = ToDictionary(request.Form, options.IgnoreFormFieldNames, true); - Cookies = GetCookies(request.Cookies, options.IgnoreCookieNames); + Cookies = GetCookies(request.Cookies, options.IsCookieIgnored); // Remove ignored and duplicated variables Data = ToDictionary(request.ServerVariables, options.IgnoreServerVariableNames); @@ -53,9 +53,9 @@ public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions opt } } - private IList GetCookies(HttpCookieCollection cookieCollection, IEnumerable<string> ignoredCookies) + private IList GetCookies(HttpCookieCollection cookieCollection, Func<string, bool> ignore) { - if (ignoredCookies.Count() == 1 && ignoredCookies.Contains("*")) + /*if (ignoredCookies.Count() == 1 && ignoredCookies.Contains("*")) { return Enumerable.Empty<Cookie>().ToList(); } @@ -73,12 +73,13 @@ private IList GetCookies(HttpCookieCollection cookieCollection, IEnumerable<stri { pureIgnores.Add(ignore); } - } + }*/ return Enumerable.Range(0, cookieCollection.Count) .Select(i => cookieCollection[i]) - .Where(c => !pureIgnores.Contains(c.Name)) - .Where(c => !IgnoreCookie(c.Name, expressions)) + //.Where(c => !pureIgnores.Contains(c.Name)) + //.Where(c => !IgnoreCookie(c.Name, expressions)) + .Where(c => !ignore(c.Name)) .Select(c => new Cookie(c.Name, c.Value)) .ToList(); } diff --git a/Mindscape.Raygun4Net/RaygunClient.cs b/Mindscape.Raygun4Net/RaygunClient.cs index e1d2b176..cbe6e28d 100644 --- a/Mindscape.Raygun4Net/RaygunClient.cs +++ b/Mindscape.Raygun4Net/RaygunClient.cs @@ -163,10 +163,11 @@ public void IgnoreHeaderNames(params string[] names) /// <param name="names">Keys to be stripped from the copy of the Cookies NameValueCollection when sending to Raygun.</param> public void IgnoreCookieNames(params string[] names) { - foreach (string name in names) + _requestMessageOptions.AddCookieNames(names); + /*foreach (string name in names) { _requestMessageOptions.IgnoreCookieNames.Add(name); - } + }*/ } /// <summary> diff --git a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs index cdf20db8..27ee4d8a 100644 --- a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs +++ b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs @@ -1,14 +1,20 @@ using System; using System.Collections.Generic; using System.Text; +using System.Text.RegularExpressions; namespace Mindscape.Raygun4Net { public class RaygunRequestMessageOptions { private readonly List<string> _ignoredFormFieldNames = new List<string>(); + private readonly List<Regex> _formFieldExpressions = new List<Regex>(); + private readonly List<string> _ignoreHeaderNames = new List<string>(); + private readonly List<string> _ignoreCookieNames = new List<string>(); + private readonly List<Regex> _cookieExpressions = new List<Regex>(); + private readonly List<string> _ignoreServerVariableNames = new List<string>(); public RaygunRequestMessageOptions() { } @@ -17,7 +23,12 @@ public RaygunRequestMessageOptions(IEnumerable<string> formFieldNames, IEnumerab { _ignoredFormFieldNames.AddRange(formFieldNames); _ignoreHeaderNames.AddRange(headerNames); - _ignoreCookieNames.AddRange(cookieNames); + + foreach (string name in cookieNames) + { + AddCookieNames(name); + } + _ignoreServerVariableNames.AddRange(serverVariableNames); } @@ -25,7 +36,45 @@ public RaygunRequestMessageOptions(IEnumerable<string> formFieldNames, IEnumerab public List<string> IgnoreHeaderNames { get { return _ignoreHeaderNames; } } - public List<string> IgnoreCookieNames { get { return _ignoreCookieNames; } } + //public List<string> IgnoreCookieNames { get { return _ignoreCookieNames; } } + public void AddCookieNames(params string[] names) + { + foreach (string name in names) + { + try + { + Regex regex = new Regex(name); + _cookieExpressions.Add(regex); + } + catch + { + _ignoreCookieNames.AddRange(names); + } + } + } + + public bool IsCookieIgnored(string name) + { + if (_ignoreCookieNames.Count == 1 && "*".Equals(_ignoreCookieNames[0])) + { + return true; + } + + if (_ignoreCookieNames.Contains(name)) + { + return true; + } + + foreach (Regex regex in _cookieExpressions) + { + Match match = regex.Match(name); + if (match != null && match.Success) + { + return true; + } + } + return false; + } public List<string> IgnoreServerVariableNames { get { return _ignoreServerVariableNames; } } } diff --git a/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs index 6d9a8547..49eb7f5e 100644 --- a/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs @@ -26,7 +26,7 @@ public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions opt Headers.Remove("Cookie"); Form = ToDictionary(request.Form, options.IgnoreFormFieldNames, true); - Cookies = GetCookies(request.Cookies, options.IgnoreCookieNames); + Cookies = GetCookies(request.Cookies, options.IsCookieIgnored); // Remove ignored and duplicated variables Data = ToDictionary(request.ServerVariables, options.IgnoreServerVariableNames); @@ -54,11 +54,13 @@ public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions opt } } - private IList GetCookies(HttpCookieCollection cookieCollection, IEnumerable<string> ignoredCookies) + private delegate R Func<R, T>(T value); + + private IList GetCookies(HttpCookieCollection cookieCollection, Func<bool, string> ignore) { IList cookies = new List<Cookie>(); - if (IgnoreAll(ignoredCookies)) + /*if (IgnoreAll(ignoredCookies)) { return cookies; } @@ -76,11 +78,12 @@ private IList GetCookies(HttpCookieCollection cookieCollection, IEnumerable<stri { pureIgnores.Add(ignore); } - } + }*/ foreach (string key in cookieCollection.Keys) { - if (!pureIgnores.Contains(key) && !IgnoreCookie(key, expressions)) + //if (!pureIgnores.Contains(key) && !IgnoreCookie(key, expressions)) + if (!ignore(key)) { cookies.Add(new Cookie(cookieCollection[key].Name, cookieCollection[key].Value)); } diff --git a/Mindscape.Raygun4Net2/RaygunClient.cs b/Mindscape.Raygun4Net2/RaygunClient.cs index f42bab60..9676a417 100644 --- a/Mindscape.Raygun4Net2/RaygunClient.cs +++ b/Mindscape.Raygun4Net2/RaygunClient.cs @@ -152,10 +152,11 @@ public void IgnoreHeaderNames(params string[] names) /// <param name="names">Keys to be stripped from the copy of the Cookies NameValueCollection when sending to Raygun.</param> public void IgnoreCookieNames(params string[] names) { - foreach (string name in names) + _requestMessageOptions.AddCookieNames(names); + /*foreach (string name in names) { _requestMessageOptions.IgnoreCookieNames.Add(name); - } + }*/ } /// <summary> From c54c0f897bcda309f1f70023216c4b26e135b9e2 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Tue, 24 Jun 2014 13:01:37 +1200 Subject: [PATCH 16/28] Replace regex support with wild card symbol * --- .../RaygunRequestMessageTests.cs | 64 +++++++++++-------- .../RaygunRequestMessageOptions.cs | 50 ++++++++------- 2 files changed, 67 insertions(+), 47 deletions(-) diff --git a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs index 46e60bd8..e9eb0f07 100644 --- a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs +++ b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs @@ -290,53 +290,67 @@ public void IgnoreAllCookies() } [Test] - public void HandleInvalidCookieRegex() + public void IgnoreCookie_StartsWith() { var request = new HttpRequest("test", "http://google.com", "test=test"); - request.Cookies.Add(new HttpCookie("+", "CookieValue")); - Assert.AreEqual(1, request.Cookies.Count); + request.Cookies.Add(new HttpCookie("TestCookieTest", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie", "CookieValue")); + request.Cookies.Add(new HttpCookie("CookieTest", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); - var options = new RaygunRequestMessageOptions(Enumerable.Empty<string>(), Enumerable.Empty<string>(), new string[] { "+" }, Enumerable.Empty<string>()); - RaygunRequestMessage message = null; - // Make sure the invalid regex "+" does not cause an exception: - Assert.DoesNotThrow(() => - { - message = new RaygunRequestMessage(request, options); - }); + var options = new RaygunRequestMessageOptions(Enumerable.Empty<string>(), Enumerable.Empty<string>(), new string[] { "cookie*" }, Enumerable.Empty<string>()); + var message = new RaygunRequestMessage(request, options); - Assert.AreEqual(0, message.Cookies.Count); + Assert.AreEqual(2, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookieTest")); + Assert.AreEqual(1, CookieCount(message, "TestCookie")); } [Test] - public void UseCookieRegex() + public void IgnoreCookie_EndsWith() { var request = new HttpRequest("test", "http://google.com", "test=test"); - request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); - request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); - request.Cookies.Add(new HttpCookie("TestCookie3", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookieTest", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie", "CookieValue")); + request.Cookies.Add(new HttpCookie("CookieTest", "CookieValue")); Assert.AreEqual(3, request.Cookies.Count); - var options = new RaygunRequestMessageOptions(Enumerable.Empty<string>(), Enumerable.Empty<string>(), new string[] { "TestCookie[1-2]" }, Enumerable.Empty<string>()); + var options = new RaygunRequestMessageOptions(Enumerable.Empty<string>(), Enumerable.Empty<string>(), new string[] { "*cookie" }, Enumerable.Empty<string>()); var message = new RaygunRequestMessage(request, options); - Assert.AreEqual(1, message.Cookies.Count); - Assert.AreEqual(1, CookieCount(message, "TestCookie3")); + Assert.AreEqual(2, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookieTest")); + Assert.AreEqual(1, CookieCount(message, "CookieTest")); } [Test] - public void UseCaseInsensitiveCookieRegex() + public void IgnoreCookie_Contains() { var request = new HttpRequest("test", "http://google.com", "test=test"); - request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); - request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); - request.Cookies.Add(new HttpCookie("AnotherCookie", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookieTest", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie", "CookieValue")); + request.Cookies.Add(new HttpCookie("CookieTest", "CookieValue")); Assert.AreEqual(3, request.Cookies.Count); - var options = new RaygunRequestMessageOptions(Enumerable.Empty<string>(), Enumerable.Empty<string>(), new string[] { "(?i)testcookie" }, Enumerable.Empty<string>()); + var options = new RaygunRequestMessageOptions(Enumerable.Empty<string>(), Enumerable.Empty<string>(), new string[] { "*cookie*" }, Enumerable.Empty<string>()); var message = new RaygunRequestMessage(request, options); - Assert.AreEqual(1, message.Cookies.Count); - Assert.AreEqual(1, CookieCount(message, "AnotherCookie")); + Assert.AreEqual(0, message.Cookies.Count); + } + + [Test] + public void IgnoreCookie_CaseInsensitive() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TESTCOOKIE", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie", "CookieValue")); + request.Cookies.Add(new HttpCookie("testcookie", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(Enumerable.Empty<string>(), Enumerable.Empty<string>(), new string[] { "TeStCoOkIe" }, Enumerable.Empty<string>()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(0, message.Cookies.Count); } private int CookieCount(RaygunRequestMessage message, string name) diff --git a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs index 27ee4d8a..19cb0e5d 100644 --- a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs +++ b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs @@ -8,13 +8,8 @@ namespace Mindscape.Raygun4Net public class RaygunRequestMessageOptions { private readonly List<string> _ignoredFormFieldNames = new List<string>(); - private readonly List<Regex> _formFieldExpressions = new List<Regex>(); - private readonly List<string> _ignoreHeaderNames = new List<string>(); - private readonly List<string> _ignoreCookieNames = new List<string>(); - private readonly List<Regex> _cookieExpressions = new List<Regex>(); - private readonly List<string> _ignoreServerVariableNames = new List<string>(); public RaygunRequestMessageOptions() { } @@ -36,43 +31,54 @@ public RaygunRequestMessageOptions(IEnumerable<string> formFieldNames, IEnumerab public List<string> IgnoreHeaderNames { get { return _ignoreHeaderNames; } } - //public List<string> IgnoreCookieNames { get { return _ignoreCookieNames; } } public void AddCookieNames(params string[] names) { foreach (string name in names) { - try - { - Regex regex = new Regex(name); - _cookieExpressions.Add(regex); - } - catch + if (name != null) { - _ignoreCookieNames.AddRange(names); + _ignoreCookieNames.Add(name.ToLower()); } } } public bool IsCookieIgnored(string name) { - if (_ignoreCookieNames.Count == 1 && "*".Equals(_ignoreCookieNames[0])) + if (name == null || (_ignoreCookieNames.Count == 1 && "*".Equals(_ignoreCookieNames[0]))) { return true; } - if (_ignoreCookieNames.Contains(name)) + foreach (string ignore in _ignoreCookieNames) { - return true; - } - - foreach (Regex regex in _cookieExpressions) - { - Match match = regex.Match(name); - if (match != null && match.Success) + string lowerName = name.ToLower(); + if (ignore.StartsWith("*")) + { + if (ignore.EndsWith("*")) + { + if (lowerName.Contains(ignore.Substring(1, ignore.Length - 2))) + { + return true; + } + } + else + { + if (lowerName.EndsWith(ignore.Substring(1))) + { + return true; + } + } + } + else if (ignore.EndsWith("*") && lowerName.StartsWith(ignore.Substring(0, ignore.Length - 1))) + { + return true; + } + else if (lowerName.Equals(ignore)) { return true; } } + return false; } From da7636ca0c489dfee909224bffa2855a382b6a17 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Tue, 24 Jun 2014 13:27:51 +1200 Subject: [PATCH 17/28] Replaced regex support for form fields, headers and server variables. --- .../RaygunRequestMessageTests.cs | 67 ++++++++++-------- .../Messages/RaygunRequestMessage.cs | 25 ++++--- Mindscape.Raygun4Net/RaygunClient.cs | 19 +---- .../RaygunRequestMessageOptions.cs | 69 +++++++++++++++---- 4 files changed, 113 insertions(+), 67 deletions(-) diff --git a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs index e9eb0f07..a831e01c 100644 --- a/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs +++ b/Mindscape.Raygun4Net.Tests/RaygunRequestMessageTests.cs @@ -80,7 +80,7 @@ public void FormFields() } [Test] - public void IgnoreFormFields() + public void IgnoreFormField() { var request = CreateWritableRequest(); @@ -131,56 +131,69 @@ public void IgnoreAllFormFields() } [Test] - public void HandleInvalidFormFieldRegex() + public void IgnoreFormField_StartsWith() { var request = CreateWritableRequest(); - request.Form.Add("+", "FormFieldValue"); // Not a valid form name, but useful for this test. - Assert.AreEqual(1, request.Form.Count); + request.Form.Add("TestFormFieldTest", "FormFieldValue"); + request.Form.Add("TestFormField", "FormFieldValue"); + request.Form.Add("FormFieldTest", "FormFieldValue"); + Assert.AreEqual(3, request.Form.Count); - var options = new RaygunRequestMessageOptions(new string[] { "+" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); - RaygunRequestMessage message = null; - // Make sure the invalid regex "+" does not cause an exception: - Assert.DoesNotThrow(() => - { - message = new RaygunRequestMessage(request, options); - }); + var options = new RaygunRequestMessageOptions(new string[] { "formfield*" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); + var message = new RaygunRequestMessage(request, options); - Assert.AreEqual(0, message.Form.Count); + Assert.AreEqual(2, message.Form.Count); + Assert.IsTrue(message.Form.Contains("TestFormFieldTest")); + Assert.IsTrue(message.Form.Contains("TestFormField")); } [Test] - public void UseFormFieldRegex() + public void IgnoreFormField_EndsWith() { var request = CreateWritableRequest(); - request.Form.Add("TestFormField1", "FormFieldValue"); - request.Form.Add("TestFormField2", "FormFieldValue"); - request.Form.Add("TestFormField3", "FormFieldValue"); + request.Form.Add("TestFormFieldTest", "FormFieldValue"); + request.Form.Add("TestFormField", "FormFieldValue"); + request.Form.Add("FormFieldTest", "FormFieldValue"); Assert.AreEqual(3, request.Form.Count); - var options = new RaygunRequestMessageOptions(new string[] { "TestFormField[1-2]" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); + var options = new RaygunRequestMessageOptions(new string[] { "*formfield" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); var message = new RaygunRequestMessage(request, options); - Assert.AreEqual(1, message.Form.Count); - Assert.IsTrue(message.Form.Contains("TestFormField3")); + Assert.AreEqual(2, message.Form.Count); + Assert.IsTrue(message.Form.Contains("TestFormFieldTest")); + Assert.IsTrue(message.Form.Contains("FormFieldTest")); } [Test] - public void UseCaseInsensitiveFormFieldRegex() + public void IgnoreFormField_Contains() { var request = CreateWritableRequest(); - request.Form.Add("TestFormField1", "FormFieldValue"); - request.Form.Add("TestFormField2", "FormFieldValue"); - request.Form.Add("AnotherFormField", "FormFieldValue"); + request.Form.Add("TestFormFieldTest", "FormFieldValue"); + request.Form.Add("TestFormField", "FormFieldValue"); + request.Form.Add("FormFieldTest", "FormFieldValue"); Assert.AreEqual(3, request.Form.Count); - var options = new RaygunRequestMessageOptions(new string[] { "(?i)testformfield" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); + var options = new RaygunRequestMessageOptions(new string[] { "*formfield*" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); var message = new RaygunRequestMessage(request, options); - Assert.AreEqual(1, message.Form.Count); - Assert.IsTrue(message.Form.Contains("AnotherFormField")); + Assert.AreEqual(0, message.Form.Count); + } + + [Test] + public void IgnoreFormField_CaseInsensitive() + { + var request = CreateWritableRequest(); + + request.Form.Add("TESTFORMFIELD", "FormFieldValue"); + Assert.AreEqual(1, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "testformfield" }, Enumerable.Empty<string>(), Enumerable.Empty<string>(), Enumerable.Empty<string>()); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(0, message.Form.Count); } private HttpRequest CreateWritableRequest() @@ -243,7 +256,7 @@ public void IgnoreCookie() } [Test] - public void IgnoreDuplicateCookie() + public void IgnoreDuplicateCookies() { var request = new HttpRequest("test", "http://google.com", "test=test"); request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); diff --git a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs index e51dfb9d..b31ab479 100644 --- a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs @@ -19,16 +19,16 @@ public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions opt Url = request.Url.AbsolutePath; HttpMethod = request.RequestType; IPAddress = request.UserHostAddress; - QueryString = ToDictionary(request.QueryString, Enumerable.Empty<string>()); + QueryString = ToDictionary(request.QueryString, null); - Headers = ToDictionary(request.Headers, options.IgnoreHeaderNames); + Headers = ToDictionary(request.Headers, options.IsHeaderIgnored); Headers.Remove("Cookie"); - Form = ToDictionary(request.Form, options.IgnoreFormFieldNames, true); + Form = ToDictionary(request.Form, options.IsFormFieldIgnored, true); Cookies = GetCookies(request.Cookies, options.IsCookieIgnored); // Remove ignored and duplicated variables - Data = ToDictionary(request.ServerVariables, options.IgnoreServerVariableNames); + Data = ToDictionary(request.ServerVariables, options.IsServerVariableIgnored); Data.Remove("ALL_HTTP"); Data.Remove("HTTP_COOKIE"); Data.Remove("ALL_RAW"); @@ -97,20 +97,27 @@ private bool IgnoreCookie(string name, List<Regex> expressions) return false; } - private static IDictionary ToDictionary(NameValueCollection nameValueCollection, IEnumerable<string> ignoreKeys, bool truncateValues = false) + private static IDictionary ToDictionary(NameValueCollection nameValueCollection, Func<string, bool> ignore, bool truncateValues = false) { var dictionary = new Dictionary<string, string>(); - if (ignoreKeys.Count() == 1 && "*".Equals(ignoreKeys.First())) + /*if (ignoreKeys.Count() == 1 && "*".Equals(ignoreKeys.First())) { return dictionary; - } + }*/ IEnumerable<string> keys; try { - keys = Filter(nameValueCollection, ignoreKeys); + if (ignore == null) + { + keys = nameValueCollection.AllKeys.Where(k => k != null); + } + else + { + keys = nameValueCollection.AllKeys.Where(k => !ignore(k)); + } } catch (HttpRequestValidationException) { @@ -143,7 +150,7 @@ private static IDictionary ToDictionary(NameValueCollection nameValueCollection, { // If changing QueryString to be of type string in future, will need to account for possible // illegal values - in this case it is contained at the end of e.Message along with an error message - + int firstInstance = e.Message.IndexOf('\"'); int lastInstance = e.Message.LastIndexOf('\"'); diff --git a/Mindscape.Raygun4Net/RaygunClient.cs b/Mindscape.Raygun4Net/RaygunClient.cs index cbe6e28d..1e129f03 100644 --- a/Mindscape.Raygun4Net/RaygunClient.cs +++ b/Mindscape.Raygun4Net/RaygunClient.cs @@ -135,10 +135,7 @@ public void AddWrapperExceptions(IEnumerable<Type> wrapperExceptions) /// <param name="names">Keys to be stripped from the copy of the Form NameValueCollection when sending to Raygun.</param> public void IgnoreFormFieldNames(params string[] names) { - foreach (string name in names) - { - _requestMessageOptions.IgnoreFormFieldNames.Add(name); - } + _requestMessageOptions.AddFormFieldNames(names); } /// <summary> @@ -149,10 +146,7 @@ public void IgnoreFormFieldNames(params string[] names) /// <param name="names">Keys to be stripped from the copy of the Headers NameValueCollection when sending to Raygun.</param> public void IgnoreHeaderNames(params string[] names) { - foreach (string name in names) - { - _requestMessageOptions.IgnoreHeaderNames.Add(name); - } + _requestMessageOptions.AddHeaderNames(names); } /// <summary> @@ -164,10 +158,6 @@ public void IgnoreHeaderNames(params string[] names) public void IgnoreCookieNames(params string[] names) { _requestMessageOptions.AddCookieNames(names); - /*foreach (string name in names) - { - _requestMessageOptions.IgnoreCookieNames.Add(name); - }*/ } /// <summary> @@ -178,10 +168,7 @@ public void IgnoreCookieNames(params string[] names) /// <param name="names">Keys to be stripped from the copy of the ServerVariables NameValueCollection when sending to Raygun.</param> public void IgnoreServerVariableNames(params string[] names) { - foreach (string name in names) - { - _requestMessageOptions.IgnoreServerVariableNames.Add(name); - } + _requestMessageOptions.AddServerVariableNames(names); } /// <summary> diff --git a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs index 19cb0e5d..f2420c09 100644 --- a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs +++ b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs @@ -16,40 +16,81 @@ public RaygunRequestMessageOptions() { } public RaygunRequestMessageOptions(IEnumerable<string> formFieldNames, IEnumerable<string> headerNames, IEnumerable<string> cookieNames, IEnumerable<string> serverVariableNames) { - _ignoredFormFieldNames.AddRange(formFieldNames); - _ignoreHeaderNames.AddRange(headerNames); + Add(_ignoredFormFieldNames, formFieldNames); + Add(_ignoreHeaderNames, headerNames); + Add(_ignoreCookieNames, cookieNames); + Add(_ignoreServerVariableNames, serverVariableNames); + } - foreach (string name in cookieNames) - { - AddCookieNames(name); - } + // Form fields - _ignoreServerVariableNames.AddRange(serverVariableNames); + public void AddFormFieldNames(params string[] names) + { + Add(_ignoredFormFieldNames, names); } - public List<string> IgnoreFormFieldNames { get { return _ignoredFormFieldNames; } } + public bool IsFormFieldIgnored(string name) + { + return IsIgnored(name, _ignoredFormFieldNames); + } - public List<string> IgnoreHeaderNames { get { return _ignoreHeaderNames; } } + // Headers + + public void AddHeaderNames(params string[] names) + { + Add(_ignoreHeaderNames, names); + } + + public bool IsHeaderIgnored(string name) + { + return IsIgnored(name, _ignoreHeaderNames); + } + + // Cookies public void AddCookieNames(params string[] names) + { + Add(_ignoreCookieNames, names); + } + + public bool IsCookieIgnored(string name) + { + return IsIgnored(name, _ignoreCookieNames); + } + + // Server variables + + public void AddServerVariableNames(params string[] names) + { + Add(_ignoreServerVariableNames, names); + } + + public bool IsServerVariableIgnored(string name) + { + return IsIgnored(name, _ignoreServerVariableNames); + } + + // Core methods: + + private void Add(List<string> list, IEnumerable<string> names) { foreach (string name in names) { if (name != null) { - _ignoreCookieNames.Add(name.ToLower()); + list.Add(name.ToLower()); } } } - public bool IsCookieIgnored(string name) + private bool IsIgnored(string name, List<string> list) { - if (name == null || (_ignoreCookieNames.Count == 1 && "*".Equals(_ignoreCookieNames[0]))) + if (name == null || (list.Count == 1 && "*".Equals(list[0]))) { return true; } - foreach (string ignore in _ignoreCookieNames) + foreach (string ignore in list) { string lowerName = name.ToLower(); if (ignore.StartsWith("*")) @@ -81,7 +122,5 @@ public bool IsCookieIgnored(string name) return false; } - - public List<string> IgnoreServerVariableNames { get { return _ignoreServerVariableNames; } } } } From 4f963bae53e59c1c984907b8efa839ec06d5803c Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Tue, 24 Jun 2014 13:42:35 +1200 Subject: [PATCH 18/28] Tidy up --- .../Messages/RaygunRequestMessage.cs | 80 +---------- .../RaygunRequestMessageTests.cs | 127 +++++++++++------- .../Messages/RaygunRequestMessage.cs | 115 ++-------------- Mindscape.Raygun4Net2/RaygunClient.cs | 19 +-- 4 files changed, 96 insertions(+), 245 deletions(-) diff --git a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs index b31ab479..24c29866 100644 --- a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs @@ -55,57 +55,15 @@ public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions opt private IList GetCookies(HttpCookieCollection cookieCollection, Func<string, bool> ignore) { - /*if (ignoredCookies.Count() == 1 && ignoredCookies.Contains("*")) - { - return Enumerable.Empty<Cookie>().ToList(); - } - - HashSet<string> pureIgnores = new HashSet<string>(); - List<Regex> expressions = new List<Regex>(); - foreach (string ignore in ignoredCookies) - { - try - { - Regex regex = new Regex(ignore); - expressions.Add(regex); - } - catch - { - pureIgnores.Add(ignore); - } - }*/ - return Enumerable.Range(0, cookieCollection.Count) .Select(i => cookieCollection[i]) - //.Where(c => !pureIgnores.Contains(c.Name)) - //.Where(c => !IgnoreCookie(c.Name, expressions)) .Where(c => !ignore(c.Name)) .Select(c => new Cookie(c.Name, c.Value)) .ToList(); } - private bool IgnoreCookie(string name, List<Regex> expressions) - { - foreach (Regex regex in expressions) - { - Match match = regex.Match(name); - if (match != null && match.Success) - { - return true; - } - } - return false; - } - private static IDictionary ToDictionary(NameValueCollection nameValueCollection, Func<string, bool> ignore, bool truncateValues = false) { - var dictionary = new Dictionary<string, string>(); - - /*if (ignoreKeys.Count() == 1 && "*".Equals(ignoreKeys.First())) - { - return dictionary; - }*/ - IEnumerable<string> keys; try @@ -124,6 +82,8 @@ private static IDictionary ToDictionary(NameValueCollection nameValueCollection, return new Dictionary<string, string> { { "Values", "Not able to be retrieved" } }; } + var dictionary = new Dictionary<string, string>(); + foreach (string key in keys) { try @@ -168,42 +128,6 @@ private static IDictionary ToDictionary(NameValueCollection nameValueCollection, return dictionary; } - private static IEnumerable<string> Filter(NameValueCollection nameValueCollection, IEnumerable<string> ignoreFields) - { - List<string> pureIgnores = new List<string>(); - List<Regex> expressions = new List<Regex>(); - foreach (string ignore in ignoreFields) - { - try - { - Regex regex = new Regex(ignore); - expressions.Add(regex); - } - catch - { - pureIgnores.Add(ignore); - } - } - - foreach (string key in nameValueCollection.AllKeys.Where(k => k != null).Except(pureIgnores)) - { - bool send = true; - foreach (Regex regex in expressions) - { - Match match = regex.Match(key); - if (match != null && match.Success) - { - send = false; - break; - } - } - if (send) - { - yield return key; - } - } - } - public class Cookie { public Cookie(string name, string value) diff --git a/Mindscape.Raygun4Net2.Tests/RaygunRequestMessageTests.cs b/Mindscape.Raygun4Net2.Tests/RaygunRequestMessageTests.cs index 790d9e74..d914a083 100644 --- a/Mindscape.Raygun4Net2.Tests/RaygunRequestMessageTests.cs +++ b/Mindscape.Raygun4Net2.Tests/RaygunRequestMessageTests.cs @@ -127,56 +127,69 @@ public void IgnoreAllFormFields() } [Test] - public void HandleInvalidFormFieldRegex() + public void IgnoreFormField_StartsWith() { var request = CreateWritableRequest(); - request.Form.Add("+", "FormFieldValue"); // Not a valid form name, but useful for this test. - Assert.AreEqual(1, request.Form.Count); + request.Form.Add("TestFormFieldTest", "FormFieldValue"); + request.Form.Add("TestFormField", "FormFieldValue"); + request.Form.Add("FormFieldTest", "FormFieldValue"); + Assert.AreEqual(3, request.Form.Count); - var options = new RaygunRequestMessageOptions(new string[] { "+" }, _empty, _empty, _empty); - RaygunRequestMessage message = null; - // Make sure the invalid regex "+" does not cause an exception: - Assert.DoesNotThrow(() => - { - message = new RaygunRequestMessage(request, options); - }); + var options = new RaygunRequestMessageOptions(new string[] { "formfield*" }, _empty, _empty, _empty); + var message = new RaygunRequestMessage(request, options); - Assert.AreEqual(0, message.Form.Count); + Assert.AreEqual(2, message.Form.Count); + Assert.IsTrue(message.Form.Contains("TestFormFieldTest")); + Assert.IsTrue(message.Form.Contains("TestFormField")); } [Test] - public void UseFormFieldRegex() + public void IgnoreFormField_EndsWith() { var request = CreateWritableRequest(); - request.Form.Add("TestFormField1", "FormFieldValue"); - request.Form.Add("TestFormField2", "FormFieldValue"); - request.Form.Add("TestFormField3", "FormFieldValue"); + request.Form.Add("TestFormFieldTest", "FormFieldValue"); + request.Form.Add("TestFormField", "FormFieldValue"); + request.Form.Add("FormFieldTest", "FormFieldValue"); Assert.AreEqual(3, request.Form.Count); - var options = new RaygunRequestMessageOptions(new string[] { "TestFormField[1-2]" }, _empty, _empty, _empty); + var options = new RaygunRequestMessageOptions(new string[] { "*formfield" }, _empty, _empty, _empty); var message = new RaygunRequestMessage(request, options); - Assert.AreEqual(1, message.Form.Count); - Assert.IsTrue(message.Form.Contains("TestFormField3")); + Assert.AreEqual(2, message.Form.Count); + Assert.IsTrue(message.Form.Contains("TestFormFieldTest")); + Assert.IsTrue(message.Form.Contains("FormFieldTest")); } [Test] - public void UseCaseInsensitiveFormFieldRegex() + public void IgnoreFormField_Contains() { var request = CreateWritableRequest(); - request.Form.Add("TestFormField1", "FormFieldValue"); - request.Form.Add("TestFormField2", "FormFieldValue"); - request.Form.Add("AnotherFormField", "FormFieldValue"); + request.Form.Add("TestFormFieldTest", "FormFieldValue"); + request.Form.Add("TestFormField", "FormFieldValue"); + request.Form.Add("FormFieldTest", "FormFieldValue"); Assert.AreEqual(3, request.Form.Count); - var options = new RaygunRequestMessageOptions(new string[] { "(?i)testformfield" }, _empty, _empty, _empty); + var options = new RaygunRequestMessageOptions(new string[] { "*formfield*" }, _empty, _empty, _empty); var message = new RaygunRequestMessage(request, options); - Assert.AreEqual(1, message.Form.Count); - Assert.IsTrue(message.Form.Contains("AnotherFormField")); + Assert.AreEqual(0, message.Form.Count); + } + + [Test] + public void IgnoreFormField_CaseInsensitive() + { + var request = CreateWritableRequest(); + + request.Form.Add("TESTFORMFIELD", "FormFieldValue"); + Assert.AreEqual(1, request.Form.Count); + + var options = new RaygunRequestMessageOptions(new string[] { "testformfield" }, _empty, _empty, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(0, message.Form.Count); } private HttpRequest CreateWritableRequest() @@ -286,53 +299,67 @@ public void IgnoreAllCookies() } [Test] - public void HandleInvalidCookieRegex() + public void IgnoreCookie_StartsWith() + { + var request = new HttpRequest("test", "http://google.com", "test=test"); + request.Cookies.Add(new HttpCookie("TestCookieTest", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie", "CookieValue")); + request.Cookies.Add(new HttpCookie("CookieTest", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); + + var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "cookie*" }, _empty); + var message = new RaygunRequestMessage(request, options); + + Assert.AreEqual(2, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookieTest")); + Assert.AreEqual(1, CookieCount(message, "TestCookie")); + } + + [Test] + public void IgnoreCookie_EndsWith() { var request = new HttpRequest("test", "http://google.com", "test=test"); - request.Cookies.Add(new HttpCookie("+", "CookieValue")); - Assert.AreEqual(1, request.Cookies.Count); + request.Cookies.Add(new HttpCookie("TestCookieTest", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie", "CookieValue")); + request.Cookies.Add(new HttpCookie("CookieTest", "CookieValue")); + Assert.AreEqual(3, request.Cookies.Count); - var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "+" }, _empty); - RaygunRequestMessage message = null; - // Make sure the invalid regex "+" does not cause an exception: - Assert.DoesNotThrow(() => - { - message = new RaygunRequestMessage(request, options); - }); + var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "*cookie" }, _empty); + var message = new RaygunRequestMessage(request, options); - Assert.AreEqual(0, message.Cookies.Count); + Assert.AreEqual(2, message.Cookies.Count); + Assert.AreEqual(1, CookieCount(message, "TestCookieTest")); + Assert.AreEqual(1, CookieCount(message, "CookieTest")); } [Test] - public void UseCookieRegex() + public void IgnoreCookie_Contains() { var request = new HttpRequest("test", "http://google.com", "test=test"); - request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); - request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); - request.Cookies.Add(new HttpCookie("TestCookie3", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookieTest", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie", "CookieValue")); + request.Cookies.Add(new HttpCookie("CookieTest", "CookieValue")); Assert.AreEqual(3, request.Cookies.Count); - var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "TestCookie[1-2]" }, _empty); + var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "*cookie*" }, _empty); var message = new RaygunRequestMessage(request, options); - Assert.AreEqual(1, message.Cookies.Count); - Assert.AreEqual(1, CookieCount(message, "TestCookie3")); + Assert.AreEqual(0, message.Cookies.Count); } [Test] - public void UseCaseInsensitiveCookieRegex() + public void IgnoreCookie_CaseInsensitive() { var request = new HttpRequest("test", "http://google.com", "test=test"); - request.Cookies.Add(new HttpCookie("TestCookie1", "CookieValue")); - request.Cookies.Add(new HttpCookie("TestCookie2", "CookieValue")); - request.Cookies.Add(new HttpCookie("AnotherCookie", "CookieValue")); + request.Cookies.Add(new HttpCookie("TESTCOOKIE", "CookieValue")); + request.Cookies.Add(new HttpCookie("TestCookie", "CookieValue")); + request.Cookies.Add(new HttpCookie("testcookie", "CookieValue")); Assert.AreEqual(3, request.Cookies.Count); - var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "(?i)testcookie" }, _empty); + var options = new RaygunRequestMessageOptions(_empty, _empty, new string[] { "TeStCoOkIe" }, _empty); var message = new RaygunRequestMessage(request, options); - Assert.AreEqual(1, message.Cookies.Count); - Assert.AreEqual(1, CookieCount(message, "AnotherCookie")); + Assert.AreEqual(0, message.Cookies.Count); } private int CookieCount(RaygunRequestMessage message, string name) diff --git a/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs index 49eb7f5e..d71d635f 100644 --- a/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs @@ -19,17 +19,17 @@ public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions opt Url = request.Url.AbsolutePath; HttpMethod = request.RequestType; IPAddress = request.UserHostAddress; - IEnumerable<string> empty = new List<string>(); - QueryString = ToDictionary(request.QueryString, empty); + + QueryString = ToDictionary(request.QueryString, null); - Headers = ToDictionary(request.Headers, options.IgnoreHeaderNames); + Headers = ToDictionary(request.Headers, options.IsHeaderIgnored); Headers.Remove("Cookie"); - Form = ToDictionary(request.Form, options.IgnoreFormFieldNames, true); + Form = ToDictionary(request.Form, options.IsFormFieldIgnored, true); Cookies = GetCookies(request.Cookies, options.IsCookieIgnored); // Remove ignored and duplicated variables - Data = ToDictionary(request.ServerVariables, options.IgnoreServerVariableNames); + Data = ToDictionary(request.ServerVariables, options.IsServerVariableIgnored); Data.Remove("ALL_HTTP"); Data.Remove("HTTP_COOKIE"); Data.Remove("ALL_RAW"); @@ -54,35 +54,14 @@ public RaygunRequestMessage(HttpRequest request, RaygunRequestMessageOptions opt } } - private delegate R Func<R, T>(T value); + private delegate R Func<T, R>(T value); - private IList GetCookies(HttpCookieCollection cookieCollection, Func<bool, string> ignore) + private IList GetCookies(HttpCookieCollection cookieCollection, Func<string, bool> ignore) { IList cookies = new List<Cookie>(); - /*if (IgnoreAll(ignoredCookies)) - { - return cookies; - } - - List<string> pureIgnores = new List<string>(); - List<Regex> expressions = new List<Regex>(); - foreach (string ignore in ignoredCookies) - { - try - { - Regex regex = new Regex(ignore); - expressions.Add(regex); - } - catch - { - pureIgnores.Add(ignore); - } - }*/ - foreach (string key in cookieCollection.Keys) { - //if (!pureIgnores.Contains(key) && !IgnoreCookie(key, expressions)) if (!ignore(key)) { cookies.Add(new Cookie(cookieCollection[key].Name, cookieCollection[key].Value)); @@ -92,39 +71,21 @@ private IList GetCookies(HttpCookieCollection cookieCollection, Func<bool, strin return cookies; } - private bool IgnoreCookie(string name, List<Regex> expressions) - { - foreach (Regex regex in expressions) - { - Match match = regex.Match(name); - if (match != null && match.Success) - { - return true; - } - } - return false; - } - - private static IDictionary ToDictionary(NameValueCollection nameValueCollection, IEnumerable<string> ignoreKeys, bool truncateValues = false) + private static IDictionary ToDictionary(NameValueCollection nameValueCollection, Func<string, bool> ignore, bool truncateValues = false) { - var dictionary = new Dictionary<string, string>(); - - if (IgnoreAll(ignoreKeys)) - { - return dictionary; - } - IEnumerable<string> keys; try { - keys = Filter(nameValueCollection, ignoreKeys); + keys = Filter(nameValueCollection, ignore); } catch (HttpRequestValidationException) { return new Dictionary<string, string> { { "Values", "Not able to be retrieved" } }; } + var dictionary = new Dictionary<string, string>(); + foreach (string key in keys) { try @@ -169,61 +130,13 @@ private static IDictionary ToDictionary(NameValueCollection nameValueCollection, return dictionary; } - private static bool IgnoreAll(IEnumerable<string> ignoreKeys) + private static IEnumerable<string> Filter(NameValueCollection nameValueCollection, Func<string, bool> ignore) { - bool ignoreAll = false; - int count = 0; - foreach (string ignore in ignoreKeys) - { - if ("*".Equals(ignore)) - { - ignoreAll = true; - } - count++; - if (count == 2) - { - ignoreAll = false; - break; - } - } - return ignoreAll; - } - - private static IEnumerable<string> Filter(NameValueCollection nameValueCollection, IEnumerable<string> ignoreFields) - { - List<string> pureIgnores = new List<string>(); - List<Regex> expressions = new List<Regex>(); - foreach (string ignore in ignoreFields) - { - try - { - Regex regex = new Regex(ignore); - expressions.Add(regex); - } - catch - { - pureIgnores.Add(ignore); - } - } - foreach (string key in nameValueCollection) { - if (key != null && !pureIgnores.Contains(key)) + if (key != null && (ignore == null || !ignore(key))) { - bool send = true; - foreach (Regex regex in expressions) - { - Match match = regex.Match(key); - if (match != null && match.Success) - { - send = false; - break; - } - } - if (send) - { - yield return key; - } + yield return key; } } } diff --git a/Mindscape.Raygun4Net2/RaygunClient.cs b/Mindscape.Raygun4Net2/RaygunClient.cs index 9676a417..0c454a42 100644 --- a/Mindscape.Raygun4Net2/RaygunClient.cs +++ b/Mindscape.Raygun4Net2/RaygunClient.cs @@ -124,10 +124,7 @@ public void AddWrapperExceptions(IEnumerable<Type> wrapperExceptions) /// <param name="names">Keys to be stripped from the copy of the Form NameValueCollection when sending to Raygun.</param> public void IgnoreFormFieldNames(params string[] names) { - foreach (string name in names) - { - _requestMessageOptions.IgnoreFormFieldNames.Add(name); - } + _requestMessageOptions.AddFormFieldNames(names); } /// <summary> @@ -138,10 +135,7 @@ public void IgnoreFormFieldNames(params string[] names) /// <param name="names">Keys to be stripped from the copy of the Headers NameValueCollection when sending to Raygun.</param> public void IgnoreHeaderNames(params string[] names) { - foreach (string name in names) - { - _requestMessageOptions.IgnoreHeaderNames.Add(name); - } + _requestMessageOptions.AddHeaderNames(names); } /// <summary> @@ -153,10 +147,6 @@ public void IgnoreHeaderNames(params string[] names) public void IgnoreCookieNames(params string[] names) { _requestMessageOptions.AddCookieNames(names); - /*foreach (string name in names) - { - _requestMessageOptions.IgnoreCookieNames.Add(name); - }*/ } /// <summary> @@ -167,10 +157,7 @@ public void IgnoreCookieNames(params string[] names) /// <param name="names">Keys to be stripped from the copy of the ServerVariables NameValueCollection when sending to Raygun.</param> public void IgnoreServerVariableNames(params string[] names) { - foreach (string name in names) - { - _requestMessageOptions.IgnoreServerVariableNames.Add(name); - } + _requestMessageOptions.AddServerVariableNames(names); } /// <summary> From 7afce979875df30521fcd3c59e2f81f8e0510bec Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Tue, 24 Jun 2014 14:18:57 +1200 Subject: [PATCH 19/28] Update readme --- README.md | 35 ++++++++++++++++++++++++----------- readme.txt | 34 +++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 6cccc069..956c17a2 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,19 @@ Raygun4Net [Raygun.io](http://raygun.io) Provider for .NET Framework +========================================================================================================= + **! IMPORTANT CHANGE IN 3.0 !** + +The ignoreFormDataNames configuration setting has been removed and replaced with 4 separate options: + +ignoreFormFieldNames +ignoreHeaderNames +ignoreCookieNames +ignoreServerVariableNames + +If you were once using the ignoreFormDataNames option to ignore headers, cookies or server variables, +make sure to use the new correct configuration options to ignore the appropriate bit. +========================================================================================================= Installation ==================== @@ -90,19 +103,19 @@ Toggle this boolean and the HTTP module will not send errors to Raygun.io if the **Remove sensitive request data** -If you have sensitive data in an HTTP request that you wish to prevent being transmitted to Raygun, you can provide a list of possible keys (Names) to remove: - -```csharp -raygunClient.IgnoreFormDataNames(new List<string>() { "SensitiveKey1", "SomeCreditCardData"}); -``` - -When an error occurs and is passed in to Raygun4Net, if any of the keys specified are present in request.Form, they will not be transmitted to the Raygun API. +If you have sensitive data in an HTTP request that you wish to prevent being transmitted to Raygun, you can provide lists of possible keys (names) to remove. +Keys to ignore can be specified on the RaygunSettings tag in web.config, (or you can use the equivalent methods on RaygunClient if you are setting things up in code). +The available options are: -*Sensitive keys are removed from the following transmitted properties:* +ignoreFormFieldNames +ignoreHeaderNames +ignoreCookieNames +ignoreServerVariableNames - * HttpRequest.**Headers** - * HttpRequest.**Form** - * HttpRequest.**ServerVariables** +These can be set to be a comma separated list of keys to ignore. Setting an option as * will indicate that all the keys will **not** be sent to Raygun. +Placing * before, after or at both ends of a key will perform an ends-with, starts-with or contains operation respectively. +For example, ignoreFormFieldNames="*password*" will cause Raygun to ignore all form fields that **contain** "password" anywhere in the name. +These options are **not** case sensitive. **Remove wrapper exceptions (available in all .NET Raygun providers)** diff --git a/readme.txt b/readme.txt index 99b52195..46a70094 100644 --- a/readme.txt +++ b/readme.txt @@ -1,6 +1,20 @@ Raygun4Net - Raygun.io Provider for .NET Framework =================== +========================================================================================================= +| ! IMPORTANT CHANGE IN 3.0 ! | +| | +| The ignoreFormDataNames configuration setting has been removed and replaced with 4 separate options: | +| | +| ignoreFormFieldNames | +| ignoreHeaderNames | +| ignoreCookieNames | +| ignoreServerVariableNames | +| | +| If you were once using the ignoreFormDataNames option to ignore headers, cookies or server variables, | +| make sure to use the new correct configuration options to ignore the appropriate bit. | +========================================================================================================= + Where is my app API key? ==================== When you create a new application on your Raygun.io dashboard, your app API key is displayed at the top of the instructions page. @@ -65,17 +79,19 @@ Toggle this boolean and the HTTP module will not send errors to Raygun.io if the Remove sensitive request data -If you have sensitive data in an HTTP request that you wish to prevent being transmitted to Raygun, you can provide a list of possible keys (Names) to remove: - -raygunClient.IgnoreFormDataNames(new List<string>() { "SensitiveKey1", "SomeCreditCardData"}); - -When an error occurs and is passed in to Raygun4Net, if any of the keys specified are present in request.Form, they will not be transmitted to the Raygun API. +If you have sensitive data in an HTTP request that you wish to prevent being transmitted to Raygun, you can provide lists of possible keys (names) to remove. +Keys to ignore can be specified on the RaygunSettings tag in web.config, (or you can use the equivalent methods on RaygunClient if you are setting things up in code). +The available options are: -Sensitive keys are removed from the following transmitted properties: +ignoreFormFieldNames +ignoreHeaderNames +ignoreCookieNames +ignoreServerVariableNames - * HttpRequest.Headers - * HttpRequest.Form - * HttpRequest.ServerVariables +These can be set to be a comma separated list of keys to ignore. Setting an option as * will indicate that all the keys will not be sent to Raygun. +Placing * before, after or at both ends of a key will perform an ends-with, starts-with or contains operation respectively. +For example, ignoreFormFieldNames="*password*" will cause Raygun to ignore all form fields that contain "password" anywhere in the name. +These options are not case sensitive. Remove wrapper exceptions (available in all .NET Raygun providers) From a2283eb5b7266a2cc6dadae3dfefe4c04fa3526e Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Tue, 24 Jun 2014 14:26:27 +1200 Subject: [PATCH 20/28] Fixed README.md --- README.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 956c17a2..5285fc35 100644 --- a/README.md +++ b/README.md @@ -3,19 +3,18 @@ Raygun4Net [Raygun.io](http://raygun.io) Provider for .NET Framework -========================================================================================================= - **! IMPORTANT CHANGE IN 3.0 !** +! IMPORTANT CHANGE IN 3.0 ! +==================== The ignoreFormDataNames configuration setting has been removed and replaced with 4 separate options: -ignoreFormFieldNames -ignoreHeaderNames -ignoreCookieNames -ignoreServerVariableNames +* ignoreFormFieldNames +* ignoreHeaderNames +* ignoreCookieNames +* ignoreServerVariableNames If you were once using the ignoreFormDataNames option to ignore headers, cookies or server variables, make sure to use the new correct configuration options to ignore the appropriate bit. -========================================================================================================= Installation ==================== @@ -107,10 +106,10 @@ If you have sensitive data in an HTTP request that you wish to prevent being tra Keys to ignore can be specified on the RaygunSettings tag in web.config, (or you can use the equivalent methods on RaygunClient if you are setting things up in code). The available options are: -ignoreFormFieldNames -ignoreHeaderNames -ignoreCookieNames -ignoreServerVariableNames +* ignoreFormFieldNames +* ignoreHeaderNames +* ignoreCookieNames +* ignoreServerVariableNames These can be set to be a comma separated list of keys to ignore. Setting an option as * will indicate that all the keys will **not** be sent to Raygun. Placing * before, after or at both ends of a key will perform an ends-with, starts-with or contains operation respectively. From f5fdf92a806d75c0124b5decf2b8d32d2f4dc03d Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Tue, 24 Jun 2014 16:48:19 +1200 Subject: [PATCH 21/28] Change AddWrapperExceptions to be a multi-parameter method. --- Mindscape.Raygun4Net.WinRT/RaygunClient.cs | 4 ++-- Mindscape.Raygun4Net.WindowsPhone/RaygunClient.cs | 4 ++-- Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs | 4 ++-- Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs | 4 ++-- Mindscape.Raygun4Net/RaygunClient.cs | 4 ++-- Mindscape.Raygun4Net2/RaygunClient.cs | 4 ++-- README.md | 6 +++--- readme.txt | 6 +++--- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Mindscape.Raygun4Net.WinRT/RaygunClient.cs b/Mindscape.Raygun4Net.WinRT/RaygunClient.cs index 60fb9f51..8ba5d30d 100644 --- a/Mindscape.Raygun4Net.WinRT/RaygunClient.cs +++ b/Mindscape.Raygun4Net.WinRT/RaygunClient.cs @@ -66,8 +66,8 @@ private bool ValidateApiKey() /// be used by Raygun for grouping and display. TargetInvocationException is added for you, /// but if you have other wrapper exceptions that you want stripped you can pass them in here. /// </summary> - /// <param name="wrapperExceptions">An enumerable list of exception types that you want removed and replaced with their inner exception.</param> - public void AddWrapperExceptions(IEnumerable<Type> wrapperExceptions) + /// <param name="wrapperExceptions">Exception types that you want removed and replaced with their inner exception.</param> + public void AddWrapperExceptions(params Type[] wrapperExceptions) { foreach (Type wrapper in wrapperExceptions) { diff --git a/Mindscape.Raygun4Net.WindowsPhone/RaygunClient.cs b/Mindscape.Raygun4Net.WindowsPhone/RaygunClient.cs index a40a8eec..789ceb32 100644 --- a/Mindscape.Raygun4Net.WindowsPhone/RaygunClient.cs +++ b/Mindscape.Raygun4Net.WindowsPhone/RaygunClient.cs @@ -80,8 +80,8 @@ private bool ValidateApiKey() /// be used by Raygun for grouping and display. TargetInvocationException is added for you, /// but if you have other wrapper exceptions that you want stripped you can pass them in here. /// </summary> - /// <param name="wrapperExceptions">An enumerable list of exception types that you want removed and replaced with their inner exception.</param> - public void AddWrapperExceptions(IEnumerable<Type> wrapperExceptions) + /// <param name="wrapperExceptions">Exception types that you want removed and replaced with their inner exception.</param> + public void AddWrapperExceptions(params Type[] wrapperExceptions) { foreach (Type wrapper in wrapperExceptions) { diff --git a/Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs b/Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs index 88bfb7f3..0ea0c7ef 100644 --- a/Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs +++ b/Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs @@ -68,8 +68,8 @@ private bool ValidateApiKey() /// be used by Raygun for grouping and display. The above two do not need to be added manually, /// but if you have other wrapper exceptions that you want stripped you can pass them in here. /// </summary> - /// <param name="wrapperExceptions">An enumerable list of exception types that you want removed and replaced with their inner exception.</param> - public void AddWrapperExceptions(IEnumerable<Type> wrapperExceptions) + /// <param name="wrapperExceptions">Exception types that you want removed and replaced with their inner exception.</param> + public void AddWrapperExceptions(params Type[] wrapperExceptions) { foreach (Type wrapper in wrapperExceptions) { diff --git a/Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs b/Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs index 12acfff4..e27aefdb 100644 --- a/Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs +++ b/Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs @@ -65,8 +65,8 @@ private bool ValidateApiKey() /// be used by Raygun for grouping and display. The above two do not need to be added manually, /// but if you have other wrapper exceptions that you want stripped you can pass them in here. /// </summary> - /// <param name="wrapperExceptions">An enumerable list of exception types that you want removed and replaced with their inner exception.</param> - public void AddWrapperExceptions(IEnumerable<Type> wrapperExceptions) + /// <param name="wrapperExceptions">Exception types that you want removed and replaced with their inner exception.</param> + public void AddWrapperExceptions(params Type[] wrapperExceptions) { foreach (Type wrapper in wrapperExceptions) { diff --git a/Mindscape.Raygun4Net/RaygunClient.cs b/Mindscape.Raygun4Net/RaygunClient.cs index 1e129f03..846ce6d7 100644 --- a/Mindscape.Raygun4Net/RaygunClient.cs +++ b/Mindscape.Raygun4Net/RaygunClient.cs @@ -115,8 +115,8 @@ protected bool OnSendingMessage(RaygunMessage raygunMessage) /// be used by Raygun for grouping and display. The above two do not need to be added manually, /// but if you have other wrapper exceptions that you want stripped you can pass them in here. /// </summary> - /// <param name="wrapperExceptions">An enumerable list of exception types that you want removed and replaced with their inner exception.</param> - public void AddWrapperExceptions(IEnumerable<Type> wrapperExceptions) + /// <param name="wrapperExceptions">Exception types that you want removed and replaced with their inner exception.</param> + public void AddWrapperExceptions(params Type[] wrapperExceptions) { foreach (Type wrapper in wrapperExceptions) { diff --git a/Mindscape.Raygun4Net2/RaygunClient.cs b/Mindscape.Raygun4Net2/RaygunClient.cs index 0c454a42..cd9495bd 100644 --- a/Mindscape.Raygun4Net2/RaygunClient.cs +++ b/Mindscape.Raygun4Net2/RaygunClient.cs @@ -104,8 +104,8 @@ protected bool OnSendingMessage(RaygunMessage raygunMessage) /// contains the actual exception as the InnerException. The message and stack trace of the inner exception will then /// be used by Raygun for grouping and display. TargetInvocationException and HttpUnhandledException will be stripped by default. /// </summary> - /// <param name="wrapperExceptions">An enumerable list of exception types that you want removed and replaced with their inner exception.</param> - public void AddWrapperExceptions(IEnumerable<Type> wrapperExceptions) + /// <param name="wrapperExceptions">Exception types that you want removed and replaced with their inner exception.</param> + public void AddWrapperExceptions(params Type[] wrapperExceptions) { foreach (Type wrapper in wrapperExceptions) { diff --git a/README.md b/README.md index 5285fc35..581ad72e 100644 --- a/README.md +++ b/README.md @@ -118,13 +118,13 @@ These options are **not** case sensitive. **Remove wrapper exceptions (available in all .NET Raygun providers)** -If you have common outer exceptions that wrap a valuable inner exception which you'd prefer to group by, you can specify these by providing a list: +If you have common outer exceptions that wrap a valuable inner exception which you'd prefer to group by, you can specify these by using the multi-parameter method: ```csharp -raygunClient.AddWrapperExceptions(new List<Type>() { typeof(TargetInvocationException) }); +raygunClient.AddWrapperExceptions(typeof(TargetInvocationException)); ``` -In this case, if a TargetInvocationException occurs, it will be removed and replaced with the actual InnerException that was the cause. Note that HttpUnhandledException and the above TargetInvocationException are already defined; you do not have to add these manually. This method is provided if you have your own common wrapper exceptions, or a framework is throwing exceptions using its own wrapper. +In this case, if a TargetInvocationException occurs, it will be removed and replaced with the actual InnerException that was the cause. Note that HttpUnhandledException and the above TargetInvocationException are already defined; you do not have to add these manually. This method is useful if you have your own custom wrapper exceptions, or a framework is throwing exceptions using its own wrapper. ### WPF diff --git a/readme.txt b/readme.txt index 46a70094..e2a4b23f 100644 --- a/readme.txt +++ b/readme.txt @@ -95,11 +95,11 @@ These options are not case sensitive. Remove wrapper exceptions (available in all .NET Raygun providers) -If you have common outer exceptions that wrap a valuable inner exception which you'd prefer to group by, you can specify these by providing a list: +If you have common outer exceptions that wrap a valuable inner exception which you'd prefer to group by, you can specify these by using the multi-parameter method: -raygunClient.AddWrapperExceptions(new List<Type>() { typeof(TargetInvocationException) }); +raygunClient.AddWrapperExceptions(typeof(TargetInvocationException)); -In this case, if a TargetInvocationException occurs, it will be removed and replaced with the actual InnerException that was the cause. Note that HttpUnhandledException and the above TargetInvocationException are already defined; you do not have to add these manually. This method is provided if you have your own common wrapper exceptions, or a framework is throwing exceptions using its own wrapper. +In this case, if a TargetInvocationException occurs, it will be removed and replaced with the actual InnerException that was the cause. Note that HttpUnhandledException and the above TargetInvocationException are already defined; you do not have to add these manually. This method is useful if you have your own custom wrapper exceptions, or a framework is throwing exceptions using its own wrapper. WPF ==================== From 02279cc4711deadb672649a1727d6c8c222b3a2f Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Wed, 25 Jun 2014 16:48:41 +1200 Subject: [PATCH 22/28] Added user IsAnonymous flag to .Net 2.0. --- Mindscape.Raygun4Net/IRaygunMessageBuilder.cs | 2 +- .../Messages/RaygunIdentifierMessage.cs | 4 +- .../RaygunClientTests.cs | 55 +++++++++++++++++++ Mindscape.Raygun4Net2/RaygunClient.cs | 7 ++- Mindscape.Raygun4Net2/RaygunMessageBuilder.cs | 7 +-- 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/Mindscape.Raygun4Net/IRaygunMessageBuilder.cs b/Mindscape.Raygun4Net/IRaygunMessageBuilder.cs index c89bdb09..e831aa6c 100644 --- a/Mindscape.Raygun4Net/IRaygunMessageBuilder.cs +++ b/Mindscape.Raygun4Net/IRaygunMessageBuilder.cs @@ -23,6 +23,6 @@ public interface IRaygunMessageBuilder IRaygunMessageBuilder SetTags(IList<string> tags); - IRaygunMessageBuilder SetUser(string user); + IRaygunMessageBuilder SetUser(RaygunIdentifierMessage user); } } \ No newline at end of file diff --git a/Mindscape.Raygun4Net/Messages/RaygunIdentifierMessage.cs b/Mindscape.Raygun4Net/Messages/RaygunIdentifierMessage.cs index 32308252..0b03c1d1 100644 --- a/Mindscape.Raygun4Net/Messages/RaygunIdentifierMessage.cs +++ b/Mindscape.Raygun4Net/Messages/RaygunIdentifierMessage.cs @@ -7,6 +7,8 @@ public RaygunIdentifierMessage(string user) Identifier = user; } - public string Identifier { get; private set; } + public string Identifier { get; set; } + + public bool IsAnonymous { get; set; } } } diff --git a/Mindscape.Raygun4Net2.Tests/RaygunClientTests.cs b/Mindscape.Raygun4Net2.Tests/RaygunClientTests.cs index 780b9352..726286aa 100644 --- a/Mindscape.Raygun4Net2.Tests/RaygunClientTests.cs +++ b/Mindscape.Raygun4Net2.Tests/RaygunClientTests.cs @@ -30,6 +30,12 @@ public void DefaultUser() Assert.IsNull(_client.User); } + [Test] + public void DefaultUserInfo() + { + Assert.IsNull(_client.UserInfo); + } + [Test] public void UserProperty() { @@ -37,6 +43,21 @@ public void UserProperty() Assert.AreEqual("Robbie Robot", _client.User); } + [Test] + public void UserInfoProperty() + { + RaygunIdentifierMessage user = new RaygunIdentifierMessage("Robbie Robot"); + _client.UserInfo = user; + Assert.AreSame(user, _client.UserInfo); + } + + [Test] + public void MessageWithNoUser() + { + RaygunMessage message = _client.ExposeBuildMessage(_exception); + Assert.IsNull(message.Details.User); + } + [Test] public void MessageWithUser() { @@ -46,6 +67,40 @@ public void MessageWithUser() Assert.AreEqual("Robbie Robot", message.Details.User.Identifier); } + [Test] + public void MessageWithUserInfo() + { + RaygunIdentifierMessage user = new RaygunIdentifierMessage("Robbie Robot") { IsAnonymous = true }; + _client.UserInfo = user; + + RaygunMessage message = _client.ExposeBuildMessage(_exception); + Assert.AreEqual("Robbie Robot", message.Details.User.Identifier); + Assert.IsTrue(message.Details.User.IsAnonymous); + } + + [Test] + public void UserInfoTrumpsUser() + { + RaygunIdentifierMessage user = new RaygunIdentifierMessage("Robbie Robot") { IsAnonymous = true }; + _client.UserInfo = user; + _client.User = "Not Robbie Robot"; + + RaygunMessage message = _client.ExposeBuildMessage(_exception); + Assert.AreEqual("Robbie Robot", message.Details.User.Identifier); + Assert.IsTrue(message.Details.User.IsAnonymous); + } + + [Test] + public void IsAnonymousDefault() + { + RaygunIdentifierMessage user = new RaygunIdentifierMessage("Robbie Robot"); + Assert.IsFalse(user.IsAnonymous); + + _client.User = "Robbie Robot"; + RaygunMessage message = _client.ExposeBuildMessage(_exception); + Assert.IsFalse(message.Details.User.IsAnonymous); + } + // Application version tests [Test] diff --git a/Mindscape.Raygun4Net2/RaygunClient.cs b/Mindscape.Raygun4Net2/RaygunClient.cs index cd9495bd..d53eabcd 100644 --- a/Mindscape.Raygun4Net2/RaygunClient.cs +++ b/Mindscape.Raygun4Net2/RaygunClient.cs @@ -88,6 +88,11 @@ protected bool OnSendingMessage(RaygunMessage raygunMessage) /// </summary> public string User { get; set; } + /// <summary> + /// Gets or sets information about the user including the identity string. + /// </summary> + public RaygunIdentifierMessage UserInfo { get; set; } + /// <summary> /// Gets or sets a custom application version identifier for all error messages sent to the Raygun.io endpoint. /// </summary> @@ -245,7 +250,7 @@ protected RaygunMessage BuildMessage(Exception exception, IList<string> tags, ID .SetVersion(ApplicationVersion) .SetTags(tags) .SetUserCustomData(userCustomData) - .SetUser(User) + .SetUser(UserInfo ?? (!String.IsNullOrEmpty(User) ? new RaygunIdentifierMessage(User) : null)) .Build(); return message; } diff --git a/Mindscape.Raygun4Net2/RaygunMessageBuilder.cs b/Mindscape.Raygun4Net2/RaygunMessageBuilder.cs index 9c05bfa5..4a7275a7 100644 --- a/Mindscape.Raygun4Net2/RaygunMessageBuilder.cs +++ b/Mindscape.Raygun4Net2/RaygunMessageBuilder.cs @@ -97,12 +97,9 @@ public IRaygunMessageBuilder SetTags(IList<string> tags) return this; } - public IRaygunMessageBuilder SetUser(string user) + public IRaygunMessageBuilder SetUser(RaygunIdentifierMessage user) { - if (user != null && user.Length > 0) - { - _raygunMessage.Details.User = new RaygunIdentifierMessage(user); - } + _raygunMessage.Details.User = user; return this; } From 87e118e9311c530a7e7e122a5592eca6fd685098 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Wed, 25 Jun 2014 16:59:42 +1200 Subject: [PATCH 23/28] Added user IsAnonymous flag for .Net 3.5 and 4.0. --- .../RaygunClientTests.cs | 55 +++++++++++++++++++ Mindscape.Raygun4Net/RaygunClient.cs | 7 ++- Mindscape.Raygun4Net/RaygunMessageBuilder.cs | 7 +-- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/Mindscape.Raygun4Net.Tests/RaygunClientTests.cs b/Mindscape.Raygun4Net.Tests/RaygunClientTests.cs index fde7d842..e7742971 100644 --- a/Mindscape.Raygun4Net.Tests/RaygunClientTests.cs +++ b/Mindscape.Raygun4Net.Tests/RaygunClientTests.cs @@ -28,6 +28,12 @@ public void DefaultUser() Assert.IsNull(_client.User); } + [Test] + public void DefaultUserInfo() + { + Assert.IsNull(_client.UserInfo); + } + [Test] public void UserProperty() { @@ -35,6 +41,21 @@ public void UserProperty() Assert.AreEqual("Robbie Robot", _client.User); } + [Test] + public void UserInfoProperty() + { + RaygunIdentifierMessage user = new RaygunIdentifierMessage("Robbie Robot"); + _client.UserInfo = user; + Assert.AreSame(user, _client.UserInfo); + } + + [Test] + public void MessageWithNoUser() + { + RaygunMessage message = _client.ExposeBuildMessage(_exception); + Assert.IsNull(message.Details.User); + } + [Test] public void MessageWithUser() { @@ -44,6 +65,40 @@ public void MessageWithUser() Assert.AreEqual("Robbie Robot", message.Details.User.Identifier); } + [Test] + public void MessageWithUserInfo() + { + RaygunIdentifierMessage user = new RaygunIdentifierMessage("Robbie Robot") { IsAnonymous = true }; + _client.UserInfo = user; + + RaygunMessage message = _client.ExposeBuildMessage(_exception); + Assert.AreEqual("Robbie Robot", message.Details.User.Identifier); + Assert.IsTrue(message.Details.User.IsAnonymous); + } + + [Test] + public void UserInfoTrumpsUser() + { + RaygunIdentifierMessage user = new RaygunIdentifierMessage("Robbie Robot") { IsAnonymous = true }; + _client.UserInfo = user; + _client.User = "Not Robbie Robot"; + + RaygunMessage message = _client.ExposeBuildMessage(_exception); + Assert.AreEqual("Robbie Robot", message.Details.User.Identifier); + Assert.IsTrue(message.Details.User.IsAnonymous); + } + + [Test] + public void IsAnonymousDefault() + { + RaygunIdentifierMessage user = new RaygunIdentifierMessage("Robbie Robot"); + Assert.IsFalse(user.IsAnonymous); + + _client.User = "Robbie Robot"; + RaygunMessage message = _client.ExposeBuildMessage(_exception); + Assert.IsFalse(message.Details.User.IsAnonymous); + } + // Application version tests [Test] diff --git a/Mindscape.Raygun4Net/RaygunClient.cs b/Mindscape.Raygun4Net/RaygunClient.cs index 846ce6d7..2469262a 100644 --- a/Mindscape.Raygun4Net/RaygunClient.cs +++ b/Mindscape.Raygun4Net/RaygunClient.cs @@ -92,6 +92,11 @@ protected bool OnSendingMessage(RaygunMessage raygunMessage) /// </summary> public string User { get; set; } + /// <summary> + /// Gets or sets information about the user including the identity string. + /// </summary> + public RaygunIdentifierMessage UserInfo { get; set; } + /// <summary> /// Gets or sets the username/password credentials which are used to authenticate with the system default Proxy server, if one is set /// and requires credentials. @@ -278,7 +283,7 @@ protected RaygunMessage BuildMessage(Exception exception, IList<string> tags, ID .SetVersion(ApplicationVersion) .SetTags(tags) .SetUserCustomData(userCustomData) - .SetUser(User) + .SetUser(UserInfo ?? (!String.IsNullOrEmpty(User) ? new RaygunIdentifierMessage(User) : null)) .Build(); return message; } diff --git a/Mindscape.Raygun4Net/RaygunMessageBuilder.cs b/Mindscape.Raygun4Net/RaygunMessageBuilder.cs index 04b9b582..9dfefd1c 100644 --- a/Mindscape.Raygun4Net/RaygunMessageBuilder.cs +++ b/Mindscape.Raygun4Net/RaygunMessageBuilder.cs @@ -110,12 +110,9 @@ public IRaygunMessageBuilder SetTags(IList<string> tags) return this; } - public IRaygunMessageBuilder SetUser(string user) + public IRaygunMessageBuilder SetUser(RaygunIdentifierMessage user) { - if (user != null && user.Length > 0) - { - _raygunMessage.Details.User = new RaygunIdentifierMessage(user); - } + _raygunMessage.Details.User = user; return this; } From 9bd3d633cecc09f7c17b72f50884526e49a66de5 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Wed, 25 Jun 2014 17:03:00 +1200 Subject: [PATCH 24/28] Added user IsAnonymous flag for Xamarin.Android. --- Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs | 7 ++++++- .../RaygunMessageBuilder.cs | 7 ++----- .../Resources/Resource.Designer.cs | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs b/Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs index 0ea0c7ef..34c4d579 100644 --- a/Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs +++ b/Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs @@ -56,6 +56,11 @@ private bool ValidateApiKey() /// </summary> public string User { get; set; } + /// <summary> + /// Gets or sets information about the user including the identity string. + /// </summary> + public RaygunIdentifierMessage UserInfo { get; set; } + /// <summary> /// Gets or sets a custom application version identifier for all error messages sent to the Raygun.io endpoint. /// </summary> @@ -231,7 +236,7 @@ internal RaygunMessage BuildMessage(Exception exception, IList<string> tags, IDi .SetVersion(ApplicationVersion) .SetTags(tags) .SetUserCustomData(userCustomData) - .SetUser(User) + .SetUser(UserInfo ?? (!String.IsNullOrEmpty(User) ? new RaygunIdentifierMessage(User) : null)) .Build(); return message; } diff --git a/Mindscape.Raygun4Net.Xamarin.Android/RaygunMessageBuilder.cs b/Mindscape.Raygun4Net.Xamarin.Android/RaygunMessageBuilder.cs index f4ea6729..2a298dd2 100644 --- a/Mindscape.Raygun4Net.Xamarin.Android/RaygunMessageBuilder.cs +++ b/Mindscape.Raygun4Net.Xamarin.Android/RaygunMessageBuilder.cs @@ -83,12 +83,9 @@ public IRaygunMessageBuilder SetTags(IList<string> tags) return this; } - public IRaygunMessageBuilder SetUser(string user) + public IRaygunMessageBuilder SetUser(RaygunIdentifierMessage user) { - if (user != null && user.Length > 0) - { - _raygunMessage.Details.User = new RaygunIdentifierMessage(user); - } + _raygunMessage.Details.User = user; return this; } diff --git a/Mindscape.Raygun4Net.Xamarin.Android/Resources/Resource.Designer.cs b/Mindscape.Raygun4Net.Xamarin.Android/Resources/Resource.Designer.cs index 0a3a6258..bd0db274 100644 --- a/Mindscape.Raygun4Net.Xamarin.Android/Resources/Resource.Designer.cs +++ b/Mindscape.Raygun4Net.Xamarin.Android/Resources/Resource.Designer.cs @@ -2,7 +2,7 @@ //------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. -// Runtime Version:4.0.30319.18408 +// Runtime Version:4.0.30319.18444 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. From 7396e6342b6b8185d2a719cb7482ec8310a47e91 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Wed, 25 Jun 2014 17:06:29 +1200 Subject: [PATCH 25/28] Added user IsAnonymous flag for Windows Phone. --- Mindscape.Raygun4Net.WindowsPhone/RaygunClient.cs | 7 ++++++- Mindscape.Raygun4Net.WindowsPhone/RaygunMessageBuilder.cs | 7 ++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Mindscape.Raygun4Net.WindowsPhone/RaygunClient.cs b/Mindscape.Raygun4Net.WindowsPhone/RaygunClient.cs index 789ceb32..010e367e 100644 --- a/Mindscape.Raygun4Net.WindowsPhone/RaygunClient.cs +++ b/Mindscape.Raygun4Net.WindowsPhone/RaygunClient.cs @@ -68,6 +68,11 @@ private bool ValidateApiKey() /// </summary> public string User { get; set; } + /// <summary> + /// Gets or sets information about the user including the identity string. + /// </summary> + public RaygunIdentifierMessage UserInfo { get; set; } + /// <summary> /// Gets or sets a custom application version identifier for all error messages sent to the Raygun.io endpoint. /// </summary> @@ -492,7 +497,7 @@ private RaygunMessage BuildMessage(Exception exception, IList<string> tags, IDic .SetVersion(version) .SetTags(tags) .SetUserCustomData(userCustomData) - .SetUser(User) + .SetUser(UserInfo ?? (!String.IsNullOrEmpty(User) ? new RaygunIdentifierMessage(User) : null)) .Build(); return message; diff --git a/Mindscape.Raygun4Net.WindowsPhone/RaygunMessageBuilder.cs b/Mindscape.Raygun4Net.WindowsPhone/RaygunMessageBuilder.cs index b5fe12f6..87e9e593 100644 --- a/Mindscape.Raygun4Net.WindowsPhone/RaygunMessageBuilder.cs +++ b/Mindscape.Raygun4Net.WindowsPhone/RaygunMessageBuilder.cs @@ -82,12 +82,9 @@ public IRaygunMessageBuilder SetTags(IList<string> tags) return this; } - public IRaygunMessageBuilder SetUser(string user) + public IRaygunMessageBuilder SetUser(RaygunIdentifierMessage user) { - if (user != null && user.Length > 0) - { - _raygunMessage.Details.User = new RaygunIdentifierMessage(user); - } + _raygunMessage.Details.User = user; return this; } From 391faf6c2ec0966f896d4052a9a654d380d3e5a5 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Wed, 25 Jun 2014 17:08:59 +1200 Subject: [PATCH 26/28] Added user IsAnonymous flag for Xamarin.iOS --- Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs | 7 ++++++- Mindscape.Raygun4Net.Xamarin.iOS/RaygunMessageBuilder.cs | 7 ++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs b/Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs index e27aefdb..3df18df5 100644 --- a/Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs +++ b/Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs @@ -53,6 +53,11 @@ private bool ValidateApiKey() /// </summary> public string User { get; set; } + /// <summary> + /// Gets or sets information about the user including the identity string. + /// </summary> + public RaygunIdentifierMessage UserInfo { get; set; } + /// <summary> /// Gets or sets a custom application version identifier for all error messages sent to the Raygun.io endpoint. /// </summary> @@ -222,7 +227,7 @@ internal RaygunMessage BuildMessage(Exception exception, IList<string> tags, IDi .SetVersion(ApplicationVersion) .SetTags(tags) .SetUserCustomData(userCustomData) - .SetUser(User) + .SetUser(UserInfo ?? (!String.IsNullOrEmpty(User) ? new RaygunIdentifierMessage(User) : null)) .Build(); return message; diff --git a/Mindscape.Raygun4Net.Xamarin.iOS/RaygunMessageBuilder.cs b/Mindscape.Raygun4Net.Xamarin.iOS/RaygunMessageBuilder.cs index 661d711c..20200485 100644 --- a/Mindscape.Raygun4Net.Xamarin.iOS/RaygunMessageBuilder.cs +++ b/Mindscape.Raygun4Net.Xamarin.iOS/RaygunMessageBuilder.cs @@ -82,12 +82,9 @@ public IRaygunMessageBuilder SetTags(IList<string> tags) return this; } - public IRaygunMessageBuilder SetUser(string user) + public IRaygunMessageBuilder SetUser(RaygunIdentifierMessage user) { - if (user != null && user.Length > 0) - { - _raygunMessage.Details.User = new RaygunIdentifierMessage(user); - } + _raygunMessage.Details.User = user; return this; } From afabf9fe70a0ea82b85a30991e573e305aa91243 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Wed, 25 Jun 2014 17:11:03 +1200 Subject: [PATCH 27/28] Added user IsAnonymous flag for WinRT --- Mindscape.Raygun4Net.WinRT/RaygunClient.cs | 7 ++++++- Mindscape.Raygun4Net.WinRT/RaygunMessageBuilder.cs | 7 ++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Mindscape.Raygun4Net.WinRT/RaygunClient.cs b/Mindscape.Raygun4Net.WinRT/RaygunClient.cs index 8ba5d30d..e3d3956d 100644 --- a/Mindscape.Raygun4Net.WinRT/RaygunClient.cs +++ b/Mindscape.Raygun4Net.WinRT/RaygunClient.cs @@ -54,6 +54,11 @@ private bool ValidateApiKey() /// </summary> public string User { get; set; } + /// <summary> + /// Gets or sets information about the user including the identity string. + /// </summary> + public RaygunIdentifierMessage UserInfo { get; set; } + /// <summary> /// Gets or sets a custom application version identifier for all error messages sent to the Raygun.io endpoint. /// </summary> @@ -187,7 +192,7 @@ private RaygunMessage BuildMessage(Exception exception, IList<string> tags, IDic .SetVersion(ApplicationVersion) .SetTags(tags) .SetUserCustomData(userCustomData) - .SetUser(User) + .SetUser(UserInfo ?? (!String.IsNullOrEmpty(User) ? new RaygunIdentifierMessage(User) : null)) .Build(); return message; diff --git a/Mindscape.Raygun4Net.WinRT/RaygunMessageBuilder.cs b/Mindscape.Raygun4Net.WinRT/RaygunMessageBuilder.cs index fe1f8aa0..ba3ffec1 100644 --- a/Mindscape.Raygun4Net.WinRT/RaygunMessageBuilder.cs +++ b/Mindscape.Raygun4Net.WinRT/RaygunMessageBuilder.cs @@ -83,12 +83,9 @@ public IRaygunMessageBuilder SetTags(IList<string> tags) return this; } - public IRaygunMessageBuilder SetUser(string user) + public IRaygunMessageBuilder SetUser(RaygunIdentifierMessage user) { - if (!String.IsNullOrEmpty(user)) - { - _raygunMessage.Details.User = new RaygunIdentifierMessage(user); - } + _raygunMessage.Details.User = user; return this; } From 7e543d161132a3aa2f088568b697d1bb287508b0 Mon Sep 17 00:00:00 2001 From: Jason Fauchelle <jason@mindscape.co.nz> Date: Thu, 26 Jun 2014 16:25:11 +1200 Subject: [PATCH 28/28] Removed using System.Text.RegularExpressions --- Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs | 1 - Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs | 1 - Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs | 1 - 3 files changed, 3 deletions(-) diff --git a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs index 24c29866..e387a50c 100644 --- a/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net/Messages/RaygunRequestMessage.cs @@ -4,7 +4,6 @@ using System.Collections.Specialized; using System.IO; using System.Linq; -using System.Text.RegularExpressions; using System.Web; namespace Mindscape.Raygun4Net.Messages diff --git a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs index f2420c09..bc7442a2 100644 --- a/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs +++ b/Mindscape.Raygun4Net/RaygunRequestMessageOptions.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Text; -using System.Text.RegularExpressions; namespace Mindscape.Raygun4Net { diff --git a/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs b/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs index d71d635f..23cbfc8c 100644 --- a/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs +++ b/Mindscape.Raygun4Net2/Messages/RaygunRequestMessage.cs @@ -4,7 +4,6 @@ using System.Collections.Specialized; using System.Diagnostics; using System.IO; -using System.Text.RegularExpressions; using System.Web; namespace Mindscape.Raygun4Net.Messages