Skip to content

Commit

Permalink
Changing the way in which Accept is validated. Resolves #34
Browse files Browse the repository at this point in the history
  • Loading branch information
tpeczek committed Apr 26, 2020
1 parent 08a2ad1 commit fbe4fca
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<Description>Lib.AspNetCore.ServerSentEvents is a library which provides Server-Sent Events (SSE) support for ASP.NET Core</Description>
<Copyright>Copyright © 2017 - 2020 Tomasz Pęczek</Copyright>
<VersionPrefix>5.0.0</VersionPrefix>
<VersionSuffix>alpha2</VersionSuffix>
<VersionSuffix>alpha3</VersionSuffix>
<Authors>Tomasz Pęczek</Authors>
<TargetFrameworks>netcoreapp2.1;netcoreapp3.0;net461</TargetFrameworks>
<AssemblyTitle>Lib.AspNetCore.ServerSentEvents</AssemblyTitle>
Expand Down
23 changes: 22 additions & 1 deletion Lib.AspNetCore.ServerSentEvents/ServerSentEventsMiddleware.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
Expand Down Expand Up @@ -52,7 +53,7 @@ public ServerSentEventsMiddleware(RequestDelegate next, IAuthorizationPolicyProv
/// <returns>The task object representing the asynchronous operation.</returns>
public async Task Invoke(HttpContext context, IPolicyEvaluator policyEvaluator)
{
if (context.Request.Headers[Constants.ACCEPT_HTTP_HEADER] == Constants.SSE_CONTENT_TYPE)
if (CheckAcceptHeader(context.Request.Headers))
{
if (!await AuthorizeAsync(context, policyEvaluator))
{
Expand Down Expand Up @@ -84,6 +85,26 @@ public async Task Invoke(HttpContext context, IPolicyEvaluator policyEvaluator)
}
}

private bool CheckAcceptHeader(IHeaderDictionary requestHeaders)
{
if (!requestHeaders.ContainsKey(Constants.ACCEPT_HTTP_HEADER))
{
return true;
}

if (requestHeaders[Constants.ACCEPT_HTTP_HEADER].Count == 0)
{
return true;
}

if (requestHeaders[Constants.ACCEPT_HTTP_HEADER].Any(acceptHeaderValue => acceptHeaderValue == Constants.SSE_CONTENT_TYPE))
{
return true;
}

return false;
}

private async Task<bool> AuthorizeAsync(HttpContext context, IPolicyEvaluator policyEvaluator)
{
bool authorized = false;
Expand Down
36 changes: 31 additions & 5 deletions Test.AspNetCore.ServerSentEvents/Middleware/HandshakeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,15 @@ private ServerSentEventsMiddleware<ServerSentEventsService> PrepareServerSentEve
);
}

private HttpContext PrepareHttpContext()
private HttpContext PrepareHttpContext(string acceptHeaderValue)
{
HttpContext context = new DefaultHttpContext();

context.Request.Headers.Append(ACCEPT_HTTP_HEADER, SSE_CONTENT_TYPE);
if (acceptHeaderValue != null)
{
context.Request.Headers.Append(ACCEPT_HTTP_HEADER, acceptHeaderValue);
}

context.RequestAborted = new CancellationToken(true);

return context;
Expand All @@ -47,16 +51,38 @@ private HttpContext PrepareHttpContext()

#region Tests
[Fact]
public async Task Invoke_SseRequest_Accepts()
public async Task Invoke_SseRequestWithoutAcceptHeader_Accepts()
{
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware();
HttpContext context = PrepareHttpContext();
HttpContext context = PrepareHttpContext(null);

await serverSentEventsMiddleware.Invoke(context, null);

Assert.Equal(SSE_CONTENT_TYPE, context.Response.ContentType);
}

[Fact]
public async Task Invoke_SseRequestWithEventStreamAcceptHeader_Accepts()
{
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware();
HttpContext context = PrepareHttpContext(SSE_CONTENT_TYPE);

await serverSentEventsMiddleware.Invoke(context, null);

Assert.Equal(SSE_CONTENT_TYPE, context.Response.ContentType);
}

[Fact]
public async Task Invoke_SseRequestWithNotEventStreamAcceptHeader_Accepts()
{
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware();
HttpContext context = PrepareHttpContext("text/plain");

await serverSentEventsMiddleware.Invoke(context, null);

Assert.Null(context.Response.ContentType);
}

[Fact]
public async Task Invoke_SseRequest_CallsOnPrepareAccept()
{
Expand All @@ -66,7 +92,7 @@ public async Task Invoke_SseRequest_CallsOnPrepareAccept()
OnPrepareAccept = onPrepareAcceptMock.Object
});

await serverSentEventsMiddleware.Invoke(PrepareHttpContext(), null);
await serverSentEventsMiddleware.Invoke(PrepareHttpContext(null), null);

onPrepareAcceptMock.Verify(m => m(It.IsAny<HttpResponse>()), Times.Once);
}
Expand Down

0 comments on commit fbe4fca

Please sign in to comment.