Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Specialized;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SystemWebAdapters;
using Microsoft.Net.Http.Headers;

Expand All @@ -15,9 +16,9 @@ public HttpCookieCollection()
{
}

internal HttpCookieCollection(HttpRequestCore request)
internal HttpCookieCollection(IRequestCookieCollection cookies)
{
foreach (var (name, value) in request.Cookies)
foreach (var (name, value) in cookies)
{
#pragma warning disable CA5396
Add(new HttpCookie(name, value));
Expand Down
7 changes: 6 additions & 1 deletion src/Microsoft.AspNetCore.SystemWebAdapters/HttpRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class HttpRequest
private NameValueCollection? _form;
private NameValueCollection? _query;
private HttpCookieCollection? _cookies;
private NameValueCollection? _params;
private HttpBrowserCapabilities? _browser;

public HttpRequest(HttpRequestCore request)
Expand Down Expand Up @@ -96,7 +97,7 @@ public string[] UserLanguages

public NameValueCollection Form => _form ??= _request.Form.ToNameValueCollection();

public HttpCookieCollection Cookies => _cookies ??= new(this);
public HttpCookieCollection Cookies => _cookies ??= new(_request.Cookies);

public int ContentLength => (int)(_request.ContentLength ?? 0);

Expand Down Expand Up @@ -175,6 +176,10 @@ public HttpBrowserCapabilities Browser
}
}

public string? this[string key] => Params[key];

public NameValueCollection Params => _params ??= new ParamsCollection(_request);

public byte[] BinaryRead(int count)
{
if (count < 0)
Expand Down
4 changes: 4 additions & 0 deletions src/Microsoft.AspNetCore.SystemWebAdapters/HttpRequestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public abstract class HttpRequestBase

public virtual HttpCookieCollection Cookies => throw new NotImplementedException();

public virtual string? this[string key] => throw new NotImplementedException();

public virtual NameValueCollection Params => throw new NotImplementedException();

public virtual int ContentLength => throw new NotImplementedException();

public virtual string? ContentType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,9 @@ public override string? ContentType
public override bool IsSecureConnection => _request.IsSecureConnection;

public override NameValueCollection ServerVariables => _request.ServerVariables;

public override NameValueCollection Params => _request.Params;

public override string? this[string key] => _request[key];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Specialized;

namespace Microsoft.AspNetCore.SystemWebAdapters.Internal;

internal abstract class NoGetByIntNameValueCollection : NameValueCollection
{
private protected const string IndexErrorMessage = "ASP.NET Core doesn't support accessing items by index.";

public sealed override string? Get(int index) => throw new PlatformNotSupportedException(IndexErrorMessage);

public sealed override string? GetKey(int index) => throw new PlatformNotSupportedException(IndexErrorMessage);

public sealed override string[]? GetValues(int index) => throw new PlatformNotSupportedException(IndexErrorMessage);

public sealed override KeysCollection Keys => throw new PlatformNotSupportedException(IndexErrorMessage);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Primitives;

namespace Microsoft.AspNetCore.SystemWebAdapters.Internal;

internal class ParamsCollection : NoGetByIntNameValueCollection
{
private readonly HttpRequestCore _request;

public ParamsCollection(HttpRequestCore request)
{
_request = request;

IsReadOnly = true;
}

public override string?[] AllKeys => throw new PlatformNotSupportedException("Enumerating all keys for parameters is not possible.");

public override int Count => throw new PlatformNotSupportedException("Count of all parameters is not possible.");

public override string? Get(string? name) => GetStringValues(name) is { Count: > 0 } result ? result.ToString() : null;

public override string[]? GetValues(string? name) => GetStringValues(name);

private StringValues GetStringValues(string? key)
{
if (key is null)
{
return StringValues.Empty;
}

if (_request.Query.TryGetValue(key, out var query))
{
return query;
}

if (_request.Form.TryGetValue(key, out var form))
{
return form;
}

if (_request.Cookies.TryGetValue(key, out var cookie))
{
return cookie;
}

if (_request.HttpContext.Features.Get<IServerVariablesFeature>() is { } serverVariables && serverVariables[key] is { } server)
{
return server;
}

return StringValues.Empty;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Microsoft.AspNetCore.SystemWebAdapters.Internal
{
internal class ServerVariablesNameValueCollection : WrappingNameValueCollection
internal class ServerVariablesNameValueCollection : NoGetByIntNameValueCollection
{
private const string EnumerationErrorMessage = "ASP.NET Core doesn't support enumerating server variables.";
private const string SerializationErrorMessage = "ASP.NET Core doesn't support serialization of server variables.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Microsoft.AspNetCore.SystemWebAdapters.Internal
{
internal class StringValuesDictionaryNameValueCollection : WrappingNameValueCollection
internal class StringValuesDictionaryNameValueCollection : NoGetByIntNameValueCollection
{
private readonly IDictionary<string, StringValues> _values;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Microsoft.AspNetCore.SystemWebAdapters.Internal
{
internal class StringValuesReadOnlyDictionaryNameValueCollection : WrappingNameValueCollection
internal class StringValuesReadOnlyDictionaryNameValueCollection : NoGetByIntNameValueCollection
{
private readonly IReadOnlyDictionary<string, StringValues> _values;

Expand Down

This file was deleted.

6 changes: 6 additions & 0 deletions src/Microsoft.AspNetCore.SystemWebAdapters/Ref.Standard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ internal HttpRequest() { }
public bool IsAuthenticated { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public bool IsLocal { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public bool IsSecureConnection { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public string this[string key] { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public System.Security.Principal.IIdentity LogonUserIdentity { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public System.Collections.Specialized.NameValueCollection Params { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public string Path { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public System.Collections.Specialized.NameValueCollection QueryString { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public string RawUrl { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
Expand Down Expand Up @@ -160,7 +162,9 @@ public abstract partial class HttpRequestBase
public virtual bool IsAuthenticated { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public virtual bool IsLocal { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public virtual bool IsSecureConnection { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public virtual string this[string key] { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public virtual System.Security.Principal.IIdentity LogonUserIdentity { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public virtual System.Collections.Specialized.NameValueCollection Params { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public virtual string Path { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public virtual System.Collections.Specialized.NameValueCollection QueryString { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public virtual string RawUrl { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
Expand Down Expand Up @@ -192,7 +196,9 @@ public partial class HttpRequestWrapper : System.Web.HttpRequestBase
public override bool IsAuthenticated { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public override bool IsLocal { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public override bool IsSecureConnection { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public override string this[string key] { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public override System.Security.Principal.IIdentity LogonUserIdentity { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public override System.Collections.Specialized.NameValueCollection Params { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public override string Path { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public override System.Collections.Specialized.NameValueCollection QueryString { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
public override string RawUrl { get { throw new System.PlatformNotSupportedException("Only support when running on ASP.NET Core or System.Web");} }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net;
Expand Down Expand Up @@ -442,7 +444,7 @@ public void UrlReferrer()
// Act
var result = request.UrlReferrer;

// Assert
// AssertexpectedResult
Assert.Equal(new Uri(referrer), result);
}

Expand Down Expand Up @@ -776,6 +778,95 @@ public void Cookies()
Assert.Same(cookies1, cookies2);
}

public enum ParamSource
{
None,
Query,
Form,
Cookie,
ServerVariable,
}

[InlineData(ParamSource.None)]
[InlineData(ParamSource.Query)]
[InlineData(ParamSource.Form)]
[InlineData(ParamSource.Cookie)]
[InlineData(ParamSource.ServerVariable)]
[Theory]
public void Indexer(ParamSource source)
=> GetParam((key, request) => request[key], source);

[InlineData(ParamSource.None)]
[InlineData(ParamSource.Query)]
[InlineData(ParamSource.Form)]
[InlineData(ParamSource.Cookie)]
[InlineData(ParamSource.ServerVariable)]
[Theory]
public void Params(ParamSource source)
=> GetParam((key, request) => request.Params[key], source);

private void GetParam(Func<string, HttpRequest, string?> getParam, ParamSource source)
{
// Arrange
var key = _fixture.Create<string>();
var expectedResult = source is ParamSource.None ? null : _fixture.Create<string>();
var otherResult = _fixture.Create<string>();

void Set(Action<string> action, ParamSource current)
{
if (source is ParamSource.None)
{
return;
}

if (current == source)
{
if (expectedResult is not null)
{
action(expectedResult);
}
}
else if (current > source)
{
action(otherResult);
}
}

var queryBacking = new Dictionary<string, StringValues>();
var queryCollection = new QueryCollection(queryBacking);
Set(v => queryBacking.Add(key, v), ParamSource.Query);

var formBacking = new Dictionary<string, StringValues>();
var formCollection = new FormCollection(formBacking);
Set(v => formBacking.Add(key, v), ParamSource.Form);

var cookies = new RequestCookies();
Set(v => cookies.Add(key, v), ParamSource.Cookie);

var serverVariables = new Mock<IServerVariablesFeature>();
Set(v => serverVariables.Setup(c => c[key]).Returns(v), ParamSource.ServerVariable);

var features = new FeatureCollection();
features.Set(serverVariables.Object);

var contextCore = new Mock<HttpContextCore>();
contextCore.Setup(c => c.Features).Returns(features);

var requestCore = new Mock<HttpRequestCore>();
requestCore.Setup(r => r.HttpContext).Returns(contextCore.Object);
requestCore.Setup(r => r.Query).Returns(queryCollection);
requestCore.Setup(r => r.Form).Returns(formCollection);
requestCore.Setup(r => r.Cookies).Returns(cookies);

var request = new HttpRequest(requestCore.Object);

// Act
var result = getParam(key, request);

// Assert
Assert.Equal(expectedResult, result);
}

[Fact]
public void ReadLessBytes()
{
Expand Down Expand Up @@ -811,5 +902,10 @@ public void ReadMoreBytes()
// Arrange
Assert.True(bytes.SequenceEqual(bytesRead));
}

private class RequestCookies : Dictionary<string, string>, IRequestCookieCollection
{
ICollection<string> IRequestCookieCollection.Keys => Keys;
}
}
}