Update UrlUtility.cs

Add UrlUtility.Combine method
pull/1/head
a.bozhenov 5 years ago
parent 2d3cf518fa
commit 95492fc74f

@ -1,5 +1,7 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace ZeroLevel.Services.Web namespace ZeroLevel.Services.Web
{ {
@ -60,6 +62,78 @@ namespace ZeroLevel.Services.Web
return str == null ? null : UrlEncodeUnicodeStringToStringInternal(str, false); return str == null ? null : UrlEncodeUnicodeStringToStringInternal(str, false);
} }
/// <summary>
/// https://github.com/tmenier/Flurl
/// </summary>
public static string Combine(params string[] parts)
{
if (parts == null)
throw new ArgumentNullException(nameof(parts));
string result = "";
bool inQuery = false, inFragment = false;
string CombineEnsureSingleSeparator(string a, string b, char separator)
{
if (string.IsNullOrEmpty(a)) return b;
if (string.IsNullOrEmpty(b)) return a;
return a.TrimEnd(separator) + separator + b.TrimStart(separator);
}
foreach (var part in parts)
{
if (string.IsNullOrEmpty(part))
continue;
if (result.EndsWith("?") || part.StartsWith("?"))
result = CombineEnsureSingleSeparator(result, part, '?');
else if (result.EndsWith("#") || part.StartsWith("#"))
result = CombineEnsureSingleSeparator(result, part, '#');
else if (inFragment)
result += part;
else if (inQuery)
result = CombineEnsureSingleSeparator(result, part, '&');
else
result = CombineEnsureSingleSeparator(result, part, '/');
if (part.Contains("#"))
{
inQuery = false;
inFragment = true;
}
else if (!inFragment && part.Contains("?"))
{
inQuery = true;
}
}
return EncodeIllegalCharacters(result);
}
/// <summary>
/// https://github.com/tmenier/Flurl
/// </summary>
public static string EncodeIllegalCharacters(string s, bool encodeSpaceAsPlus = false)
{
if (string.IsNullOrEmpty(s))
return s;
if (encodeSpaceAsPlus)
s = s.Replace(" ", "+");
// Uri.EscapeUriString mostly does what we want - encodes illegal characters only - but it has a quirk
// in that % isn't illegal if it's the start of a %-encoded sequence https://stackoverflow.com/a/47636037/62600
// no % characters, so avoid the regex overhead
if (!s.Contains("%"))
return Uri.EscapeUriString(s);
// pick out all %-hex-hex matches and avoid double-encoding
return Regex.Replace(s, "(.*?)((%[0-9A-Fa-f]{2})|$)", c => {
var a = c.Groups[1].Value; // group 1 is a sequence with no %-encoding - encode illegal characters
var b = c.Groups[2].Value; // group 2 is a valid 3-character %-encoded sequence - leave it alone!
return Uri.EscapeUriString(a) + b;
});
}
private static string UrlEncodeUnicodeStringToStringInternal(string s, bool ignoreAscii) private static string UrlEncodeUnicodeStringToStringInternal(string s, bool ignoreAscii)
{ {
var l = s.Length; var l = s.Length;

Loading…
Cancel
Save

Powered by TurnKey Linux.