Explorar o código

Merge branch 'release/3.0-preview7' => 'master' (#11784)

Doug Bunting %!s(int64=6) %!d(string=hai) anos
pai
achega
025476f31e

+ 1 - 1
.gitignore

@@ -39,4 +39,4 @@ modules/
 launchSettings.json
 msbuild.ProjectImports.zip
 StyleCop.Cache
-UpgradeLog.htm
+UpgradeLog.htm

+ 5 - 0
Directory.Build.targets

@@ -125,6 +125,11 @@
       <TargetingPackVersion Condition="'%(TargetFramework)' == 'netstandard2.1' and '$(IsServicingBuild)' != 'true'">$(NETStandardLibraryRefPackageVersion)</TargetingPackVersion>
     </KnownFrameworkReference>
 
+    <!-- Track compiler separately from Arcade.-->
+    <PackageReference Include="Microsoft.Net.Compilers.Toolset"
+        Version="$(MicrosoftNetCompilersToolsetPackageVersion)"
+        PrivateAssets="all"
+        IsImplicitlyDefined="true" />
   </ItemGroup>
 
   <PropertyGroup Condition=" '$(CopySymbolsToArtifacts)' == 'true' AND '$(TargetFramework)' != '' ">

+ 4 - 0
eng/Version.Details.xml

@@ -420,5 +420,9 @@
       <Uri>https://github.com/aspnet/Extensions</Uri>
       <Sha>0538d10f82468dd7539d9abdb7b60c378989e0a6</Sha>
     </Dependency>
+    <Dependency Name="Microsoft.Net.Compilers.Toolset" Version="3.3.0-beta1-19351-01">
+      <Uri>https://github.com/dotnet/roslyn</Uri>
+      <Sha>c91adff42c488aef2c2c532a7b053fb55e0c16ea</Sha>
+    </Dependency>
   </ToolsetDependencies>
 </Dependencies>

+ 7 - 3
eng/Versions.props

@@ -33,8 +33,6 @@
   <PropertyGroup Label="Arcade settings">
     <!-- Opt-in to Arcade tools for building VSIX projects. -->
     <UsingToolVSSDK>true</UsingToolVSSDK>
-    <!-- Opt-in to using the version of the Roslyn compiler bundled with Arcade. -->
-    <UsingToolMicrosoftNetCompilers Condition="'$(MSBuildProjectExtension)' == '.csproj' or '$(MSBuildProjectExtension)' == '.fsproj' or '$(MSBuildProjectExtension)' == '.vbproj'">true</UsingToolMicrosoftNetCompilers>
     <!-- Only use Microsoft.NETFramework.ReferenceAssemblies on non-windows builds. Using this on Windows breaks MVC runtime compilation. -->
     <UsingToolNetFrameworkReferenceAssemblies Condition="'$(OS)' != 'Windows_NT'">true</UsingToolNetFrameworkReferenceAssemblies>
     <!-- Disable XLIFF tasks -->
@@ -53,6 +51,8 @@
   <PropertyGroup Label="Automated">
     <!-- Packages from dotnet/arcade -->
     <MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19323.4</MicrosoftDotNetGenAPIPackageVersion>
+    <!-- Packages from dotnet/roslyn -->
+    <MicrosoftNetCompilersToolsetPackageVersion>3.3.0-beta1-19351-01</MicrosoftNetCompilersToolsetPackageVersion>
     <!-- Packages from dotnet/core-setup -->
     <MicrosoftExtensionsDependencyModelPackageVersion>3.0.0-preview8-27903-07</MicrosoftExtensionsDependencyModelPackageVersion>
     <MicrosoftNETCoreAppRefPackageVersion>3.0.0-preview8-27903-07</MicrosoftNETCoreAppRefPackageVersion>
@@ -217,7 +217,7 @@
     <CastleCorePackageVersion>4.2.1</CastleCorePackageVersion>
     <FSharpCorePackageVersion>4.2.1</FSharpCorePackageVersion>
     <GoogleProtobufPackageVersion>3.8.0</GoogleProtobufPackageVersion>
-    <GrpcAspNetCorePackageVersion>0.1.22-pre1</GrpcAspNetCorePackageVersion>
+    <GrpcAspNetCorePackageVersion>0.1.22-pre2</GrpcAspNetCorePackageVersion>
     <IdentityServer4AspNetIdentityPackageVersion>3.0.0-preview3.4</IdentityServer4AspNetIdentityPackageVersion>
     <IdentityServer4EntityFrameworkPackageVersion>3.0.0-preview3.4</IdentityServer4EntityFrameworkPackageVersion>
     <IdentityServer4PackageVersion>3.0.0-preview3.4</IdentityServer4PackageVersion>
@@ -255,6 +255,10 @@
       https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json;
       https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev;
     </RestoreSources>
+    <RestoreSources Condition="'$(DotNetBuildOffline)' != 'true' AND $(MicrosoftNetCompilersToolsetPackageVersion.Contains('-')) ">
+      $(RestoreSources);
+      https://dotnet.myget.org/F/roslyn/api/v3/index.json;
+    </RestoreSources>
     <!-- TODO remove this once we move Microsoft.Internal.AspNetCore.H2Spec.All to a non-myget feed -->
     <RestoreSources>
       $(RestoreSources);

+ 3 - 3
src/Mvc/Mvc.DataAnnotations/test/DataAnnotationsMetadataProviderTest.cs

@@ -1142,7 +1142,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations
             Assert.Equal(initialValue, context.ValidationMetadata.IsRequired);
         }
 
-        [Fact]
+        [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/11828")]
         public void CreateValidationMetadata_InfersRequiredAttribute_NoNonNullableProperty()
         {
             // Arrange
@@ -1325,7 +1325,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations
             Assert.Same(attribute, validatorMetadata);
         }
 
-        [Fact]
+        [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/11828")]
         public void IsNonNullable_FindsNonNullableProperty()
         {
             // Arrange
@@ -1353,7 +1353,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations
             Assert.False(result);
         }
 
-        [Fact]
+        [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/11828")]
         public void IsNonNullable_FindsNonNullableParameter()
         {
             // Arrange

+ 1 - 1
src/Mvc/test/Mvc.FunctionalTests/NonNullableReferenceTypesTest.cs

@@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
 
         private HttpClient Client { get; set; }
 
-        [Fact]
+        [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/11828")]
         public async Task CanUseNonNullableReferenceType_WithController_OmitData_ValidationErrors()
         {
             // Arrange

+ 3 - 3
src/Mvc/test/Mvc.IntegrationTests/NullableReferenceTypeIntegrationTest.cs

@@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
         }
 #nullable restore
 
-        [Fact]
+        [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/11828")]
         public async Task BindProperty_WithNonNullableReferenceType_NoData_ValidationError()
         {
             // Arrange
@@ -112,7 +112,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
         }
 #nullable restore
 
-        [Fact]
+        [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/11828")]
         public async Task BindProperty_WithNonNullableReferenceType_NoData_ValidationError_CustomMessage()
         {
             // Arrange
@@ -159,7 +159,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
         }
 #nullable restore
 
-        [Fact]
+        [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/11828")]
         public async Task BindParameter_WithNonNullableReferenceType_NoData_ValidationError()
         {
             // Arrange

+ 1 - 1
src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Properties/launchSettings.json

@@ -3,7 +3,7 @@
     "GrpcService-CSharp": {
       "commandName": "Project",
       "launchBrowser": false,
-      "applicationUrl": "https://localhost:50051",
+      "applicationUrl": "https://localhost:5001",
       "environmentVariables": {
         "ASPNETCORE_ENVIRONMENT": "Development"
       }

+ 6 - 1
src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/appsettings.json

@@ -5,5 +5,10 @@
       "Microsoft.Hosting.Lifetime": "Information"
     }
   },
-  "AllowedHosts": "*"
+  "AllowedHosts": "*",
+  "Kestrel": {
+    "EndpointDefaults": {
+      "Protocols": "Http2"
+    }
+  }
 }

+ 2 - 2
src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/store/Counter.ts

@@ -24,8 +24,8 @@ export type KnownAction = IncrementCountAction | DecrementCountAction;
 // They don't directly mutate state, but they can have external side-effects (such as loading data).
 
 export const actionCreators = {
-    increment: () => <IncrementCountAction>{ type: 'INCREMENT_COUNT' },
-    decrement: () => <DecrementCountAction>{ type: 'DECREMENT_COUNT' }
+    increment: () => ({ type: 'INCREMENT_COUNT' } as IncrementCountAction),
+    decrement: () => ({ type: 'DECREMENT_COUNT' } as DecrementCountAction)
 };
 
 // ----------------

+ 1 - 1
src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/store/configureStore.ts

@@ -1,4 +1,4 @@
-import { applyMiddleware, combineReducers, compose, createStore, Reducer } from 'redux';
+import { applyMiddleware, combineReducers, compose, createStore } from 'redux';
 import thunk from 'redux-thunk';
 import { connectRouter, routerMiddleware } from 'connected-react-router';
 import { History } from 'history';

+ 0 - 6
src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/Controllers/WeatherForecastController.cs

@@ -2,17 +2,11 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
-#if (!NoAuth)
-using Microsoft.AspNetCore.Authorization;
-#endif
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Logging;
 
 namespace Company.WebApplication1.Controllers
 {
-#if (!NoAuth)
-    [Authorize]
-#endif
     [ApiController]
     [Route("[controller]")]
     public class WeatherForecastController : ControllerBase

+ 0 - 3
src/ProjectTemplates/test/SpaTemplateTest/ReactReduxTemplateTest.cs

@@ -3,8 +3,6 @@
 
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.E2ETesting;
-using Microsoft.AspNetCore.Testing;
-using Microsoft.AspNetCore.Testing.xunit;
 using Templates.Test.Helpers;
 using Xunit;
 using Xunit.Abstractions;
@@ -19,7 +17,6 @@ namespace Templates.Test.SpaTemplateTest
         }
 
         [Fact]
-        [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2407", FlakyOn.AzP.Windows)]
         public Task ReactReduxTemplate_Works_NetCore()
             => SpaTemplateImplAsync("reactredux", "reactredux", useLocalDb: false, usesAuth: false);
     }

+ 27 - 9
src/Servers/Kestrel/Core/src/Internal/Http/Http1OutputProducer.cs

@@ -55,7 +55,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
         // and append the end terminator.
 
         private bool _autoChunk;
-        private bool _suffixSent;
+
+        // We rely on the TimingPipeFlusher to give us ValueTasks that can be safely awaited multiple times.
+        private bool _writeStreamSuffixCalled;
+        private ValueTask<FlushResult> _writeStreamSuffixValueTask;
+
         private int _advancedBytesForChunk;
         private Memory<byte> _currentChunkMemory;
         private bool _currentChunkMemoryUpdated;
@@ -113,15 +117,28 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
         {
             lock (_contextLock)
             {
-                if (_suffixSent || !_autoChunk)
+                if (_writeStreamSuffixCalled)
                 {
-                    _suffixSent = true;
-                    return FlushAsync();
+                    // If WriteStreamSuffixAsync has already been called, no-op and return the previously returned ValueTask.
+                    return _writeStreamSuffixValueTask;
                 }
 
-                _suffixSent = true;
-                var writer = new BufferWriter<PipeWriter>(_pipeWriter);
-                return WriteAsyncInternal(ref writer, EndChunkedResponseBytes);
+                if (_autoChunk)
+                {
+                    var writer = new BufferWriter<PipeWriter>(_pipeWriter);
+                    _writeStreamSuffixValueTask = WriteAsyncInternal(ref writer, EndChunkedResponseBytes);
+                }
+                else if (_unflushedBytes > 0)
+                {
+                    _writeStreamSuffixValueTask = FlushAsync();
+                }
+                else
+                {
+                    _writeStreamSuffixValueTask = default;
+                }
+
+                _writeStreamSuffixCalled = true;
+                return _writeStreamSuffixValueTask;
             }
         }
 
@@ -510,7 +527,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
             // Cleared in sequential address ascending order 
             _currentMemoryPrefixBytes = 0;
             _autoChunk = false;
-            _suffixSent = false;
+            _writeStreamSuffixCalled = false;
+            _writeStreamSuffixValueTask = default;
             _currentChunkMemoryUpdated = false;
             _startCalled = false;
         }
@@ -701,7 +719,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
         [StackTraceHidden]
         private void ThrowIfSuffixSent()
         {
-            if (_suffixSent)
+            if (_writeStreamSuffixCalled)
             {
                 throw new InvalidOperationException("Writing is not allowed after writer was completed.");
             }

+ 50 - 1
src/Servers/Kestrel/test/InMemory.FunctionalTests/ResponseTests.cs

@@ -2905,7 +2905,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
             var expectedString = new string('a', expectedLength);
             await using (var server = new TestServer(async httpContext =>
             {
-                httpContext.Response.Headers["Content-Length"] = new[] { expectedLength.ToString() };
+                httpContext.Response.ContentLength = expectedLength;
                 await httpContext.Response.WriteAsync(expectedString);
                 Assert.True(httpContext.Response.HasStarted);
             }, testContext))
@@ -2927,6 +2927,55 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
             }
         }
 
+        [Fact]
+        public async Task UnflushedContentLengthResponseIsFlushedAutomatically()
+        {
+            var testContext = new TestServiceContext(LoggerFactory);
+            var expectedLength = 100000;
+            var expectedString = new string('a', expectedLength);
+
+            void WriteStringWithoutFlushing(PipeWriter writer, string content)
+            {
+                var encoder = Encoding.ASCII.GetEncoder();
+                var encodedLength = Encoding.ASCII.GetByteCount(expectedString);
+                var source = expectedString.AsSpan();
+                var completed = false;
+
+                while (!completed)
+                {
+                    encoder.Convert(source, writer.GetSpan(), flush: source.Length == 0, out var charsUsed, out var bytesUsed, out completed);
+                    writer.Advance(bytesUsed);
+                    source = source.Slice(charsUsed);
+                }
+            }
+
+            await using (var server = new TestServer(httpContext =>
+            {
+                httpContext.Response.ContentLength = expectedLength;
+
+                WriteStringWithoutFlushing(httpContext.Response.BodyWriter, expectedString);
+
+                Assert.False(httpContext.Response.HasStarted);
+                return Task.CompletedTask;
+            }, testContext))
+            {
+                using (var connection = server.CreateConnection())
+                {
+                    await connection.Send(
+                        "GET / HTTP/1.1",
+                        "Host:",
+                        "",
+                        "");
+                    await connection.Receive(
+                        "HTTP/1.1 200 OK",
+                        $"Date: {testContext.DateHeaderValue}",
+                        $"Content-Length: {expectedLength}",
+                        "",
+                        expectedString);
+                }
+            }
+        }
+
         [Fact]
         public async Task StartAsyncAndFlushWorks()
         {