Skip to content

Commit

Permalink
updated browser filters rules to be more flexible:
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
lucasnz committed Sep 6, 2021
1 parent af9b0b1 commit da145a4
Show file tree
Hide file tree
Showing 9 changed files with 426 additions and 182 deletions.
22 changes: 17 additions & 5 deletions BrowserSelect/Form1.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using BrowserSelect.Properties;
using Newtonsoft.Json;
using SHDocVw;

namespace BrowserSelect
Expand Down Expand Up @@ -118,12 +120,22 @@ public void add_rule(Browser b, string pattern)

private void save_rule(string pattern, Browser b)
{
// save a rule and save app settings
Settings.Default.AutoBrowser.Add((new AutoMatchRule()
// add a rule and save app settings
DataTable rules;
if (Settings.Default.Rules != null && Settings.Default.Rules != "")
rules = (DataTable)JsonConvert.DeserializeObject(Settings.Default.Rules, (typeof(DataTable)));
else
{
Pattern = pattern,
Browser = b.name
}).ToString());
rules = new DataTable();
rules.Columns.Add("Type");
rules.Columns.Add("Match");
rules.Columns.Add("Pattern");
rules.Columns.Add("Browser");
}
if (pattern.StartsWith("*."))
pattern = pattern.Substring(2);
rules.Rows.Add("Ends With", "Domain", pattern, b.name);
Settings.Default.Rules = JsonConvert.SerializeObject(rules);
Settings.Default.Save();
}

Expand Down
161 changes: 71 additions & 90 deletions BrowserSelect/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
using System.Web;
using System.Net;
using System.Threading;
using Newtonsoft.Json;
using System.Data;

namespace BrowserSelect
{
Expand All @@ -31,8 +33,6 @@ static class Program
[STAThread]
static void Main(string[] args)
{
// fix #28
LeaveDotsAndSlashesEscaped();
// to prevent loss of settings when on update
if (Settings.Default.UpdateSettings)
{
Expand Down Expand Up @@ -94,32 +94,9 @@ static void Main(string[] args)
uri = UriFollowRedirects(uri);
url = uri.AbsoluteUri;

foreach (var sr in Settings.Default.AutoBrowser.Cast<string>()
// maybe i should use a better way to split the pattern and browser name ?
.Select(x => x.Split(new[] { "[#!][$~][?_]" }, StringSplitOptions.None))
// to make sure * doesn't match when non-* rules exist.
.OrderBy(x => ((x[0].Contains("*")) ? 1 : 0) + (x[0] == "*" ? 1 : 0)))
{
var pattern = sr[0];
var browser = sr[1];

// matching the domain to pattern
if (DoesDomainMatchPattern(uri.Host, pattern))
{
// ignore the display browser select entry to prevent app running itself
if (browser != "display BrowserSelect")
{
//todo: handle the case if browser is not found (e.g. imported settings or uninstalled browser)
Form1.open_url((Browser)browser);
return;
}
else
{
// simply break the loop to let the app display selection dialogue
break;
}
}
}
//if we loaded the browser finish execution here...
if (load_browser(uri))
return;
}

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

private static Boolean load_browser(Uri uri)
{
if (Settings.Default.Rules != null && Settings.Default.Rules != "")
{
DataTable rules = (DataTable)JsonConvert.DeserializeObject(Settings.Default.Rules, (typeof(DataTable)));
foreach (DataRow rule in rules.Rows)
{
Boolean rule_match = false;
string match_type = (string)rule["Type"];
string match = (string)rule["Match"];
string pattern = (string)rule["Pattern"];

string test_uri = "";
if (match == "Domain")
test_uri = uri.Host;
else if (match == "URL Path")
test_uri = uri.PathAndQuery;
else if (match == "Full URL")
test_uri = uri.AbsoluteUri;

switch (match_type)
{
case "Ends With":
if (test_uri.EndsWith(pattern, StringComparison.OrdinalIgnoreCase))
rule_match = true;
break;
case "Starts With":
if (test_uri.StartsWith(pattern, StringComparison.OrdinalIgnoreCase))
rule_match = true;
break;
case "Contains":
if (test_uri.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) >= 0)
rule_match = true;
break;
case "Matches":
if (test_uri.Equals(pattern, StringComparison.OrdinalIgnoreCase))
rule_match = true;
break;
case "RegEx":
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
if (regex.IsMatch(test_uri))
rule_match = true;
break;
}

if (rule_match)
{
System.Diagnostics.Debug.WriteLine(test_uri + " " + match_type + " " + pattern);
string browser = (string)rule["Browser"];
if (browser != "display BrowserSelect")
Form1.open_url((Browser)browser);
return true;
}
}
}
if (Settings.Default.DefaultBrowser != null &&
Settings.Default.DefaultBrowser != "" &&
Settings.Default.DefaultBrowser != "display BrowserSelect")
{
Form1.open_url((Browser)Settings.Default.DefaultBrowser);
return true;
}
return false;
}

// from : http://stackoverflow.com/a/250400/1461004
public static double time()
{
Expand Down Expand Up @@ -191,68 +233,6 @@ public static string ProgramFilesx86()
return Environment.GetEnvironmentVariable("ProgramFiles");
}


/// <summary>
/// Checks if a wildcard string matches a domain
/// taken from http://madskristensen.net/post/wildcard-search-for-domains-in-c
/// </summary>
public static bool DoesDomainMatchPattern(string domain, string domainToCheck)
{
if (domainToCheck.Contains("*"))
{
string checkDomain = domainToCheck;
if (checkDomain.StartsWith("*."))
checkDomain = "*" + checkDomain.Substring(2, checkDomain.Length - 2);
return DoesWildcardMatch(domain, checkDomain);
}
else
{
return domainToCheck.Equals(domain, StringComparison.OrdinalIgnoreCase);
}
}
/// <summary>
/// Performs a wildcard (*) search on any string.
/// </summary>
public static bool DoesWildcardMatch(string originalString, string searchString)
{
if (!searchString.StartsWith("*"))
{
int stop = searchString.IndexOf('*');
if (!originalString.StartsWith(searchString.Substring(0, stop)))
return false;
}
if (!searchString.EndsWith("*"))
{
int start = searchString.LastIndexOf('*') + 1;
if (!originalString.EndsWith(searchString.Substring(start, searchString.Length - start)))
return false;
}
Regex regex = new Regex(searchString.Replace(@".", @"\.").Replace(@"*", @".*"));
return regex.IsMatch(originalString);
}

// https://stackoverflow.com/a/7202560/1461004
private static void LeaveDotsAndSlashesEscaped()
{
var getSyntaxMethod =
typeof(UriParser).GetMethod("GetSyntax", BindingFlags.Static | BindingFlags.NonPublic);
if (getSyntaxMethod == null)
{
throw new MissingMethodException("UriParser", "GetSyntax");
}

var uriParser = getSyntaxMethod.Invoke(null, new object[] { "http" });

var setUpdatableFlagsMethod =
uriParser.GetType().GetMethod("SetUpdatableFlags", BindingFlags.Instance | BindingFlags.NonPublic);
if (setUpdatableFlagsMethod == null)
{
throw new MissingMethodException("UriParser", "SetUpdatableFlags");
}

setUpdatableFlagsMethod.Invoke(uriParser, new object[] { 0 });
}

private static Uri UriExpander(Uri uri)
{
List<string> enabled_url_expanders = new List<string>();
Expand Down Expand Up @@ -280,6 +260,7 @@ private static Uri UriExpander(Uri uri)

return uri;
}

private static Uri UriFollowRedirects(Uri uri, int num_redirects = 0)
{
int max_redirects = 20;
Expand Down
24 changes: 24 additions & 0 deletions BrowserSelect/Properties/Settings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions BrowserSelect/Properties/Settings.settings
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,11 @@
<Setting Name="URLProcessors" Type="System.Collections.Specialized.StringCollection" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="DefaultBrowser" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="Rules" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>
6 changes: 6 additions & 0 deletions BrowserSelect/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
<setting name="ExpandUrl" serializeAs="String">
<value>Never</value>
</setting>
<setting name="DefaultBrowser" serializeAs="String">
<value />
</setting>
<setting name="Rules" serializeAs="String">
<value />
</setting>
</BrowserSelect.Properties.Settings>
</userSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/></startup></configuration>
Loading

0 comments on commit da145a4

Please sign in to comment.