/// <summary>Processes the API request.</summary> /// <param name="context">The context.</param> /// <param name="httpcontext">The httpcontext.</param> /// <param name="contextResolver">The context resolver.</param> /// <param name="requestPipeline">The request pipeline.</param> /// <param name="defaultRequestConfiguration">The default request configuration.</param> /// <returns></returns> internal static async Task <bool> ProcessApiRequest( this ApiRequestContext context, HttpContext httpcontext, IApiRequestContextResolver contextResolver, IApiRequestPipeline requestPipeline, IDeepSleepRequestConfiguration defaultRequestConfiguration) { if (!context.RequestAborted.IsCancellationRequested) { await requestPipeline.Run(contextResolver); context.SetThreadCulure(); var responseDate = DateTimeOffset.UtcNow; context.Response.Date = responseDate; context.Response.AddHeader( name: "Date", value: responseDate.ToString("r"), append: false, allowMultiple: false); httpcontext.Response.Headers.Add("Date", responseDate.ToString("r")); // Sync up the expire header for nocache requests with the date header being used var contextExpiresHeader = context.Response.Headers.FirstOrDefault(h => h.Name == "Expires"); var expirationSeconds = context.Configuration?.CacheDirective?.ExpirationSeconds ?? defaultRequestConfiguration?.CacheDirective?.ExpirationSeconds ?? ApiRequestContext.GetDefaultRequestConfiguration().CacheDirective.ExpirationSeconds.Value; var cacheability = context.Configuration?.CacheDirective?.Cacheability ?? defaultRequestConfiguration?.CacheDirective?.Cacheability ?? ApiRequestContext.GetDefaultRequestConfiguration().CacheDirective.Cacheability.Value; if (contextExpiresHeader != null) { if (cacheability == HttpCacheType.NoCache && expirationSeconds > 0) { contextExpiresHeader.Value = responseDate.AddSeconds(-1).ToString("r"); } else { contextExpiresHeader.Value = responseDate.AddSeconds(expirationSeconds).ToString("r"); } } // Merge status code to the http response httpcontext.Response.StatusCode = context.Response.StatusCode; if (context.Response.ResponseWriter != null && context.Response.ResponseWriterOptions != null) { context.Response.AddHeader( name: "Content-Type", value: context.Response.ContentType.ToString(), append: false, allowMultiple: false); if (!string.IsNullOrWhiteSpace(context.Response.ContentLanguage)) { context.Response.AddHeader( name: "Content-Language", value: context.Response.ContentLanguage, append: false, allowMultiple: false); } if (!context.Request.IsHeadRequest()) { var contentLength = await context.Response.ResponseWriter.WriteType( stream : httpcontext.Response.Body, obj : context.Response.ResponseObject, context.Response.ResponseWriterOptions, (l) => { context.Response.ContentLength = l; context.Response.AddHeader( name: "Content-Length", value: l.ToString(CultureInfo.InvariantCulture), append: false, allowMultiple: false); AddHeadersToResponse(httpcontext, context); }).ConfigureAwait(false); context.Response.ContentLength = contentLength; } else { using (var ms = new MemoryStream()) { await context.Response.ResponseWriter.WriteType( ms, context.Response.ResponseObject, context.Response.ResponseWriterOptions).ConfigureAwait(false); context.Response.ResponseObject = null; context.Response.ContentLength = ms.Length; context.Response.AddHeader( name: "Content-Length", value: ms.Length.ToString(CultureInfo.InvariantCulture), append: false, allowMultiple: false); AddHeadersToResponse(httpcontext, context); } } } else { context.Response.ContentLength = 0; context.Response.AddHeader("Content-Length", "0"); AddHeadersToResponse(httpcontext, context); } context.Runtime.Duration.UtcEnd = DateTime.UtcNow; } return(true); }