add support for parsing ASP.NET Core HTTP requests into CloudEvents
Signed-off-by: Michael Friis <friism@gmail.com>
This commit is contained in:
parent
a0f3e72897
commit
209247e75f
|
@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CloudNative.CloudEvents.Amq
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CloudNative.CloudEvents.Kafka", "src\CloudNative.CloudEvents.Kafka\CloudNative.CloudEvents.Kafka.csproj", "{193D6D9D-C1A0-459E-86CF-F207CDF0FC73}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CloudNative.CloudEvents.AspNetCore", "src\CloudNative.CloudEvents.AspNetCore\CloudNative.CloudEvents.AspNetCore.csproj", "{C726DD78-2D56-48D3-928A-D10226E3750B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -93,6 +95,7 @@ Global
|
|||
{39EF4DB0-9890-4CAD-A36E-F7E25D2E72EF}.Release|x64.Build.0 = Release|Any CPU
|
||||
{39EF4DB0-9890-4CAD-A36E-F7E25D2E72EF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{39EF4DB0-9890-4CAD-A36E-F7E25D2E72EF}.Release|x86.Build.0 = Release|Any CPU
|
||||
<<<<<<< HEAD
|
||||
{193D6D9D-C1A0-459E-86CF-F207CDF0FC73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{193D6D9D-C1A0-459E-86CF-F207CDF0FC73}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{193D6D9D-C1A0-459E-86CF-F207CDF0FC73}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
|
@ -105,6 +108,20 @@ Global
|
|||
{193D6D9D-C1A0-459E-86CF-F207CDF0FC73}.Release|x64.Build.0 = Release|Any CPU
|
||||
{193D6D9D-C1A0-459E-86CF-F207CDF0FC73}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{193D6D9D-C1A0-459E-86CF-F207CDF0FC73}.Release|x86.Build.0 = Release|Any CPU
|
||||
=======
|
||||
{C726DD78-2D56-48D3-928A-D10226E3750B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C726DD78-2D56-48D3-928A-D10226E3750B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C726DD78-2D56-48D3-928A-D10226E3750B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C726DD78-2D56-48D3-928A-D10226E3750B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C726DD78-2D56-48D3-928A-D10226E3750B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C726DD78-2D56-48D3-928A-D10226E3750B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C726DD78-2D56-48D3-928A-D10226E3750B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C726DD78-2D56-48D3-928A-D10226E3750B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C726DD78-2D56-48D3-928A-D10226E3750B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C726DD78-2D56-48D3-928A-D10226E3750B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C726DD78-2D56-48D3-928A-D10226E3750B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C726DD78-2D56-48D3-928A-D10226E3750B}.Release|x86.Build.0 = Release|Any CPU
|
||||
>>>>>>> dde2c54... add support for parsing ASP.NET Core HTTP requests into CloudEvents
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<SolutionConfiguration>
|
||||
<Settings>
|
||||
<AllowParallelTestExecution>False</AllowParallelTestExecution>
|
||||
<SolutionConfigured>True</SolutionConfigured>
|
||||
</Settings>
|
||||
</SolutionConfiguration>
|
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CloudNative.CloudEvents\CloudNative.CloudEvents.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,120 @@
|
|||
// Copyright (c) Cloud Native Foundation.
|
||||
// Licensed under the Apache 2.0 license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace CloudNative.CloudEvents
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Net.Mime;
|
||||
|
||||
public static class HttpRequestExtension
|
||||
{
|
||||
const string HttpHeaderPrefix = "ce-";
|
||||
|
||||
const string SpecVersionHttpHeader1 = HttpHeaderPrefix + "cloudEventsVersion";
|
||||
|
||||
const string SpecVersionHttpHeader2 = HttpHeaderPrefix + "specversion";
|
||||
|
||||
static JsonEventFormatter jsonFormatter = new JsonEventFormatter();
|
||||
|
||||
/// <summary>
|
||||
/// Converts this HTTP request into a CloudEvent object, with the given extensions.
|
||||
/// </summary>
|
||||
/// <param name="httpRequest">HTTP request</param>
|
||||
/// <param name="extensions">List of extension instances</param>
|
||||
/// <returns>A CloudEvent instance or 'null' if the request message doesn't hold a CloudEvent</returns>
|
||||
public static CloudEvent ToCloudEvent(this HttpRequest httpRequest,
|
||||
params ICloudEventExtension[] extensions)
|
||||
{
|
||||
return ToCloudEvent(httpRequest, null, extensions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this HTTP request into a CloudEvent object, with the given extensions,
|
||||
/// overriding the formatter.
|
||||
/// </summary>
|
||||
/// <param name="httpRequest">HTTP request</param>
|
||||
/// <param name="formatter"></param>
|
||||
/// <param name="extensions">List of extension instances</param>
|
||||
/// <returns>A CloudEvent instance or 'null' if the request message doesn't hold a CloudEvent</returns>
|
||||
public static CloudEvent ToCloudEvent(this HttpRequest httpRequest,
|
||||
ICloudEventFormatter formatter = null,
|
||||
params ICloudEventExtension[] extensions)
|
||||
{
|
||||
if (httpRequest.ContentType != null &&
|
||||
httpRequest.ContentType.StartsWith(CloudEvent.MediaType,
|
||||
StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
// handle structured mode
|
||||
if (formatter == null)
|
||||
{
|
||||
// if we didn't get a formatter, pick one
|
||||
if (httpRequest.ContentType.EndsWith(JsonEventFormatter.MediaTypeSuffix,
|
||||
StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
formatter = jsonFormatter;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Unsupported CloudEvents encoding");
|
||||
}
|
||||
}
|
||||
|
||||
return formatter.DecodeStructuredEvent(httpRequest.Body, extensions);
|
||||
}
|
||||
else
|
||||
{
|
||||
CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
|
||||
if (httpRequest.Headers[SpecVersionHttpHeader1] != StringValues.Empty)
|
||||
{
|
||||
version = CloudEventsSpecVersion.V0_1;
|
||||
}
|
||||
|
||||
if (httpRequest.Headers[SpecVersionHttpHeader2] != StringValues.Empty)
|
||||
{
|
||||
version = httpRequest.Headers[SpecVersionHttpHeader2] == "0.2"
|
||||
? CloudEventsSpecVersion.V0_2
|
||||
: CloudEventsSpecVersion.Default;
|
||||
}
|
||||
|
||||
var cloudEvent = new CloudEvent(version, extensions);
|
||||
var attributes = cloudEvent.GetAttributes();
|
||||
foreach (var httpRequestHeader in httpRequest.Headers.Keys)
|
||||
{
|
||||
if (httpRequestHeader.Equals(SpecVersionHttpHeader1,
|
||||
StringComparison.InvariantCultureIgnoreCase) ||
|
||||
httpRequestHeader.Equals(SpecVersionHttpHeader2, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (httpRequestHeader.StartsWith(HttpHeaderPrefix, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
string headerValue = httpRequest.Headers[httpRequestHeader];
|
||||
if (headerValue.StartsWith("{") && headerValue.EndsWith("}") ||
|
||||
headerValue.StartsWith("[") && headerValue.EndsWith("]"))
|
||||
{
|
||||
attributes[httpRequestHeader.Substring(3)] =
|
||||
JsonConvert.DeserializeObject(headerValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
attributes[httpRequestHeader.Substring(3)] = headerValue;
|
||||
attributes[httpRequestHeader.Substring(3)] = headerValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cloudEvent.ContentType = httpRequest.ContentType != null
|
||||
? new ContentType(httpRequest.ContentType)
|
||||
: null;
|
||||
cloudEvent.Data = httpRequest.Body;
|
||||
return cloudEvent;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue