Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion build/dependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<MicrosoftAspNetCoreHttpAbstractionsPackageVersion>3.0.0-alpha1-10584</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>3.0.0-alpha1-10584</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
<MicrosoftAspNetCoreHttpPackageVersion>3.0.0-alpha1-10584</MicrosoftAspNetCoreHttpPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-alpha1-10584</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-alpha1-10657</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>3.0.0-alpha1-10584</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
<MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.3</MicrosoftNETCoreApp21PackageVersion>
Expand Down
8 changes: 4 additions & 4 deletions build/sources.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
<RestoreSources>$(DotNetRestoreSources)</RestoreSources>
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true' AND '$(AspNetUniverseBuildOffline)' != 'true' ">
$(RestoreSources);
https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json;
https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json;
https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json;
</RestoreSources>
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true'">
$(RestoreSources);
https://api.nuget.org/v3/index.json;
</RestoreSources>
</PropertyGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private static bool IsMicrosoftRuntime

private static bool GetApplicationBasePath(IApplicationBuilder app, out string applicationBasePath)
{
IHostingEnvironment hostingEnvironment = app.ApplicationServices.GetService(typeof(IHostingEnvironment)) as IHostingEnvironment;
IWebHostEnvironment hostingEnvironment = app.ApplicationServices.GetService(typeof(IWebHostEnvironment)) as IWebHostEnvironment;

if (hostingEnvironment != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ private async Task ExecuteWithFilter(IHttpSocketAdapter injectScriptSocket, stri
return StaticTaskResult.True;
});

IHttpSendFileFeature originalSendFile = httpContext.Features.Get<IHttpSendFileFeature>();
httpContext.Features.Set<IHttpSendFileFeature>(new SendFilesWrapper(originalSendFile, httpContext.Response));
IHttpResponseBodyFeature originalSendFile = httpContext.Features.Get<IHttpResponseBodyFeature>();
httpContext.Features.Set<IHttpResponseBodyFeature>(new SendFilesWrapper(originalSendFile, httpContext.Response));

using (AddPageExecutionListenerFeatureTo(httpContext, requestId))
{
Expand Down
30 changes: 30 additions & 0 deletions src/Microsoft.VisualStudio.Web.BrowserLink/HostingStartup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

[assembly: HostingStartup(typeof(Microsoft.VisualStudio.Web.BrowserLink.HostingStartup))]

namespace Microsoft.VisualStudio.Web.BrowserLink
{
internal sealed class HostingStartup : IHostingStartup, IStartupFilter
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices(services => services.TryAddEnumerable(ServiceDescriptor.Singleton<IStartupFilter>(this)));
}

public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return app =>
{
app.UseBrowserLink();
next(app);
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@

<PropertyGroup>
<Description>A middleware that supports creating a communication channel between the development environment and one or more web browsers.</Description>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;browserlink</PackageTags>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="$(MicrosoftAspNetCoreHostingAbstractionsPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="$(MicrosoftAspNetCoreHttpAbstractionsPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="$(MicrosoftAspNetCoreHttpExtensionsPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="$(MicrosoftExtensionsFileProvidersPhysicalPackageVersion)" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

</Project>
33 changes: 27 additions & 6 deletions src/Microsoft.VisualStudio.Web.BrowserLink/SendFilesWrapper.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,59 @@
using System.IO;
using System.IO.Pipelines;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;


namespace Microsoft.VisualStudio.Web.BrowserLink
{
internal class SendFilesWrapper : IHttpSendFileFeature
internal class SendFilesWrapper : IHttpResponseBodyFeature
{
private HttpResponse _response;
private IHttpSendFileFeature _wrapped;
private IHttpResponseBodyFeature _wrapped;

internal SendFilesWrapper(IHttpSendFileFeature wrapped, HttpResponse response)
internal SendFilesWrapper(IHttpResponseBodyFeature wrapped, HttpResponse response)
{
_wrapped = wrapped;
_response = response;
}

async Task IHttpSendFileFeature.SendFileAsync(string path, long offset, long? count, CancellationToken cancellation)
public Stream Stream => _wrapped.Stream;

public PipeWriter Writer => _wrapped.Writer;

public Task CompleteAsync()
{
return _wrapped.CompleteAsync();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It used to be possible for _wrapped to be null, if app.UseStaticFiles() wasn't included. We should check all references for null to be on the safe side, so we don't cause runtime errors in working applications.

}

public void DisableBuffering()
{
_wrapped.DisableBuffering();
}

public async Task SendFileAsync(string path, long offset, long? count, CancellationToken cancellationToken = default)
{
// TODO: Send mapping data to VS

if (_wrapped != null)
{
await _wrapped.SendFileAsync(path, offset, count, cancellation);
await _wrapped.SendFileAsync(path, offset, count, cancellationToken);
return;
}

using (Stream readStream = File.OpenRead(path))
{
readStream.Seek(offset, SeekOrigin.Begin);

await readStream.CopyToAsync(_response.Body, 4096, cancellation);
await readStream.CopyToAsync(_response.Body, 4096, cancellationToken);
}
}

public Task StartAsync(CancellationToken cancellationToken = default)
{
return _wrapped.StartAsync(cancellationToken);
}
}
}
10 changes: 10 additions & 0 deletions src/Microsoft.VisualStudio.Web.BrowserLink/StartupHook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// 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.

internal class StartupHook
{
public static void Initialize()
{
// This method exists to make startup hook load successfully. We do not need to do anything interesting here.
}
}
4 changes: 2 additions & 2 deletions test/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
<Import Project="..\Directory.Build.props" />

<PropertyGroup>
<DeveloperBuildTestTfms>netcoreapp2.2</DeveloperBuildTestTfms>
<DeveloperBuildTestTfms>netcoreapp3.1</DeveloperBuildTestTfms>
<StandardTestTfms>$(DeveloperBuildTestTfms)</StandardTestTfms>

<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' AND '$(OS)' == 'Windows_NT' ">$(StandardTestTfms);net461</StandardTestTfms>
<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' AND '$(OS)' == 'Windows_NT' ">$(StandardTestTfms);net472</StandardTestTfms>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ public void FilterRequestHeader_PortsNotMatch()
BrowserLinkMiddleWareUtil.FilterRequestHeader(requestHeader, connectionString);

// Assert
Assert.Null(requestHeader.IfNoneMatch);
Assert.Equal(0, requestHeader.IfNoneMatch.Count);
Assert.Null(requestHeader.IfModifiedSince);
}

Expand All @@ -372,7 +372,7 @@ public void FilterRequestHeader_NoPortInConnectionString()
BrowserLinkMiddleWareUtil.FilterRequestHeader(requestHeader, connectionString);

// Assert
Assert.Null(requestHeader.IfNoneMatch);
Assert.Equal(0, requestHeader.IfNoneMatch.Count);
Assert.Null(requestHeader.IfModifiedSince);
}

Expand All @@ -392,7 +392,7 @@ public void FilterRequestHeader_NoPortInETag()
BrowserLinkMiddleWareUtil.FilterRequestHeader(requestHeader, connectionString);

// Assert
Assert.Null(requestHeader.IfNoneMatch);
Assert.Equal(0, requestHeader.IfNoneMatch.Count);
Assert.Null(requestHeader.IfModifiedSince);
}

Expand All @@ -412,7 +412,7 @@ public void FilterRequestHeader_NoPortInEtagAndConnectionString()
BrowserLinkMiddleWareUtil.FilterRequestHeader(requestHeader, connectionString);

// Assert
Assert.Null(requestHeader.IfNoneMatch);
Assert.Equal(0, requestHeader.IfNoneMatch.Count);
Assert.Null(requestHeader.IfModifiedSince);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
<!--<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>-->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I would just remove this instead of commenting it out.

<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.VisualStudio.Web.BrowserLink\Microsoft.VisualStudio.Web.BrowserLink.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="$(MicrosoftAspNetCoreHttpPackageVersion)" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualstudioPackageVersion)" />
Expand Down