forked from ThreeMammals/Ocelot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* ThreeMammals#464 added code to request mapper to not automatically add content type and content length headers, .net will automatically try and add these headers in a few circumstances but this solves the 464 issue * ThreeMammals#464 use seek instead of read on body check for websockets tests * ThreeMammals#464 ran out of inodes on linux, looks like reloadonchange causes this
- Loading branch information
1 parent
12ef3bc
commit 23c5fcb
Showing
19 changed files
with
1,253 additions
and
1,034 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 61 additions & 61 deletions
122
src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,61 @@ | ||
using System.Collections.Generic; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Authentication; | ||
using Ocelot.Configuration; | ||
using Ocelot.Errors; | ||
using Ocelot.Infrastructure.Extensions; | ||
using Ocelot.Logging; | ||
using Ocelot.Middleware; | ||
|
||
namespace Ocelot.Authentication.Middleware | ||
{ | ||
public class AuthenticationMiddleware : OcelotMiddleware | ||
{ | ||
private readonly OcelotRequestDelegate _next; | ||
|
||
public AuthenticationMiddleware(OcelotRequestDelegate next, | ||
IOcelotLoggerFactory loggerFactory) | ||
: base(loggerFactory.CreateLogger<AuthenticationMiddleware>()) | ||
{ | ||
_next = next; | ||
} | ||
|
||
public async Task Invoke(DownstreamContext context) | ||
{ | ||
if (IsAuthenticatedRoute(context.DownstreamReRoute)) | ||
{ | ||
Logger.LogInformation($"{context.HttpContext.Request.Path} is an authenticated route. {MiddlewareName} checking if client is authenticated"); | ||
|
||
var result = await context.HttpContext.AuthenticateAsync(context.DownstreamReRoute.AuthenticationOptions.AuthenticationProviderKey); | ||
|
||
context.HttpContext.User = result.Principal; | ||
|
||
if (context.HttpContext.User.Identity.IsAuthenticated) | ||
{ | ||
Logger.LogInformation($"Client has been authenticated for {context.HttpContext.Request.Path}"); | ||
await _next.Invoke(context); | ||
} | ||
else | ||
{ | ||
var error = new UnauthenticatedError( | ||
$"Request for authenticated route {context.HttpContext.Request.Path} by {context.HttpContext.User.Identity.Name} was unauthenticated"); | ||
|
||
Logger.LogWarning($"Client has NOT been authenticated for {context.HttpContext.Request.Path} and pipeline error set. {error}"); | ||
|
||
SetPipelineError(context, error); | ||
} | ||
} | ||
else | ||
{ | ||
Logger.LogInformation($"No authentication needed for {context.HttpContext.Request.Path}"); | ||
|
||
await _next.Invoke(context); | ||
} | ||
} | ||
|
||
private static bool IsAuthenticatedRoute(DownstreamReRoute reRoute) | ||
{ | ||
return reRoute.IsAuthenticated; | ||
} | ||
} | ||
} | ||
using System.Collections.Generic; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Authentication; | ||
using Ocelot.Configuration; | ||
using Ocelot.Errors; | ||
using Ocelot.Infrastructure.Extensions; | ||
using Ocelot.Logging; | ||
using Ocelot.Middleware; | ||
|
||
namespace Ocelot.Authentication.Middleware | ||
{ | ||
public class AuthenticationMiddleware : OcelotMiddleware | ||
{ | ||
private readonly OcelotRequestDelegate _next; | ||
|
||
public AuthenticationMiddleware(OcelotRequestDelegate next, | ||
IOcelotLoggerFactory loggerFactory) | ||
: base(loggerFactory.CreateLogger<AuthenticationMiddleware>()) | ||
{ | ||
_next = next; | ||
} | ||
|
||
public async Task Invoke(DownstreamContext context) | ||
{ | ||
if (IsAuthenticatedRoute(context.DownstreamReRoute)) | ||
{ | ||
Logger.LogInformation($"{context.HttpContext.Request.Path} is an authenticated route. {MiddlewareName} checking if client is authenticated"); | ||
|
||
var result = await context.HttpContext.AuthenticateAsync(context.DownstreamReRoute.AuthenticationOptions.AuthenticationProviderKey); | ||
|
||
context.HttpContext.User = result.Principal; | ||
|
||
if (context.HttpContext.User.Identity.IsAuthenticated) | ||
{ | ||
Logger.LogInformation($"Client has been authenticated for {context.HttpContext.Request.Path}"); | ||
await _next.Invoke(context); | ||
} | ||
else | ||
{ | ||
var error = new UnauthenticatedError( | ||
$"Request for authenticated route {context.HttpContext.Request.Path} by {context.HttpContext.User.Identity.Name} was unauthenticated"); | ||
|
||
Logger.LogWarning($"Client has NOT been authenticated for {context.HttpContext.Request.Path} and pipeline error set. {error}"); | ||
|
||
SetPipelineError(context, error); | ||
} | ||
} | ||
else | ||
{ | ||
Logger.LogInformation($"No authentication needed for {context.HttpContext.Request.Path}"); | ||
|
||
await _next.Invoke(context); | ||
} | ||
} | ||
|
||
private static bool IsAuthenticatedRoute(DownstreamReRoute reRoute) | ||
{ | ||
return reRoute.IsAuthenticated; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
namespace Ocelot.Request.Mapper | ||
{ | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Http; | ||
using Ocelot.Responses; | ||
|
||
public interface IRequestMapper | ||
{ | ||
Task<Response<HttpRequestMessage>> Map(HttpRequest request); | ||
} | ||
} | ||
namespace Ocelot.Request.Mapper | ||
{ | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Http; | ||
using Ocelot.Responses; | ||
|
||
public interface IRequestMapper | ||
{ | ||
Response<HttpRequestMessage> Map(HttpRequest request); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,108 +1,99 @@ | ||
namespace Ocelot.Request.Mapper | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Http.Extensions; | ||
using Microsoft.Extensions.Primitives; | ||
using Ocelot.Responses; | ||
|
||
public class RequestMapper : IRequestMapper | ||
{ | ||
private readonly string[] _unsupportedHeaders = { "host" }; | ||
|
||
public async Task<Response<HttpRequestMessage>> Map(HttpRequest request) | ||
{ | ||
try | ||
{ | ||
var requestMessage = new HttpRequestMessage() | ||
{ | ||
Content = await MapContent(request), | ||
Method = MapMethod(request), | ||
RequestUri = MapUri(request) | ||
}; | ||
|
||
MapHeaders(request, requestMessage); | ||
|
||
return new OkResponse<HttpRequestMessage>(requestMessage); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return new ErrorResponse<HttpRequestMessage>(new UnmappableRequestError(ex)); | ||
} | ||
} | ||
|
||
private async Task<HttpContent> MapContent(HttpRequest request) | ||
{ | ||
if (request.Body == null) | ||
{ | ||
return null; | ||
} | ||
|
||
var content = new ByteArrayContent(await ToByteArray(request.Body)); | ||
|
||
content.Headers | ||
.TryAddWithoutValidation("Content-Type", new[] {request.ContentType}); | ||
|
||
AddHeaderIfExistsOnRequest("Content-Language", content, request); | ||
AddHeaderIfExistsOnRequest("Content-Location", content, request); | ||
AddHeaderIfExistsOnRequest("Content-Range", content, request); | ||
AddHeaderIfExistsOnRequest("Content-MD5", content, request); | ||
AddHeaderIfExistsOnRequest("Content-Disposition", content, request); | ||
AddHeaderIfExistsOnRequest("Content-Encoding", content, request); | ||
|
||
return content; | ||
} | ||
|
||
private void AddHeaderIfExistsOnRequest(string key, HttpContent content, HttpRequest request) | ||
{ | ||
if(request.Headers.ContainsKey(key)) | ||
{ | ||
content.Headers | ||
.TryAddWithoutValidation(key, request.Headers[key].ToList()); | ||
} | ||
} | ||
|
||
private HttpMethod MapMethod(HttpRequest request) | ||
{ | ||
return new HttpMethod(request.Method); | ||
} | ||
|
||
private Uri MapUri(HttpRequest request) | ||
{ | ||
return new Uri(request.GetEncodedUrl()); | ||
} | ||
|
||
private void MapHeaders(HttpRequest request, HttpRequestMessage requestMessage) | ||
{ | ||
foreach (var header in request.Headers) | ||
{ | ||
if (IsSupportedHeader(header)) | ||
{ | ||
requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()); | ||
} | ||
} | ||
} | ||
|
||
private async Task<byte[]> ToByteArray(Stream stream) | ||
{ | ||
using (stream) | ||
{ | ||
using (var memStream = new MemoryStream()) | ||
{ | ||
await stream.CopyToAsync(memStream); | ||
return memStream.ToArray(); | ||
} | ||
} | ||
} | ||
|
||
private bool IsSupportedHeader(KeyValuePair<string, StringValues> header) | ||
{ | ||
return !_unsupportedHeaders.Contains(header.Key.ToLower()); | ||
} | ||
} | ||
} | ||
namespace Ocelot.Request.Mapper | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Http.Extensions; | ||
using Microsoft.Extensions.Primitives; | ||
using Ocelot.Responses; | ||
|
||
public class RequestMapper : IRequestMapper | ||
{ | ||
private readonly string[] _unsupportedHeaders = { "host" }; | ||
|
||
public Response<HttpRequestMessage> Map(HttpRequest request) | ||
{ | ||
try | ||
{ | ||
var requestMessage = new HttpRequestMessage() | ||
{ | ||
Content = MapContent(request), | ||
Method = MapMethod(request), | ||
RequestUri = MapUri(request) | ||
}; | ||
|
||
MapHeaders(request, requestMessage); | ||
|
||
return new OkResponse<HttpRequestMessage>(requestMessage); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return new ErrorResponse<HttpRequestMessage>(new UnmappableRequestError(ex)); | ||
} | ||
} | ||
|
||
private HttpContent MapContent(HttpRequest request) | ||
{ | ||
if (request.Body == null || (request.Body.CanSeek && request.Body.Length <= 0)) | ||
{ | ||
return null; | ||
} | ||
|
||
var content = new StreamContent(request.Body); | ||
|
||
if(!string.IsNullOrEmpty(request.ContentType)) | ||
{ | ||
content.Headers | ||
.TryAddWithoutValidation("Content-Type", new[] {request.ContentType}); | ||
} | ||
|
||
AddHeaderIfExistsOnRequest("Content-Language", content, request); | ||
AddHeaderIfExistsOnRequest("Content-Location", content, request); | ||
AddHeaderIfExistsOnRequest("Content-Range", content, request); | ||
AddHeaderIfExistsOnRequest("Content-MD5", content, request); | ||
AddHeaderIfExistsOnRequest("Content-Disposition", content, request); | ||
AddHeaderIfExistsOnRequest("Content-Encoding", content, request); | ||
|
||
return content; | ||
} | ||
|
||
private void AddHeaderIfExistsOnRequest(string key, HttpContent content, HttpRequest request) | ||
{ | ||
if(request.Headers.ContainsKey(key)) | ||
{ | ||
content.Headers | ||
.TryAddWithoutValidation(key, request.Headers[key].ToList()); | ||
} | ||
} | ||
|
||
private HttpMethod MapMethod(HttpRequest request) | ||
{ | ||
return new HttpMethod(request.Method); | ||
} | ||
|
||
private Uri MapUri(HttpRequest request) | ||
{ | ||
return new Uri(request.GetEncodedUrl()); | ||
} | ||
|
||
private void MapHeaders(HttpRequest request, HttpRequestMessage requestMessage) | ||
{ | ||
foreach (var header in request.Headers) | ||
{ | ||
if (IsSupportedHeader(header)) | ||
{ | ||
requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()); | ||
} | ||
} | ||
} | ||
|
||
private bool IsSupportedHeader(KeyValuePair<string, StringValues> header) | ||
{ | ||
return !_unsupportedHeaders.Contains(header.Key.ToLower()); | ||
} | ||
} | ||
} |
Oops, something went wrong.