1
using System;
2
using System.Linq;
3

4
namespace TurnerSoftware.RobotsExclusionTools.Helpers
5
{
6
	public static class PathComparisonUtility
7
	{
8
		public static bool IsAllowed(SiteAccessEntry accessEntry, Uri requestUri)
9 1
		{
10 1
			var requestPath = requestUri.PathAndQuery;
11

12
			//Robots file is always unrestricted
13 1
			if (requestUri.LocalPath == "/robots.txt")
14 1
			{
15 1
				return true;
16
			}
17

18
			//If no entry is defined, the robot is allowed access by default
19 1
			if (accessEntry == null)
20 1
			{
21 1
				return true;
22
			}
23

24 1
			foreach (var rule in accessEntry.PathRules)
25 1
			{
26 1
				if (rule.RuleType == PathRuleType.Disallow && rule.Path == string.Empty)
27 1
				{
28 1
					return true;
29
				}
30 1
				else if (PathMatch(rule.Path, requestPath, StringComparison.InvariantCulture))
31 1
				{
32 1
					return rule.RuleType == PathRuleType.Allow;
33
				}
34 1
			}
35

36 1
			return true;
37 1
		}
38

39
		public static bool PathMatch(string sourceRecord, string uriPath, StringComparison comparison)
40 1
		{
41 1
			var sourcePieces = sourceRecord.Split(new[] { '*' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
42 1
			var lastPiece = sourcePieces.LastOrDefault();
43 1
			var mustMatchToEnd = false;
44 1
			var mustMatchToStart = true;
45

46 1
			if (lastPiece != null && lastPiece.EndsWith("$"))
47 1
			{
48
				//Remove the last dollar sign from the last piece
49 1
				lastPiece = lastPiece.Substring(0, lastPiece.Length - 1);
50 1
				sourcePieces[sourcePieces.Length - 1] = lastPiece;
51 1
				mustMatchToEnd = true;
52 1
			}
53

54 1
			if (sourceRecord.StartsWith("*"))
55 1
			{
56 1
				mustMatchToStart = false;
57 1
			}
58

59 1
			var offsetPosition = 0;
60

61 1
			for (int i = 0, l = sourcePieces.Length; i < l; i++)
62 1
			{
63 1
				var piece = sourcePieces[i];
64 1
				var indexPosition = uriPath.IndexOf(piece, offsetPosition, comparison);
65

66 1
				if (mustMatchToStart && offsetPosition == 0 && indexPosition > 0)
67 1
				{
68 1
					return false;
69
				}
70

71 1
				if (indexPosition >= offsetPosition)
72 1
				{
73 1
					offsetPosition = piece.Length;
74 1
				}
75
				else
76 1
				{
77 1
					return false;
78
				}
79

80 1
			}
81

82 1
			if (mustMatchToEnd)
83 1
			{
84 1
				var endOffset = uriPath.Length - lastPiece.Length;
85 1
				if (uriPath.IndexOf(lastPiece, endOffset, comparison) == -1)
86 1
				{
87 1
					return false;
88
				}
89 1
			}
90

91 1
			return true;
92 1
		}
93
	}
94
}

Read our documentation on viewing source code .

Loading