diff --git a/src/CloudNative.CloudEvents.AspNetCore/HttpRequestExtension.cs b/src/CloudNative.CloudEvents.AspNetCore/HttpRequestExtension.cs index 07b3d36..8163ce7 100644 --- a/src/CloudNative.CloudEvents.AspNetCore/HttpRequestExtension.cs +++ b/src/CloudNative.CloudEvents.AspNetCore/HttpRequestExtension.cs @@ -9,6 +9,7 @@ namespace CloudNative.CloudEvents using Newtonsoft.Json; using System; using System.IO; + using System.Net; using System.Net.Mime; using System.Text; using System.Threading.Tasks; @@ -106,7 +107,7 @@ namespace CloudNative.CloudEvents if (httpRequestHeader.StartsWith(HttpHeaderPrefix, StringComparison.InvariantCultureIgnoreCase)) { - string headerValue = httpRequest.Headers[httpRequestHeader]; + string headerValue = WebUtility.UrlDecode(httpRequest.Headers[httpRequestHeader]); // maps in headers have been abolished in 1.0 if (version != CloudEventsSpecVersion.V1_0 && headerValue.StartsWith("{") && headerValue.EndsWith("}") || diff --git a/src/CloudNative.CloudEvents/CloudEventContent.cs b/src/CloudNative.CloudEvents/CloudEventContent.cs index bc5061f..9da3c26 100644 --- a/src/CloudNative.CloudEvents/CloudEventContent.cs +++ b/src/CloudNative.CloudEvents/CloudEventContent.cs @@ -84,7 +84,7 @@ namespace CloudNative.CloudEvents { if (attribute.Value is string) { - Headers.Add("ce-" + attribute.Key, attribute.Value.ToString()); + Headers.Add("ce-" + attribute.Key, WebUtility.UrlEncode(attribute.Value.ToString())); } else if (attribute.Value is DateTime) { @@ -97,8 +97,9 @@ namespace CloudNative.CloudEvents else { Headers.Add("ce-" + attribute.Key, - Encoding.UTF8.GetString(jsonFormatter.EncodeAttribute(cloudEvent.SpecVersion, attribute.Key, attribute.Value, - cloudEvent.Extensions.Values))); + WebUtility.UrlEncode( + Encoding.UTF8.GetString(jsonFormatter.EncodeAttribute(cloudEvent.SpecVersion, attribute.Key, attribute.Value, + cloudEvent.Extensions.Values)))); } } } diff --git a/test/CloudNative.CloudEvents.IntegrationTests/AspNetCore/CloudEventControllerTests.cs b/test/CloudNative.CloudEvents.IntegrationTests/AspNetCore/CloudEventControllerTests.cs index cedcd6d..66cf621 100644 --- a/test/CloudNative.CloudEvents.IntegrationTests/AspNetCore/CloudEventControllerTests.cs +++ b/test/CloudNative.CloudEvents.IntegrationTests/AspNetCore/CloudEventControllerTests.cs @@ -29,7 +29,7 @@ namespace CloudNative.CloudEvents.IntegrationTests.AspNetCore // Arrange var expectedExtensionKey = "comexampleextension1"; var expectedExtensionValue = Guid.NewGuid().ToString(); - var cloudEvent = new CloudEvent("test-type", new Uri("urn:integration-tests")) + var cloudEvent = new CloudEvent("test-type-æøå", new Uri("urn:integration-tests")) { Id = Guid.NewGuid().ToString(), }; @@ -45,6 +45,7 @@ namespace CloudNative.CloudEvents.IntegrationTests.AspNetCore // Assert Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Contains(cloudEvent.Id, await result.Content.ReadAsStringAsync()); + Assert.Contains(cloudEvent.Type, await result.Content.ReadAsStringAsync()); Assert.Contains($"\"{expectedExtensionKey}\":\"{expectedExtensionValue}\"", await result.Content.ReadAsStringAsync()); } } diff --git a/test/CloudNative.CloudEvents.UnitTests/HttpTest.cs b/test/CloudNative.CloudEvents.UnitTests/HttpTest.cs index e0f7e2b..8288a90 100644 --- a/test/CloudNative.CloudEvents.UnitTests/HttpTest.cs +++ b/test/CloudNative.CloudEvents.UnitTests/HttpTest.cs @@ -276,7 +276,8 @@ namespace CloudNative.CloudEvents.UnitTests var attrs = cloudEvent.GetAttributes(); attrs["comexampleextension1"] = "value"; - + attrs["utf8examplevalue"] = "æøå"; + string ctx = Guid.NewGuid().ToString(); var content = new CloudEventContent(cloudEvent, ContentMode.Structured, new JsonEventFormatter()); content.Headers.Add(testContextHeader, ctx); @@ -298,6 +299,8 @@ namespace CloudNative.CloudEvents.UnitTests var attr = receivedCloudEvent.GetAttributes(); Assert.Equal("value", (string)attr["comexampleextension1"]); + Assert.Equal("%C3%A6%C3%B8%C3%A5", content.Headers.Single(h => h.Key == "ce-utf8examplevalue").Value.Single()); + Assert.Equal("æøå", (string)attr["utf8examplevalue"]); context.Response.StatusCode = (int)HttpStatusCode.NoContent; } catch (Exception e)