mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-15 16:13:30 +01:00
79 lines
2.8 KiB
C#
79 lines
2.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using WireMock.Types;
|
|
|
|
namespace WireMock.Util;
|
|
|
|
/// <summary>
|
|
/// Based on https://stackoverflow.com/questions/659887/get-url-parameters-from-a-string-in-net
|
|
/// </summary>
|
|
internal static class QueryStringParser
|
|
{
|
|
private static readonly Dictionary<string, WireMockList<string>> Empty = new();
|
|
|
|
public static bool TryParse(string? queryString, bool caseIgnore, [NotNullWhen(true)] out IDictionary<string, string>? nameValueCollection)
|
|
{
|
|
if (queryString is null)
|
|
{
|
|
nameValueCollection = default;
|
|
return false;
|
|
}
|
|
|
|
var parts = queryString!
|
|
.Split(new[] { "&" }, StringSplitOptions.RemoveEmptyEntries)
|
|
.Select(parameter => parameter.Split('='))
|
|
.Distinct();
|
|
|
|
nameValueCollection = caseIgnore ? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) : new Dictionary<string, string>();
|
|
foreach (var part in parts)
|
|
{
|
|
if (part.Length == 2)
|
|
{
|
|
nameValueCollection.Add(part[0], WebUtility.UrlDecode(part[1]));
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static IDictionary<string, WireMockList<string>> Parse(string? queryString, QueryParameterMultipleValueSupport? support = null)
|
|
{
|
|
if (string.IsNullOrEmpty(queryString))
|
|
{
|
|
return Empty;
|
|
}
|
|
|
|
var queryParameterMultipleValueSupport = support ?? QueryParameterMultipleValueSupport.All;
|
|
|
|
string[] JoinParts(string[] parts)
|
|
{
|
|
if (parts.Length > 1)
|
|
{
|
|
return queryParameterMultipleValueSupport.HasFlag(QueryParameterMultipleValueSupport.Comma) ?
|
|
parts[1].Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries) : // Support "?key=1,2"
|
|
new[] { parts[1] };
|
|
}
|
|
|
|
return new string[0];
|
|
}
|
|
|
|
var splitOn = new List<string>();
|
|
if (queryParameterMultipleValueSupport.HasFlag(QueryParameterMultipleValueSupport.Ampersand))
|
|
{
|
|
splitOn.Add("&"); // Support "?key=value&key=anotherValue"
|
|
}
|
|
if (queryParameterMultipleValueSupport.HasFlag(QueryParameterMultipleValueSupport.SemiColon))
|
|
{
|
|
splitOn.Add(";"); // Support "?key=value;key=anotherValue"
|
|
}
|
|
|
|
return queryString!.TrimStart('?')
|
|
.Split(splitOn.ToArray(), StringSplitOptions.RemoveEmptyEntries)
|
|
.Select(parameter => parameter.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries))
|
|
.GroupBy(parts => parts[0], JoinParts)
|
|
.ToDictionary(grouping => grouping.Key, grouping => new WireMockList<string>(grouping.SelectMany(x => x).Select(WebUtility.UrlDecode)));
|
|
}
|
|
} |