Skip to content

Commit da7c62f

Browse files
committed
Merge remote-tracking branch 'origin/master' into pakrym/EnableAzurePipelinesReporter
2 parents 58e9154 + 508256d commit da7c62f

File tree

132 files changed

+2301
-996
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+2301
-996
lines changed

.azure/pipelines/jobs/default-build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ jobs:
103103
BuildScriptArgs: ${{ parameters.buildArgs }}
104104
BuildConfiguration: ${{ parameters.configuration }}
105105
BuildDirectory: ${{ parameters.buildDirectory }}
106+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
106107
TeamName: AspNetCore
107108
${{ if eq(parameters.agentOs, 'Windows') }}:
108109
JAVA_HOME: $(Agent.BuildDirectory)\.tools\jdk

build/SharedFx.targets

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
<FxProjectToBuild Condition=" '$(BuildSiteExtensions)' == 'true' " Include="$(RepositoryRoot)src\SiteExtensions\Runtime\Microsoft.AspNetCore.Runtime.SiteExtension.pkgproj" />
1212
<FxProjectToBuild Condition=" '$(BuildSiteExtensions)' == 'true' " Include="$(RepositoryRoot)src\SiteExtensions\LoggingBranch\LoggingBranch.csproj" />
13+
14+
<FxProjectToBuild Condition=" '$(TargetRuntimeIdentifier)' == 'win-x86' " Include="$(RepositoryRoot)src\Framework\src\Microsoft.AspNetCore.App.Runtime.csproj" />
1315
</ItemGroup>
1416

1517
<Target Name="BuildSharedFx" DependsOnTargets="$(BuildSharedFxDependsOn)" />

build/repo.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154
<Target Name="Helix">
155155
<MSBuild Projects="$(MSBuildThisFileDirectory)..\eng\helix\helix.proj"
156156
Targets="Test"
157+
Properties="$(BuildProperties);$(SolutionProperties);"
157158
ContinueOnError="ErrorAndStop" />
158159
</Target>
159160
</Project>

eng/helix/helix.proj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<EnableXUnitReporter>true</EnableXUnitReporter>
2323
<IsExternal>true</IsExternal>
2424
<Creator>aspnetcore</Creator>
25+
<SkipInvalidConfigurations>true</SkipInvalidConfigurations>
2526
</PropertyGroup>
2627

2728
<Target Name="Gather" BeforeTargets="Build">

eng/targets/CSharp.Common.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22

33
<PropertyGroup>
4-
<LangVersion>7.3</LangVersion>
4+
<LangVersion>8.0</LangVersion>
55
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)..\AspNetCore.snk</AssemblyOriginatorKeyFile>
66
<SignAssembly>true</SignAssembly>
77

src/Components/Components/src/Rendering/Renderer.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -328,13 +328,14 @@ internal void AddToPendingTasks(Task task)
328328
HandleException(task.Exception.GetBaseException());
329329
break;
330330
default:
331-
// We are not in rendering the root component.
332-
if (_pendingTasks == null)
333-
{
334-
return;
335-
}
336-
337-
_pendingTasks.Add(GetErrorHandledTask(task));
331+
// It's important to evaluate the following even if we're not going to use
332+
// handledErrorTask below, because it has the side-effect of calling HandleException.
333+
var handledErrorTask = GetErrorHandledTask(task);
334+
335+
// The pendingTasks collection is only used during prerendering to track quiescence,
336+
// so will be null at other times.
337+
_pendingTasks?.Add(handledErrorTask);
338+
338339
break;
339340
}
340341
}

src/Components/Components/test/RendererTest.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2683,7 +2683,7 @@ public void ExceptionsReturnedUsingTaskFromExceptionCanBeHandled()
26832683
}
26842684

26852685
[Fact]
2686-
public async Task ExceptionsThrownAsynchronouslyCanBeHandled()
2686+
public async Task ExceptionsThrownAsynchronouslyDuringFirstRenderCanBeHandled()
26872687
{
26882688
// Arrange
26892689
var renderer = new TestRenderer { ShouldHandleExceptions = true };
@@ -2722,6 +2722,36 @@ public async Task ExceptionsThrownAsynchronouslyCanBeHandled()
27222722
Assert.Same(exception, Assert.Single(renderer.HandledExceptions).GetBaseException());
27232723
}
27242724

2725+
[Fact]
2726+
public async Task ExceptionsThrownAsynchronouslyAfterFirstRenderCanBeHandled()
2727+
{
2728+
// This differs from the "during first render" case, because some aspects of the rendering
2729+
// code paths are special cased for the first render because of prerendering.
2730+
2731+
// Arrange
2732+
var renderer = new TestRenderer { ShouldHandleExceptions = true };
2733+
var taskToAwait = Task.CompletedTask;
2734+
var component = new TestComponent(builder =>
2735+
{
2736+
builder.OpenComponent<ComponentThatAwaitsTask>(0);
2737+
builder.AddAttribute(1, nameof(ComponentThatAwaitsTask.TaskToAwait), taskToAwait);
2738+
builder.CloseComponent();
2739+
});
2740+
var componentId = renderer.AssignRootComponentId(component);
2741+
await renderer.RenderRootComponentAsync(componentId); // Not throwing on first render
2742+
2743+
var asyncExceptionTcs = new TaskCompletionSource<object>();
2744+
taskToAwait = asyncExceptionTcs.Task;
2745+
await renderer.Invoke(component.TriggerRender);
2746+
2747+
// Act
2748+
var exception = new InvalidOperationException();
2749+
asyncExceptionTcs.SetException(exception);
2750+
2751+
// Assert
2752+
Assert.Same(exception, Assert.Single(renderer.HandledExceptions).GetBaseException());
2753+
}
2754+
27252755
[Fact]
27262756
public async Task ExceptionsThrownAsynchronouslyFromMultipleComponentsCanBeHandled()
27272757
{
@@ -3696,5 +3726,15 @@ public enum EventType
36963726
OnAfterRenderAsync,
36973727
}
36983728
}
3729+
3730+
private class ComponentThatAwaitsTask : ComponentBase
3731+
{
3732+
[Parameter] public Task TaskToAwait { get; set; }
3733+
3734+
protected override async Task OnParametersSetAsync()
3735+
{
3736+
await TaskToAwait;
3737+
}
3738+
}
36993739
}
37003740
}

src/Components/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Blazor uses only the latest web standards. No plugins or transpilation needed. I
3131

3232
> Note: client-side Blazor is an *experimental* project. It's not yet a committed product . This is to allow time to fully investigate the technical issues associated with running .NET in the browser and to ensure we can build something that developers love and can be productive with. During this experimental phase, we expect to engage deeply with early Blazor adopters like you to hear your feedback and suggestions.
3333
34-
To see Blazor in action, check out [Steve Sanderson's demo at NDC Minnesota](https://www.youtube.com/watch?v=JU-6pAxqAa4). You can also try out a [simple live Blazor app](https://blazor-demo.github.io/).
34+
To see Blazor in action, check out [Steve Sanderson's demo at NDC London](https://www.youtube.com/watch?v=Qe8UW5543-s). You can also try out a [simple live Blazor app](https://blazor-demo.github.io/).
3535

3636
## Getting Started
3737

src/Http/Http.Abstractions/src/CookieBuilder.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
@@ -49,12 +49,12 @@ public virtual string Name
4949
public virtual bool HttpOnly { get; set; }
5050

5151
/// <summary>
52-
/// The SameSite attribute of the cookie. The default value is <see cref="SameSiteMode.Lax"/>
52+
/// The SameSite attribute of the cookie. The default value is <see cref="SameSiteMode.None"/>
5353
/// </summary>
5454
/// <remarks>
5555
/// Determines the value that will set on <seealso cref="CookieOptions.SameSite"/>.
5656
/// </remarks>
57-
public virtual SameSiteMode SameSite { get; set; } = SameSiteMode.Lax;
57+
public virtual SameSiteMode SameSite { get; set; } = SameSiteMode.None;
5858

5959
/// <summary>
6060
/// The policy that will be used to determine <seealso cref="CookieOptions.Secure"/>.

src/Http/Http.Features/src/CookieOptions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ public CookieOptions()
4343
public bool Secure { get; set; }
4444

4545
/// <summary>
46-
/// Gets or sets the value for the SameSite attribute of the cookie. The default value is <see cref="SameSiteMode.Lax"/>
46+
/// Gets or sets the value for the SameSite attribute of the cookie. The default value is <see cref="SameSiteMode.None"/>
4747
/// </summary>
4848
/// <returns>The <see cref="SameSiteMode"/> representing the enforcement mode of the cookie.</returns>
49-
public SameSiteMode SameSite { get; set; } = SameSiteMode.Lax;
49+
public SameSiteMode SameSite { get; set; } = SameSiteMode.None;
5050

5151
/// <summary>
5252
/// Gets or sets a value that indicates whether a cookie is accessible by client-side script.

src/Http/Http/src/Features/FormFeature.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,13 @@ private async Task<IFormCollection> InnerReadFormAsync(CancellationToken cancell
150150
if (HasApplicationFormContentType(contentType))
151151
{
152152
var encoding = FilterEncoding(contentType.Encoding);
153-
using (var formReader = new FormReader(_request.Body, encoding)
153+
var formReader = new FormPipeReader(_request.BodyPipe, encoding)
154154
{
155155
ValueCountLimit = _options.ValueCountLimit,
156156
KeyLengthLimit = _options.KeyLengthLimit,
157157
ValueLengthLimit = _options.ValueLengthLimit,
158-
})
159-
{
160-
formFields = new FormCollection(await formReader.ReadFormAsync(cancellationToken));
161-
}
158+
};
159+
formFields = new FormCollection(await formReader.ReadFormAsync(cancellationToken));
162160
}
163161
else if (HasMultipartFormContentType(contentType))
164162
{

src/Http/Http/test/Features/FormFeatureTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Collections.Generic;
66
using System.IO;
7+
using System.IO.Pipelines;
78
using System.Text;
89
using System.Threading.Tasks;
910
using Xunit;
@@ -82,6 +83,41 @@ public async Task ReadFormAsync_SimpleData_ReturnsParsedFormCollection(bool buff
8283
await responseFeature.CompleteAsync();
8384
}
8485

86+
[Theory]
87+
[InlineData(true)]
88+
[InlineData(false)]
89+
public async Task ReadFormAsync_SimpleData_ReplacePipeReader_ReturnsParsedFormCollection(bool bufferRequest)
90+
{
91+
var formContent = Encoding.UTF8.GetBytes("foo=bar&baz=2");
92+
var context = new DefaultHttpContext();
93+
var responseFeature = new FakeResponseFeature();
94+
context.Features.Set<IHttpResponseFeature>(responseFeature);
95+
context.Request.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
96+
97+
var pipe = new Pipe();
98+
await pipe.Writer.WriteAsync(formContent);
99+
pipe.Writer.Complete();
100+
101+
context.Request.BodyPipe = pipe.Reader;
102+
103+
IFormFeature formFeature = new FormFeature(context.Request, new FormOptions() { BufferBody = bufferRequest });
104+
context.Features.Set<IFormFeature>(formFeature);
105+
106+
var formCollection = await context.Request.ReadFormAsync();
107+
108+
Assert.Equal("bar", formCollection["foo"]);
109+
Assert.Equal("2", formCollection["baz"]);
110+
111+
// Cached
112+
formFeature = context.Features.Get<IFormFeature>();
113+
Assert.NotNull(formFeature);
114+
Assert.NotNull(formFeature.Form);
115+
Assert.Same(formFeature.Form, formCollection);
116+
117+
// Cleanup
118+
await responseFeature.CompleteAsync();
119+
}
120+
85121
private const string MultipartContentType = "multipart/form-data; boundary=WebKitFormBoundary5pDRpGheQXaM8k3T";
86122

87123
private const string MultipartContentTypeWithSpecialCharacters = "multipart/form-data; boundary=\"WebKitFormBoundary/:5pDRpGheQXaM8k3T\"";

src/Http/HttpAbstractions.sln

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HttpOv
113113
EndProject
114114
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration", "..\Servers\IIS\IISIntegration\src\Microsoft.AspNetCore.Server.IISIntegration.csproj", "{1062FCDE-E145-40EC-B175-FDBCAA0C59A0}"
115115
EndProject
116+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.WebUtilities.Performance", "WebUtilities\perf\Microsoft.AspNetCore.WebUtilities.Performance\Microsoft.AspNetCore.WebUtilities.Performance.csproj", "{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}"
117+
EndProject
116118
Global
117119
GlobalSection(SolutionConfigurationPlatforms) = preSolution
118120
Debug|Any CPU = Debug|Any CPU
@@ -603,6 +605,18 @@ Global
603605
{1062FCDE-E145-40EC-B175-FDBCAA0C59A0}.Release|x64.Build.0 = Release|Any CPU
604606
{1062FCDE-E145-40EC-B175-FDBCAA0C59A0}.Release|x86.ActiveCfg = Release|Any CPU
605607
{1062FCDE-E145-40EC-B175-FDBCAA0C59A0}.Release|x86.Build.0 = Release|Any CPU
608+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
609+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}.Debug|Any CPU.Build.0 = Debug|Any CPU
610+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}.Debug|x64.ActiveCfg = Debug|Any CPU
611+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}.Debug|x64.Build.0 = Debug|Any CPU
612+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}.Debug|x86.ActiveCfg = Debug|Any CPU
613+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}.Debug|x86.Build.0 = Debug|Any CPU
614+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}.Release|Any CPU.ActiveCfg = Release|Any CPU
615+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}.Release|Any CPU.Build.0 = Release|Any CPU
616+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}.Release|x64.ActiveCfg = Release|Any CPU
617+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}.Release|x64.Build.0 = Release|Any CPU
618+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}.Release|x86.ActiveCfg = Release|Any CPU
619+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E}.Release|x86.Build.0 = Release|Any CPU
606620
EndGlobalSection
607621
GlobalSection(SolutionProperties) = preSolution
608622
HideSolutionNode = FALSE
@@ -651,6 +665,7 @@ Global
651665
{DC519C5E-CA6E-48CA-BF35-B46305B83013} = {14A7B3DE-46C8-4245-B0BD-9AFF3795C163}
652666
{611794D2-EF3A-422A-A077-23E61C7ADE49} = {793FFE24-138A-4C3D-81AB-18D625E36230}
653667
{1062FCDE-E145-40EC-B175-FDBCAA0C59A0} = {793FFE24-138A-4C3D-81AB-18D625E36230}
668+
{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E} = {80A090C8-ED02-4DE3-875A-30DCCDBD84BA}
654669
EndGlobalSection
655670
GlobalSection(ExtensibilityGlobals) = postSolution
656671
SolutionGuid = {85B5E151-2E9D-419C-83DD-0DDCF446C83A}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[assembly: BenchmarkDotNet.Attributes.AspNetCoreBenchmark]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Buffers;
5+
using System.Text;
6+
using BenchmarkDotNet.Attributes;
7+
8+
namespace Microsoft.AspNetCore.WebUtilities.Performance
9+
{
10+
/// <summary>
11+
/// Test internal parsing speed of FormPipeReader without pipe
12+
/// </summary>
13+
public class FormPipeReaderInternalsBenchmark
14+
{
15+
private byte[] _singleUtf8 = Encoding.UTF8.GetBytes("foo=bar&baz=boo&haha=hehe&lol=temp");
16+
private byte[] _firstUtf8 = Encoding.UTF8.GetBytes("foo=bar&baz=boo");
17+
private byte[] _secondUtf8 = Encoding.UTF8.GetBytes("&haha=hehe&lol=temp");
18+
private FormPipeReader _formPipeReader;
19+
20+
[IterationSetup]
21+
public void Setup()
22+
{
23+
_formPipeReader = new FormPipeReader(null);
24+
}
25+
26+
[Benchmark]
27+
public void ReadUtf8Data()
28+
{
29+
var buffer = new ReadOnlySequence<byte>(_singleUtf8);
30+
KeyValueAccumulator accum = default;
31+
32+
_formPipeReader.ParseFormValues(ref buffer, ref accum, isFinalBlock: true);
33+
}
34+
35+
[Benchmark]
36+
public void ReadUtf8MultipleBlockData()
37+
{
38+
var buffer = ReadOnlySequenceFactory.CreateSegments(_firstUtf8, _secondUtf8);
39+
KeyValueAccumulator accum = default;
40+
41+
_formPipeReader.ParseFormValues(ref buffer, ref accum, isFinalBlock: true);
42+
}
43+
}
44+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Buffers;
5+
using System.Collections.Generic;
6+
using System.IO;
7+
using System.IO.Pipelines;
8+
using System.Linq;
9+
using System.Text;
10+
using System.Threading.Tasks;
11+
using BenchmarkDotNet.Attributes;
12+
using Microsoft.Extensions.Primitives;
13+
14+
namespace Microsoft.AspNetCore.WebUtilities
15+
{
16+
public class FormReaderBenchmark
17+
{
18+
[Benchmark]
19+
public async Task ReadSmallFormAsyncStream()
20+
{
21+
var bytes = Encoding.UTF8.GetBytes("foo=bar&baz=boo");
22+
var stream = new MemoryStream(bytes);
23+
24+
for (var i = 0; i < 1000; i++)
25+
{
26+
var formReader = new FormReader(stream);
27+
await formReader.ReadFormAsync();
28+
stream.Position = 0;
29+
}
30+
}
31+
32+
[Benchmark]
33+
public async Task ReadSmallFormAsyncPipe()
34+
{
35+
var pipe = new Pipe();
36+
var bytes = Encoding.UTF8.GetBytes("foo=bar&baz=boo");
37+
38+
for (var i = 0; i < 1000; i++)
39+
{
40+
pipe.Writer.Write(bytes);
41+
pipe.Writer.Complete();
42+
var formReader = new FormPipeReader(pipe.Reader);
43+
await formReader.ReadFormAsync();
44+
pipe.Reader.Complete();
45+
pipe.Reset();
46+
}
47+
}
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.0</TargetFramework>
5+
<OutputType>Exe</OutputType>
6+
<ServerGarbageCollection>true</ServerGarbageCollection>
7+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
8+
<IsPackable>false</IsPackable>
9+
<RootNamespace>Microsoft.AspNetCore.WebUtilities</RootNamespace>
10+
</PropertyGroup>
11+
12+
13+
<ItemGroup>
14+
<Reference Include="BenchmarkDotNet" />
15+
<Reference Include="Microsoft.AspNetCore.WebUtilities" />
16+
<Reference Include="Microsoft.AspNetCore.BenchmarkRunner.Sources" />
17+
</ItemGroup>
18+
19+
<ItemGroup>
20+
<Compile Include="$(SharedSourceRoot)Buffers.Testing\**\*.cs" />
21+
</ItemGroup>
22+
</Project>

0 commit comments

Comments
 (0)