This commit is contained in:
Chris Ross 2020-08-12 16:51:22 -07:00 коммит произвёл GitHub
Родитель 635c92f641
Коммит 535ab4ccc4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 57 добавлений и 15 удалений

Просмотреть файл

@ -530,13 +530,13 @@ namespace Microsoft.Owin.Infrastructure
if (request.Get<string>("Microsoft.Owin.Cookies#text") != text)
{
cookies.Clear();
ParseDelimited(text, SemicolonAndComma, AddCookieCallback, cookies);
ParseDelimited(text, SemicolonAndComma, AddCookieCallback, decodePlus: false, decodeKey: false, state: cookies);
request.Set("Microsoft.Owin.Cookies#text", text);
}
return cookies;
}
internal static void ParseDelimited(string text, char[] delimiters, Action<string, string, object> callback, object state)
internal static void ParseDelimited(string text, char[] delimiters, Action<string, string, object> callback, bool decodePlus, bool decodeKey, object state)
{
int textLength = text.Length;
int equalIndex = text.IndexOf('=');
@ -560,10 +560,17 @@ namespace Microsoft.Owin.Infrastructure
}
string name = text.Substring(scanIndex, equalIndex - scanIndex);
string value = text.Substring(equalIndex + 1, delimiterIndex - equalIndex - 1);
callback(
Uri.UnescapeDataString(name.Replace('+', ' ')),
Uri.UnescapeDataString(value.Replace('+', ' ')),
state);
if (decodePlus)
{
name.Replace('+', ' ');
value.Replace('+', ' ');
}
if (decodeKey)
{
name = Uri.UnescapeDataString(name);
}
value = Uri.UnescapeDataString(value);
callback(name, value, state);
equalIndex = text.IndexOf('=', delimiterIndex);
if (equalIndex == -1)
{
@ -799,7 +806,7 @@ namespace Microsoft.Owin.Infrastructure
{
query.Clear();
var accumulator = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
ParseDelimited(text, AmpersandAndSemicolon, AppendItemCallback, accumulator);
ParseDelimited(text, AmpersandAndSemicolon, AppendItemCallback, decodePlus: true, decodeKey: true, state: accumulator);
foreach (var kv in accumulator)
{
query.Add(kv.Key, kv.Value.ToArray());
@ -813,7 +820,7 @@ namespace Microsoft.Owin.Infrastructure
{
IDictionary<string, string[]> form = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
var accumulator = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
ParseDelimited(text, new[] { '&' }, AppendItemCallback, accumulator);
ParseDelimited(text, new[] { '&' }, AppendItemCallback, decodePlus: false, decodeKey: true, state: accumulator);
foreach (var kv in accumulator)
{
form.Add(kv.Key, kv.Value.ToArray());

Просмотреть файл

@ -37,8 +37,11 @@ namespace Microsoft.Owin
get
{
string value;
Store.TryGetValue(key, out value);
return value;
if (Store.TryGetValue(key, out value) || Store.TryGetValue(Uri.EscapeDataString(key), out value))
{
return value;
}
return null;
}
}

Просмотреть файл

@ -14,7 +14,7 @@ namespace Microsoft.Owin.Tests
private static readonly string[] RawValues = new[] { "v1", "v2, v3", "\"v4, b\"", "v5, v6", "v7", };
private const string JoinedValues = "v1,v2, v3,\"v4, b\",v5, v6,v7";
private const string OriginalFormsString = "q1=v1&q2=v2,b&q3=v3&q3=v4&q4&q5=v5&q5=v5";
private const string OriginalFormsString = "q1=v1&q2=v2,b&q3=v3&q3=v4&q4&q5=v5&q5=v+5";
[Fact]
public void ParseForm()
@ -30,7 +30,7 @@ namespace Microsoft.Owin.Tests
Assert.Equal("v2,b", form.Get("Q2"));
Assert.Equal("v3,v4", form.Get("q3"));
Assert.Null(form.Get("q4"));
Assert.Equal("v5,v5", form.Get("Q5"));
Assert.Equal("v5,v+5", form.Get("Q5"));
Assert.True(stream.CanRead);
}
@ -89,7 +89,7 @@ namespace Microsoft.Owin.Tests
Assert.Equal("v2,b", form.Get("Q2"));
Assert.Equal("v3,v4", form.Get("q3"));
Assert.Null(form.Get("q4"));
Assert.Equal("v5,v5", form.Get("Q5"));
Assert.Equal("v5,v+5", form.Get("Q5"));
}
[Fact]
@ -107,14 +107,14 @@ namespace Microsoft.Owin.Tests
Assert.Equal("v2,b", form.Get("Q2"));
Assert.Equal("v3,v4", form.Get("q3"));
Assert.Null(form.Get("q4"));
Assert.Equal("v5,v5", form.Get("Q5"));
Assert.Equal("v5,v+5", form.Get("Q5"));
form = request.ReadFormAsync().Result;
Assert.Equal("v1", form.Get("q1"));
Assert.Equal("v2,b", form.Get("Q2"));
Assert.Equal("v3,v4", form.Get("q3"));
Assert.Null(form.Get("q4"));
Assert.Equal("v5,v5", form.Get("Q5"));
Assert.Equal("v5,v+5", form.Get("Q5"));
}
}
}

Просмотреть файл

@ -63,6 +63,7 @@
<Compile Include="Builder\AppBuilderTestExtensions.cs" />
<Compile Include="Builder\AppBuilderTests.cs" />
<Compile Include="CookieChunkingTests.cs" />
<Compile Include="RequestCookieTests.cs" />
<Compile Include="FormsTests.cs" />
<Compile Include="HeaderTests.cs" />
<Compile Include="HostStringTests.cs" />

Просмотреть файл

@ -0,0 +1,31 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using Xunit;
using Xunit.Extensions;
namespace Microsoft.Owin.Tests
{
public class RequestCookieTests
{
[Theory]
[InlineData("key=value", "key", "value")]
[InlineData("__secure-key=value", "__secure-key", "value")]
[InlineData("key%2C=%21value", "key,", "!value")]
[InlineData("ke%23y%2C=val%5Eue", "ke#y,", "val^ue")]
[InlineData("base64=QUI%2BREU%2FRw%3D%3D", "base64", "QUI+REU/Rw==")]
[InlineData("base64=QUI+REU/Rw==", "base64", "QUI+REU/Rw==")]
public void UnEscapesValues(string input, string expectedKey, string expectedValue)
{
var context = new OwinRequest();
context.Headers["Cookie"] = input;
var cookies = context.Cookies;
Assert.Equal(1, cookies.Count());
Assert.Equal(Uri.EscapeDataString(expectedKey), cookies.Single().Key);
Assert.Equal(expectedValue, cookies[expectedKey]);
}
}
}