Skip to content

Commit

Permalink
#159 remove special encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
pwelter34 committed Jun 5, 2024
1 parent 8f184f0 commit 27af755
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 23 deletions.
3 changes: 2 additions & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AssemblyMetadata.Generators" Version="2.0.0" PrivateAssets="All" />
<PackageReference Include="MinVer" Version="5.0.0" PrivateAssets="All" />
</ItemGroup>

Expand All @@ -53,5 +54,5 @@
<Visible>false</Visible>
</None>
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion src/FluentRest/FluentDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private static async Task<HttpRequestMessage> PrepareRequest(HttpRequestMessage
if (requestMessage.Headers.UserAgent.Count == 0)
{
// user-agent header required
var headerValue = new ProductInfoHeaderValue("FluentRest", "5.0.0.0");
var headerValue = new ProductInfoHeaderValue("FluentRest", ThisAssembly.FileVersion);
requestMessage.Headers.UserAgent.Add(headerValue);
}

Expand Down
54 changes: 54 additions & 0 deletions src/FluentRest/StringBuilderCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System.Text;

namespace FluentRest;

/// <summary>Provide a cached reusable instance of StringBuilder per thread.</summary>
internal static class StringBuilderCache
{
// The value 360 was chosen in discussion with performance experts as a compromise between using
// as little memory per thread as possible and still covering a large part of short-lived
// StringBuilder creations on the startup path of VS designers.
internal const int MaxBuilderSize = 360;
private const int DefaultCapacity = 16; // == StringBuilder.DefaultCapacity

[ThreadStatic]
private static StringBuilder t_cachedInstance;

/// <summary>Get a StringBuilder for the specified capacity.</summary>
/// <remarks>If a StringBuilder of an appropriate size is cached, it will be returned and the cache emptied.</remarks>
public static StringBuilder Acquire(int capacity = DefaultCapacity)
{
if (capacity > MaxBuilderSize)
return new StringBuilder(capacity);

var sb = t_cachedInstance;
if (sb == null)
return new StringBuilder(capacity);

// Avoid StringBuilder block fragmentation by getting a new StringBuilder
// when the requested size is larger than the current capacity
if (capacity > sb.Capacity)
return new StringBuilder(capacity);

t_cachedInstance = null;
sb.Clear();

return sb;

}

/// <summary>Place the specified builder in the cache if it is not too big.</summary>
public static void Release(StringBuilder sb)
{
if (sb.Capacity <= MaxBuilderSize)
t_cachedInstance = sb;
}

/// <summary>Release StringBuilder to the cache, and return the resulting string.</summary>
public static string ToString(StringBuilder sb)
{
string result = sb.ToString();
Release(sb);
return result;
}
}
30 changes: 12 additions & 18 deletions src/FluentRest/UrlBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ public Uri ToUri()
/// </returns>
public override string ToString()
{
var builder = new StringBuilder();
var builder = StringBuilderCache.Acquire(150);

if (!string.IsNullOrWhiteSpace(_scheme))
builder.Append(_scheme).Append(_schemeDelimiter);
Expand All @@ -553,16 +553,16 @@ public override string ToString()
{
builder.Append(_username);
if (!string.IsNullOrWhiteSpace(_password))
builder.Append(":").Append(_password);
builder.Append(':').Append(_password);

builder.Append("@");
builder.Append('@');
}

if (!string.IsNullOrWhiteSpace(_host))
{
builder.Append(_host);
if (_port.HasValue && !IsStandardPort())
builder.Append(":").Append(_port);
builder.Append(':').Append(_port);
}

WritePath(builder);
Expand All @@ -571,7 +571,7 @@ public override string ToString()
if (!string.IsNullOrWhiteSpace(_fragment))
builder.Append(_fragment);

return builder.ToString();
return StringBuilderCache.ToString(builder);
}


Expand All @@ -586,20 +586,19 @@ private bool IsStandardPort()

private void WritePath(StringBuilder builder)
{
builder.Append("/");
builder.Append('/');
if (Path == null || Path.Count == 0)
return;

int start = builder.Length;
foreach (var p in Path)
{
if (builder.Length > start)
builder.Append("/");
builder.Append('/');

var s = p.Replace(" ", "+");
s = Uri.EscapeUriString(s);
var v = Uri.EscapeDataString(p);

builder.Append(s);
builder.Append(v);
}
}

Expand All @@ -608,29 +607,27 @@ private void WriteQueryString(StringBuilder builder)
if (Query == null || Query.Count == 0)
return;

builder.Append("?");
builder.Append('?');

int start = builder.Length;
foreach (var pair in Query)
{
var key = pair.Key;
key = Uri.EscapeDataString(key);
key = key.Replace("%20", "+");

var values = pair.Value.ToList();

foreach (var value in values)
{
if (builder.Length > start)
builder.Append("&");
builder.Append('&');

var v = value;
v = Uri.EscapeDataString(v);
v = v.Replace("%20", "+");

builder
.Append(key)
.Append("=")
.Append('=')
.Append(v);
}
}
Expand Down Expand Up @@ -763,6 +760,3 @@ private void ParsePath(string s)
}

}



6 changes: 3 additions & 3 deletions test/FluentRest.Tests/UrlBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ public UrlBuilderTests(ITestOutputHelper output)

[Theory]
[InlineData("http://foo/bar/baz", "date", "today", "http://foo/bar/baz?date=today")]
[InlineData("http://foo/bar/baz", "date", "sunday afternoon", "http://foo/bar/baz?date=sunday+afternoon")]
[InlineData("http://foo/bar/baz", "date", "sunday afternoon", "http://foo/bar/baz?date=sunday%20afternoon")]
[InlineData("http://foo/bar/baz?date=today", "key1", "value1", "http://foo/bar/baz?date=today&key1=value1")]
[InlineData("http://foo/bar/baz?date=today", "key1", "value 1&", "http://foo/bar/baz?date=today&key1=value+1%26")]
[InlineData("foo/bar/baz?date=today", "key1", "value 1&", "http://foo/bar/baz?date=today&key1=value+1%26")]
[InlineData("http://foo/bar/baz?date=today", "key1", "value 1&", "http://foo/bar/baz?date=today&key1=value%201%26")]
[InlineData("foo/bar/baz?date=today", "key1", "value 1&", "http://foo/bar/baz?date=today&key1=value%201%26")]
public void AppendQuery(string url, string key, string value, string expected)
{
var builder = new UrlBuilder(url);
Expand Down

0 comments on commit 27af755

Please sign in to comment.