Example #1
0
 internal HttpRequest(ITraceable trace, HeaderRequestParameters parameters, Func <Stream, Task> writeBody)
 {
     Context   = trace.Context;
     URI       = parameters.URI;
     WriteBody = writeBody;
     Headers   = parameters.Headers;
     Method    = parameters.Method;
 }
 internal HttpRequest(ITraceable trace, HeaderRequestParameters parameters, Stream body)
 {
     TraceId = trace.TraceId;
     Context = trace.Context;
     URI     = parameters.URI;
     Body    = body;
     Headers = parameters.Headers;
     Method  = parameters.Method;
 }
        /// <inheritdoc />
        public ISerializedResult Serialize(IResult result, IContentTypeProvider contentTypeProvider)
        {
            switch (result)
            {
            case Report report:
                contentTypeProvider.SerializeCollection(new[] { report.ReportBody }, report.Body, report.Request);
                return(report);

            case Head head:
                head.Headers.EntityCount = head.EntityCount.ToString();
                return(head);

            case IEntities <object> entities:

                ISerializedResult SerializeEntities()
                {
                    var entityCount = contentTypeProvider.SerializeCollection((dynamic)entities, entities.Body, entities.Request);

                    if (entityCount == 0)
                    {
                        return(new NoContent(entities.Request));
                    }
                    entities.Body.Seek(0, SeekOrigin.Begin);
                    entities.Headers.EntityCount = entityCount.ToString();
                    entities.EntityCount         = entityCount;
                    if (entities.IsPaged)
                    {
                        var pager = entities.GetNextPageLink();
                        entities.Headers.Pager = pager.ToUriString();
                    }
                    entities.SetContentDisposition(contentTypeProvider.ContentDispositionFileExtension);
                    return(entities);
                }

                if (entities.Request.Headers.Destination == null)
                {
                    return(SerializeEntities());
                }
                try
                {
                    var parameters = new HeaderRequestParameters(entities.Request.Headers.Destination);
                    if (parameters.IsInternal)
                    {
                        var internalRequest    = entities.Context.CreateRequest(parameters.URI, parameters.Method, null, parameters.Headers);
                        var serializedEntities = SerializeEntities();
                        if (!(serializedEntities is Content content))
                        {
                            return(serializedEntities);
                        }
                        internalRequest.SetBody(content.Body);
                        return(internalRequest.Evaluate().Serialize());
                    }
                    var serialized      = SerializeEntities();
                    var externalRequest = new HttpRequest(serialized, parameters, serialized.Body);
                    var response        = externalRequest.GetResponseAsync().Result
                                          ?? throw new InvalidExternalDestination(externalRequest, "No response");
                    if (response.StatusCode >= HttpStatusCode.BadRequest)
                    {
                        throw new InvalidExternalDestination(externalRequest,
                                                             $"Received {response.StatusCode.ToCode()} - {response.StatusDescription}. {response.Headers.Info}");
                    }
                    if (serialized.Headers.AccessControlAllowOrigin is string h)
                    {
                        response.Headers.AccessControlAllowOrigin = h;
                    }
                    return(new ExternalDestinationResult(entities.Request, response));
                }
                catch (HttpRequestException re)
                {
                    throw new InvalidSyntax(ErrorCodes.InvalidDestination, $"{re.Message} in the Destination header");
                }

            default: return(result as ISerializedResult);
            }
        }