Skip to content

Commit da145a4

Browse files
committed
updated browser filters rules to be more flexible:
* Added ability to choose comparitor (Ends with, contains, regex, etc) * Added ability to compare domain, HTTP path, or full URL * Changed rules to be stored in Json format * Added auto import and conversion from old rule format Removed LeaveDotsAndSlashesEscaped() doesn't seem to be required any more.
1 parent af9b0b1 commit da145a4

9 files changed

+426
-182
lines changed

BrowserSelect/Form1.cs

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Data;
34
using System.Diagnostics;
45
using System.Drawing;
56
using System.Linq;
67
using System.Windows.Forms;
78
using BrowserSelect.Properties;
9+
using Newtonsoft.Json;
810
using SHDocVw;
911

1012
namespace BrowserSelect
@@ -118,12 +120,22 @@ public void add_rule(Browser b, string pattern)
118120

119121
private void save_rule(string pattern, Browser b)
120122
{
121-
// save a rule and save app settings
122-
Settings.Default.AutoBrowser.Add((new AutoMatchRule()
123+
// add a rule and save app settings
124+
DataTable rules;
125+
if (Settings.Default.Rules != null && Settings.Default.Rules != "")
126+
rules = (DataTable)JsonConvert.DeserializeObject(Settings.Default.Rules, (typeof(DataTable)));
127+
else
123128
{
124-
Pattern = pattern,
125-
Browser = b.name
126-
}).ToString());
129+
rules = new DataTable();
130+
rules.Columns.Add("Type");
131+
rules.Columns.Add("Match");
132+
rules.Columns.Add("Pattern");
133+
rules.Columns.Add("Browser");
134+
}
135+
if (pattern.StartsWith("*."))
136+
pattern = pattern.Substring(2);
137+
rules.Rows.Add("Ends With", "Domain", pattern, b.name);
138+
Settings.Default.Rules = JsonConvert.SerializeObject(rules);
127139
Settings.Default.Save();
128140
}
129141

BrowserSelect/Program.cs

+71-90
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
using System.Web;
1111
using System.Net;
1212
using System.Threading;
13+
using Newtonsoft.Json;
14+
using System.Data;
1315

1416
namespace BrowserSelect
1517
{
@@ -31,8 +33,6 @@ static class Program
3133
[STAThread]
3234
static void Main(string[] args)
3335
{
34-
// fix #28
35-
LeaveDotsAndSlashesEscaped();
3636
// to prevent loss of settings when on update
3737
if (Settings.Default.UpdateSettings)
3838
{
@@ -94,32 +94,9 @@ static void Main(string[] args)
9494
uri = UriFollowRedirects(uri);
9595
url = uri.AbsoluteUri;
9696

97-
foreach (var sr in Settings.Default.AutoBrowser.Cast<string>()
98-
// maybe i should use a better way to split the pattern and browser name ?
99-
.Select(x => x.Split(new[] { "[#!][$~][?_]" }, StringSplitOptions.None))
100-
// to make sure * doesn't match when non-* rules exist.
101-
.OrderBy(x => ((x[0].Contains("*")) ? 1 : 0) + (x[0] == "*" ? 1 : 0)))
102-
{
103-
var pattern = sr[0];
104-
var browser = sr[1];
105-
106-
// matching the domain to pattern
107-
if (DoesDomainMatchPattern(uri.Host, pattern))
108-
{
109-
// ignore the display browser select entry to prevent app running itself
110-
if (browser != "display BrowserSelect")
111-
{
112-
//todo: handle the case if browser is not found (e.g. imported settings or uninstalled browser)
113-
Form1.open_url((Browser)browser);
114-
return;
115-
}
116-
else
117-
{
118-
// simply break the loop to let the app display selection dialogue
119-
break;
120-
}
121-
}
122-
}
97+
//if we loaded the browser finish execution here...
98+
if (load_browser(uri))
99+
return;
123100
}
124101

125102
// display main form
@@ -131,6 +108,71 @@ static void Main(string[] args)
131108
Application.Run(new frm_settings());
132109
}
133110

111+
private static Boolean load_browser(Uri uri)
112+
{
113+
if (Settings.Default.Rules != null && Settings.Default.Rules != "")
114+
{
115+
DataTable rules = (DataTable)JsonConvert.DeserializeObject(Settings.Default.Rules, (typeof(DataTable)));
116+
foreach (DataRow rule in rules.Rows)
117+
{
118+
Boolean rule_match = false;
119+
string match_type = (string)rule["Type"];
120+
string match = (string)rule["Match"];
121+
string pattern = (string)rule["Pattern"];
122+
123+
string test_uri = "";
124+
if (match == "Domain")
125+
test_uri = uri.Host;
126+
else if (match == "URL Path")
127+
test_uri = uri.PathAndQuery;
128+
else if (match == "Full URL")
129+
test_uri = uri.AbsoluteUri;
130+
131+
switch (match_type)
132+
{
133+
case "Ends With":
134+
if (test_uri.EndsWith(pattern, StringComparison.OrdinalIgnoreCase))
135+
rule_match = true;
136+
break;
137+
case "Starts With":
138+
if (test_uri.StartsWith(pattern, StringComparison.OrdinalIgnoreCase))
139+
rule_match = true;
140+
break;
141+
case "Contains":
142+
if (test_uri.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) >= 0)
143+
rule_match = true;
144+
break;
145+
case "Matches":
146+
if (test_uri.Equals(pattern, StringComparison.OrdinalIgnoreCase))
147+
rule_match = true;
148+
break;
149+
case "RegEx":
150+
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
151+
if (regex.IsMatch(test_uri))
152+
rule_match = true;
153+
break;
154+
}
155+
156+
if (rule_match)
157+
{
158+
System.Diagnostics.Debug.WriteLine(test_uri + " " + match_type + " " + pattern);
159+
string browser = (string)rule["Browser"];
160+
if (browser != "display BrowserSelect")
161+
Form1.open_url((Browser)browser);
162+
return true;
163+
}
164+
}
165+
}
166+
if (Settings.Default.DefaultBrowser != null &&
167+
Settings.Default.DefaultBrowser != "" &&
168+
Settings.Default.DefaultBrowser != "display BrowserSelect")
169+
{
170+
Form1.open_url((Browser)Settings.Default.DefaultBrowser);
171+
return true;
172+
}
173+
return false;
174+
}
175+
134176
// from : http://stackoverflow.com/a/250400/1461004
135177
public static double time()
136178
{
@@ -191,68 +233,6 @@ public static string ProgramFilesx86()
191233
return Environment.GetEnvironmentVariable("ProgramFiles");
192234
}
193235

194-
195-
/// <summary>
196-
/// Checks if a wildcard string matches a domain
197-
/// taken from http://madskristensen.net/post/wildcard-search-for-domains-in-c
198-
/// </summary>
199-
public static bool DoesDomainMatchPattern(string domain, string domainToCheck)
200-
{
201-
if (domainToCheck.Contains("*"))
202-
{
203-
string checkDomain = domainToCheck;
204-
if (checkDomain.StartsWith("*."))
205-
checkDomain = "*" + checkDomain.Substring(2, checkDomain.Length - 2);
206-
return DoesWildcardMatch(domain, checkDomain);
207-
}
208-
else
209-
{
210-
return domainToCheck.Equals(domain, StringComparison.OrdinalIgnoreCase);
211-
}
212-
}
213-
/// <summary>
214-
/// Performs a wildcard (*) search on any string.
215-
/// </summary>
216-
public static bool DoesWildcardMatch(string originalString, string searchString)
217-
{
218-
if (!searchString.StartsWith("*"))
219-
{
220-
int stop = searchString.IndexOf('*');
221-
if (!originalString.StartsWith(searchString.Substring(0, stop)))
222-
return false;
223-
}
224-
if (!searchString.EndsWith("*"))
225-
{
226-
int start = searchString.LastIndexOf('*') + 1;
227-
if (!originalString.EndsWith(searchString.Substring(start, searchString.Length - start)))
228-
return false;
229-
}
230-
Regex regex = new Regex(searchString.Replace(@".", @"\.").Replace(@"*", @".*"));
231-
return regex.IsMatch(originalString);
232-
}
233-
234-
// https://stackoverflow.com/a/7202560/1461004
235-
private static void LeaveDotsAndSlashesEscaped()
236-
{
237-
var getSyntaxMethod =
238-
typeof(UriParser).GetMethod("GetSyntax", BindingFlags.Static | BindingFlags.NonPublic);
239-
if (getSyntaxMethod == null)
240-
{
241-
throw new MissingMethodException("UriParser", "GetSyntax");
242-
}
243-
244-
var uriParser = getSyntaxMethod.Invoke(null, new object[] { "http" });
245-
246-
var setUpdatableFlagsMethod =
247-
uriParser.GetType().GetMethod("SetUpdatableFlags", BindingFlags.Instance | BindingFlags.NonPublic);
248-
if (setUpdatableFlagsMethod == null)
249-
{
250-
throw new MissingMethodException("UriParser", "SetUpdatableFlags");
251-
}
252-
253-
setUpdatableFlagsMethod.Invoke(uriParser, new object[] { 0 });
254-
}
255-
256236
private static Uri UriExpander(Uri uri)
257237
{
258238
List<string> enabled_url_expanders = new List<string>();
@@ -280,6 +260,7 @@ private static Uri UriExpander(Uri uri)
280260

281261
return uri;
282262
}
263+
283264
private static Uri UriFollowRedirects(Uri uri, int num_redirects = 0)
284265
{
285266
int max_redirects = 20;

BrowserSelect/Properties/Settings.Designer.cs

+24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

BrowserSelect/Properties/Settings.settings

+6
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,11 @@
2929
<Setting Name="URLProcessors" Type="System.Collections.Specialized.StringCollection" Scope="User">
3030
<Value Profile="(Default)" />
3131
</Setting>
32+
<Setting Name="DefaultBrowser" Type="System.String" Scope="User">
33+
<Value Profile="(Default)" />
34+
</Setting>
35+
<Setting Name="Rules" Type="System.String" Scope="User">
36+
<Value Profile="(Default)" />
37+
</Setting>
3238
</Settings>
3339
</SettingsFile>

BrowserSelect/app.config

+6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
<setting name="ExpandUrl" serializeAs="String">
2323
<value>Never</value>
2424
</setting>
25+
<setting name="DefaultBrowser" serializeAs="String">
26+
<value />
27+
</setting>
28+
<setting name="Rules" serializeAs="String">
29+
<value />
30+
</setting>
2531
</BrowserSelect.Properties.Settings>
2632
</userSettings>
2733
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/></startup></configuration>

0 commit comments

Comments
 (0)