Files
w4rpservices/vendor/snowplow/referer-parser/dotnet/RefererParser/Parser.cs
2019-12-26 05:03:41 +00:00

120 lines
3.8 KiB
C#

using Newtonsoft.Json;
using RefererParser;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Web;
namespace RefererParser
{
/// <summary>
/// Parse URL referers
/// </summary>
public static class Parser
{
/// <summary>
/// Parse referer and return keyword information if available.
/// </summary>
/// <param name="refererUri">Uri to parse</param>
/// <param name="pageHost">(optional)Host name of website</param>
/// <returns></returns>
public static Referer Parse(Uri refererUri, string pageHost = "")
{
if (refererUri == null)
{
throw new NullReferenceException("No refererUri supplied!");
}
if (refererUri.Scheme.ToLower() != "http" && refererUri.Scheme.ToLower() != "https")
{
return null;
}
else
{
if (!string.IsNullOrWhiteSpace(pageHost) && string.Compare(pageHost, refererUri.Host) == 0)
{
return new Referer
{
Medium = RefererMedium.Internal
};
}
var referer = LookupReferer(refererUri.Host, refererUri.AbsolutePath, true) ??
LookupReferer(refererUri.Host, refererUri.AbsolutePath, false);
if (referer == null || !referer.Any())
{
return new Referer
{
Medium = RefererMedium.Unknown
};
}
else
{
var term = string.Empty;
var first = referer
.OrderBy(r => r.Medium)
.First();
if (first.Medium == RefererMedium.Search)
{
term = ExtractSearchTerm(refererUri, first.Parameters);
}
return new Referer
{
Medium = first.Medium,
Source = first.Name,
Term = term
};
}
}
}
private static RefererDefinition[] LookupReferer(string refererHost, string refererPath, bool includePath)
{
// Check if domain + full path matches, e.g. apollo.tv/portal/search/
var referer = includePath ? Referers.Catalog[refererHost + refererPath] : Referers.Catalog[refererHost];
// Check if domain+one-level path matches, e.g. for orange.fr/webmail/fr_FR/read.html (in our YAML it's orange.fr/webmail)
if (includePath && referer == null)
{
var pathElements = refererPath.Split('/');
if (pathElements.Length > 1)
{
referer = Referers.Catalog[refererHost + "/" + pathElements[1]];
}
}
if (referer == null)
{
int index = refererHost.IndexOf('.');
if (index >= 0)
{
referer = LookupReferer(refererHost.Substring(index + 1), refererPath, includePath);
}
}
return referer;
}
private static string ExtractSearchTerm(Uri refererUri, string[] possibleParameters)
{
var @params = HttpUtility.ParseQueryString(refererUri.Query);
foreach (string key in @params.AllKeys.Where(k => !string.IsNullOrWhiteSpace(k)))
{
if (possibleParameters.Contains(key.ToLower()))
{
return @params[key];
}
}
return null;
}
}
}