public async Task CopyToHttpListenerResponseAsync_StructuredMode() { var cloudEvent = new CloudEvent { Data = "plain text", DataContentType = "text/plain" }.PopulateRequiredAttributes(); var formatter = new JsonEventFormatter(); var response = await GetResponseAsync( async context => await cloudEvent.CopyToHttpListenerResponseAsync(context.Response, ContentMode.Structured, formatter)); response.EnsureSuccessStatusCode(); var content = response.Content; Assert.Equal(MimeUtilities.MediaType + "+json", content.Headers.ContentType.MediaType); var bytes = await content.ReadAsByteArrayAsync(); var parsed = new JsonEventFormatter().DecodeStructuredModeMessage(bytes, MimeUtilities.ToContentType(content.Headers.ContentType), extensionAttributes: null); AssertCloudEventsEqual(cloudEvent, parsed); Assert.Equal(cloudEvent.Data, parsed.Data); // We populate headers even though we don't strictly need to; let's validate that. Assert.Equal("1.0", response.Headers.GetValues("ce-specversion").Single()); Assert.Equal(cloudEvent.Type, response.Headers.GetValues("ce-type").Single()); Assert.Equal(cloudEvent.Id, response.Headers.GetValues("ce-id").Single()); Assert.Equal(CloudEventAttributeType.UriReference.Format(cloudEvent.Source !), response.Headers.GetValues("ce-source").Single()); // We don't populate the data content type header Assert.False(response.Headers.Contains("ce-datacontenttype")); }
public async Task ToHttpContent_Batch() { var batch = CreateSampleBatch(); var formatter = new JsonEventFormatter(); var content = batch.ToHttpContent(formatter); var bytes = await content.ReadAsByteArrayAsync(); var parsedBatch = formatter.DecodeBatchModeMessage(bytes, MimeUtilities.ToContentType(content.Headers.ContentType), extensionAttributes: null); AssertBatchesEqual(batch, parsedBatch); }
private static async Task <CloudEvent> ToCloudEventInternalAsync(HttpHeaders headers, HttpContent content, CloudEventFormatter formatter, IEnumerable <CloudEventAttribute>?extensionAttributes, string paramName) { Validation.CheckNotNull(formatter, nameof(formatter)); if (HasCloudEventsContentType(content)) { var stream = await content.ReadAsStreamAsync().ConfigureAwait(false); return(await formatter.DecodeStructuredModeMessageAsync(stream, MimeUtilities.ToContentType(content.Headers.ContentType), extensionAttributes).ConfigureAwait(false)); } else { string?versionId = headers.Contains(HttpUtilities.SpecVersionHttpHeader) ? headers.GetValues(HttpUtilities.SpecVersionHttpHeader).First() : null; if (versionId is null) { throw new ArgumentException($"Request does not represent a CloudEvent. It has neither a {HttpUtilities.SpecVersionHttpHeader} header, nor a suitable content type.", nameof(paramName)); } var version = CloudEventsSpecVersion.FromVersionId(versionId) ?? throw new ArgumentException($"Unknown CloudEvents spec version '{versionId}'", paramName); var cloudEvent = new CloudEvent(version, extensionAttributes); foreach (var header in headers) { string?attributeName = HttpUtilities.GetAttributeNameFromHeaderName(header.Key); if (attributeName is null || attributeName == CloudEventsSpecVersion.SpecVersionAttribute.Name) { continue; } string attributeValue = HttpUtilities.DecodeHeaderValue(header.Value.First()); cloudEvent.SetAttributeFromString(attributeName, attributeValue); } if (content is object) { // TODO: Should this just be the media type? We probably need to take a full audit of this... cloudEvent.DataContentType = content.Headers?.ContentType?.ToString(); var data = await content.ReadAsByteArrayAsync().ConfigureAwait(false); formatter.DecodeBinaryModeEventData(data, cloudEvent); } return(Validation.CheckCloudEventArgument(cloudEvent, paramName)); } }
private static async Task <IReadOnlyList <CloudEvent> > ToCloudEventBatchInternalAsync(HttpContent content, CloudEventFormatter formatter, IEnumerable <CloudEventAttribute>?extensionAttributes, string paramName) { Validation.CheckNotNull(formatter, nameof(formatter)); if (HasCloudEventsBatchContentType(content)) { var stream = await content.ReadAsStreamAsync().ConfigureAwait(false); return(await formatter .DecodeBatchModeMessageAsync(stream, MimeUtilities.ToContentType(content.Headers.ContentType), extensionAttributes) .ConfigureAwait(false)); } else { throw new ArgumentException("HTTP message does not represent a CloudEvents batch.", paramName); } }
public void ContentTypeConversions(string text) { var originalContentType = new ContentType(text); var header = MimeUtilities.ToMediaTypeHeaderValue(originalContentType); AssertEqualParts(text, header !.ToString()); var convertedContentType = MimeUtilities.ToContentType(header); AssertEqualParts(originalContentType.ToString(), convertedContentType !.ToString()); // Conversions can end up reordering the parameters. In reality we're only // likely to end up with a media type and charset, but our tests use more parameters. // This just makes them deterministic. void AssertEqualParts(string expected, string actual) { expected = string.Join(";", expected.Split(";").OrderBy(x => x)); actual = string.Join(";", actual.Split(";").OrderBy(x => x)); Assert.Equal(expected, actual); } }
public async Task CopyToHttpListenerResponseAsync_Batch() { var batch = CreateSampleBatch(); var response = await GetResponseAsync(async context => { await batch.CopyToHttpListenerResponseAsync(context.Response, new JsonEventFormatter()); context.Response.StatusCode = 200; }); response.EnsureSuccessStatusCode(); var content = response.Content; Assert.Equal(MimeUtilities.BatchMediaType + "+json", content.Headers.ContentType.MediaType); var bytes = await content.ReadAsByteArrayAsync(); var parsedBatch = new JsonEventFormatter().DecodeBatchModeMessage(bytes, MimeUtilities.ToContentType(content.Headers.ContentType), extensionAttributes: null); AssertBatchesEqual(batch, parsedBatch); }
public void ContentTypeConversions_Null() { Assert.Null(MimeUtilities.ToMediaTypeHeaderValue(default(ContentType))); Assert.Null(MimeUtilities.ToContentType(default(MediaTypeHeaderValue))); }