/// <summary> /// Converts a CloudEvent to <see cref="HttpContent"/>. /// </summary> /// <param name="cloudEvent">The CloudEvent to convert. Must not be null, and must be a valid CloudEvent.</param> /// <param name="contentMode">Content mode. Structured or binary.</param> /// <param name="formatter">The formatter to use within the conversion. Must not be null.</param> public static HttpContent ToHttpContent(this CloudEvent cloudEvent, ContentMode contentMode, CloudEventFormatter formatter) { Validation.CheckCloudEventArgument(cloudEvent, nameof(cloudEvent)); Validation.CheckNotNull(formatter, nameof(formatter)); ReadOnlyMemory <byte> content; // The content type to include in the ContentType header - may be the data content type, or the formatter's content type. ContentType?contentType; switch (contentMode) { case ContentMode.Structured: content = formatter.EncodeStructuredModeMessage(cloudEvent, out contentType); break; case ContentMode.Binary: content = formatter.EncodeBinaryModeEventData(cloudEvent); contentType = MimeUtilities.CreateContentTypeOrNull(formatter.GetOrInferDataContentType(cloudEvent)); break; default: throw new ArgumentOutOfRangeException(nameof(contentMode), $"Unsupported content mode: {contentMode}"); } ByteArrayContent ret = ToByteArrayContent(content); if (contentType is object) { ret.Headers.ContentType = MimeUtilities.ToMediaTypeHeaderValue(contentType); } else if (content.Length != 0) { throw new ArgumentException(Strings.ErrorContentTypeUnspecified, nameof(cloudEvent)); } // Map headers in either mode. // Including the headers in structured mode is optional in the spec (as they're already within the body) but // can be useful. ret.Headers.Add(HttpUtilities.SpecVersionHttpHeader, HttpUtilities.EncodeHeaderValue(cloudEvent.SpecVersion.VersionId)); foreach (var attributeAndValue in cloudEvent.GetPopulatedAttributes()) { CloudEventAttribute attribute = attributeAndValue.Key; string headerName = HttpUtilities.HttpHeaderPrefix + attribute.Name; object value = attributeAndValue.Value; // Skip the data content type attribute in binary mode, because it's already in the content type header. if (attribute == cloudEvent.SpecVersion.DataContentTypeAttribute && contentMode == ContentMode.Binary) { continue; } else { string headerValue = HttpUtilities.EncodeHeaderValue(attribute.Format(value)); ret.Headers.Add(headerName, headerValue); } } return(ret); }
private void MapHeaders(CloudEvent cloudEvent, bool includeDataContentType) { Headers.Add(HttpUtilities.SpecVersionHttpHeader, HttpUtilities.EncodeHeaderValue(cloudEvent.SpecVersion.VersionId)); foreach (var attributeAndValue in cloudEvent.GetPopulatedAttributes()) { CloudEventAttribute attribute = attributeAndValue.Key; string headerName = HttpUtilities.HttpHeaderPrefix + attribute.Name; object value = attributeAndValue.Value; // Only map the data content type attribute to a header if we've been asked to if (attribute == cloudEvent.SpecVersion.DataContentTypeAttribute && !includeDataContentType) { continue; } else { string headerValue = HttpUtilities.EncodeHeaderValue(attribute.Format(value)); Headers.Add(headerName, headerValue); } } }