/// <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">The event formatter to use to process the request body.</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 async ValueTask <CloudEvent> ReadCloudEventAsync(this HttpRequest httpRequest,
                                                                       ICloudEventFormatter formatter,
                                                                       params CloudEventAttribute[] extensionAttributes)
        {
            if (HasCloudEventsContentType(httpRequest))
            {
                // TODO: Handle formatter being null
                return(await formatter.DecodeStructuredEventAsync(httpRequest.Body, extensionAttributes).ConfigureAwait(false));
            }
            else
            {
                var headers = httpRequest.Headers;
                CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
                if (headers.TryGetValue(HttpUtilities.SpecVersionHttpHeader, out var values))
                {
                    string versionId = values.First();
                    version = CloudEventsSpecVersion.FromVersionId(versionId);
                }

                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);
                }

                cloudEvent.DataContentType = httpRequest.ContentType;
                if (httpRequest.Body is Stream body)
                {
                    // TODO: This is a bit ugly.
                    var memoryStream = new MemoryStream();
                    await body.CopyToAsync(memoryStream).ConfigureAwait(false);

                    if (memoryStream.Length != 0)
                    {
                        cloudEvent.Data = formatter.DecodeData(memoryStream.ToArray(), cloudEvent.DataContentType);
                    }
                }
                return(cloudEvent);
            }
        }
        /// <summary>
        /// Converts this listener request into a CloudEvent object, with the given extension attributes.
        /// </summary>
        /// <param name="httpListenerRequest">Listener 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 HttpListenerRequest httpListenerRequest,
                                              ICloudEventFormatter formatter, params CloudEventAttribute[] extensionAttributes)
        {
            if (HasCloudEventsContentType(httpListenerRequest))
            {
                // FIXME: Handle no formatter being specified.
                return(formatter.DecodeStructuredEvent(httpListenerRequest.InputStream, extensionAttributes));
            }
            else
            {
                CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
                if (httpListenerRequest.Headers[HttpUtilities.SpecVersionHttpHeader] is string versionId)
                {
                    version = CloudEventsSpecVersion.FromVersionId(versionId);
                }

                var cloudEvent = new CloudEvent(version, extensionAttributes);
                var headers    = httpListenerRequest.Headers;
                foreach (var key in headers.AllKeys)
                {
                    string attributeName = HttpUtilities.GetAttributeNameFromHeaderName(key);
                    if (attributeName is null || attributeName == CloudEventsSpecVersion.SpecVersionAttribute.Name)
                    {
                        continue;
                    }
                    string attributeValue = HttpUtilities.DecodeHeaderValue(headers[key]);
                    cloudEvent.SetAttributeFromString(attributeName, attributeValue);
                }

                // TODO: Check that this doesn't come through as a header already
                cloudEvent.DataContentType = httpListenerRequest.ContentType;

                // TODO: This is a bit ugly.
                var memoryStream = new MemoryStream();
                httpListenerRequest.InputStream.CopyTo(memoryStream);
                if (memoryStream.Length != 0)
                {
                    cloudEvent.Data = formatter.DecodeData(memoryStream.ToArray(), cloudEvent.DataContentType);
                }
                return(cloudEvent);
            }
        }
Esempio n. 3
0
        private static async Task <CloudEvent> ToCloudEventInternalAsync(HttpHeaders headers, HttpContent content,
                                                                         ICloudEventFormatter formatter, IEnumerable <CloudEventAttribute> extensionAttributes)
        {
            if (HasCloudEventsContentType(content))
            {
                // FIXME: Handle no formatter being specified.
                var stream = await content.ReadAsStreamAsync().ConfigureAwait(false);

                return(await formatter.DecodeStructuredEventAsync(stream, extensionAttributes).ConfigureAwait(false));
            }
            else
            {
                CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
                if (headers.Contains(HttpUtilities.SpecVersionHttpHeader))
                {
                    string versionId = headers.GetValues(HttpUtilities.SpecVersionHttpHeader).First();
                    version = CloudEventsSpecVersion.FromVersionId(versionId);
                }

                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);

                    cloudEvent.Data = formatter.DecodeData(data, cloudEvent.DataContentType);
                }
                return(cloudEvent);
            }
        }