Add form and query helpers needed for Facebook auth.

This commit is contained in:
Chris Ross 2014-08-07 15:19:47 -07:00
parent e2a3f1455b
commit 7230a3d78e
11 changed files with 155 additions and 22 deletions

View File

@ -9,8 +9,9 @@ using System.Threading.Tasks;
using Microsoft.AspNet.FeatureModel;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.PipelineCore.Collections;
using Microsoft.AspNet.PipelineCore.Infrastructure;
using Microsoft.AspNet.WebUtilities;
using Microsoft.AspNet.WebUtilities.Collections;
namespace Microsoft.AspNet.PipelineCore
{
@ -60,8 +61,8 @@ namespace Microsoft.AspNet.PipelineCore
detectEncodingFromByteOrderMarks: true,
bufferSize: 1024, leaveOpen: true))
{
string formQuery = await streamReader.ReadToEndAsync();
_form = new ReadableStringCollection(ParsingHelpers.GetQuery(formQuery));
string form = await streamReader.ReadToEndAsync();
_form = FormHelpers.ParseForm(form);
}
}
return _form;

View File

@ -818,18 +818,6 @@ namespace Microsoft.AspNet.PipelineCore.Infrastructure
StringComparer.OrdinalIgnoreCase);
}
internal static IFormCollection GetForm(string text)
{
IDictionary<string, string[]> form = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
var accumulator = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
ParseDelimited(text, new[] { '&' }, AppendItemCallback, accumulator);
foreach (var kv in accumulator)
{
form.Add(kv.Key, kv.Value.ToArray());
}
return new FormCollection(form);
}
internal static string GetJoinedValue(IDictionary<string, string[]> store, string key)
{
string[] values = GetUnmodifiedValues(store, key);

View File

@ -5,8 +5,8 @@ using System.Collections.Generic;
using Microsoft.AspNet.FeatureModel;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.PipelineCore.Collections;
using Microsoft.AspNet.PipelineCore.Infrastructure;
using Microsoft.AspNet.WebUtilities.Collections;
namespace Microsoft.AspNet.PipelineCore
{

View File

@ -9,6 +9,7 @@ using Microsoft.AspNet.Http.Infrastructure;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.PipelineCore.Collections;
using Microsoft.AspNet.PipelineCore.Infrastructure;
using Microsoft.AspNet.WebUtilities.Collections;
namespace Microsoft.AspNet.PipelineCore
{

View File

@ -4,7 +4,8 @@
"dependencies": {
"Microsoft.AspNet.FeatureModel": "",
"Microsoft.AspNet.Http": "",
"Microsoft.AspNet.HttpFeature": ""
"Microsoft.AspNet.HttpFeature": "",
"Microsoft.AspNet.WebUtilities": ""
},
"frameworks": {
"net45": {},

View File

@ -4,7 +4,7 @@
using Microsoft.AspNet.Http;
using System.Collections.Generic;
namespace Microsoft.AspNet.PipelineCore.Collections
namespace Microsoft.AspNet.WebUtilities.Collections
{
/// <summary>
/// Contains the parsed form values.
@ -12,7 +12,7 @@ namespace Microsoft.AspNet.PipelineCore.Collections
public class FormCollection : ReadableStringCollection, IFormCollection
{
/// <summary>
/// Initializes a new instance of the <see cref="T:Microsoft.Owin.FormCollection" /> class.
/// Initializes a new instance of the <see cref="T:Microsoft.AspNet.WebUtilities.FormCollection" /> class.
/// </summary>
/// <param name="store">The store for the form.</param>
public FormCollection(IDictionary<string, string[]> store)

View File

@ -4,11 +4,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.AspNet.Http.Infrastructure;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.PipelineCore.Infrastructure;
namespace Microsoft.AspNet.PipelineCore.Collections
namespace Microsoft.AspNet.WebUtilities.Collections
{
/// <summary>
/// Accessors for query, forms, etc.

View File

@ -0,0 +1,18 @@
using System;
using Microsoft.AspNet.Http;
namespace Microsoft.AspNet.WebUtilities
{
public static class FormHelpers
{
/// <summary>
/// Parses an HTTP form body.
/// </summary>
/// <param name="text">The HTTP form body to parse.</param>
/// <returns>The <see cref="T:Microsoft.Owin.IFormCollection" /> object containing the parsed HTTP form body.</returns>
public static IFormCollection ParseForm(string text)
{
return ParsingHelpers.GetForm(text);
}
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNet.WebUtilities
{
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
internal sealed class NotNullAttribute : Attribute
{
}
}

View File

@ -0,0 +1,94 @@
// Copyright (c) Microsoft Open Technologies, Inc. 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.Collections.Generic;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.WebUtilities.Collections;
namespace Microsoft.AspNet.WebUtilities
{
internal static partial class ParsingHelpers
{
internal static void ParseDelimited(string text, char[] delimiters, Action<string, string, object> callback, object state)
{
int textLength = text.Length;
int equalIndex = text.IndexOf('=');
if (equalIndex == -1)
{
equalIndex = textLength;
}
int scanIndex = 0;
while (scanIndex < textLength)
{
int delimiterIndex = text.IndexOfAny(delimiters, scanIndex);
if (delimiterIndex == -1)
{
delimiterIndex = textLength;
}
if (equalIndex < delimiterIndex)
{
while (scanIndex != equalIndex && char.IsWhiteSpace(text[scanIndex]))
{
++scanIndex;
}
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);
equalIndex = text.IndexOf('=', delimiterIndex);
if (equalIndex == -1)
{
equalIndex = textLength;
}
}
scanIndex = delimiterIndex + 1;
}
}
private static readonly Action<string, string, object> AppendItemCallback = (name, value, state) =>
{
var dictionary = (IDictionary<string, List<String>>)state;
List<string> existing;
if (!dictionary.TryGetValue(name, out existing))
{
dictionary.Add(name, new List<string>(1) { value });
}
else
{
existing.Add(value);
}
};
internal static IFormCollection GetForm(string text)
{
IDictionary<string, string[]> form = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
var accumulator = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
ParseDelimited(text, new[] { '&' }, AppendItemCallback, accumulator);
foreach (var kv in accumulator)
{
form.Add(kv.Key, kv.Value.ToArray());
}
return new FormCollection(form);
}
internal static string GetJoinedValue(IDictionary<string, string[]> store, string key)
{
string[] values = GetUnmodifiedValues(store, key);
return values == null ? null : string.Join(",", values);
}
internal static string[] GetUnmodifiedValues(IDictionary<string, string[]> store, string key)
{
if (store == null)
{
throw new ArgumentNullException("store");
}
string[] values;
return store.TryGetValue(key, out values) ? values : null;
}
}
}

View File

@ -0,0 +1,20 @@
using System;
namespace Microsoft.AspNet.WebUtilities
{
public static class QueryHelpers
{
/// <summary>
/// Append the given query key and value to the uri.
/// </summary>
/// <param name="uri">The base uri.</param>
/// <param name="name">The name of the query key.</param>
/// <param name="value">The query value.</param>
/// <returns>The combine result.</returns>
public static string AddQueryString([NotNull] string uri, [NotNull] string name, [NotNull] string value)
{
bool hasQuery = uri.IndexOf('?') != -1;
return uri + (hasQuery ? "&" : "?") + Uri.EscapeDataString(name) + "=" + Uri.EscapeDataString(value);
}
}
}