Esempio n. 1
0
        public void DisposeRequestResources_WhenResourceListDoesNotExists_DoesNothing()
        {
            _request.Properties.Remove(HttpPropertyKeys.DisposableRequestResourcesKey);

            _request.DisposeRequestResources();

            Assert.False(_request.Properties.ContainsKey(HttpPropertyKeys.DisposableRequestResourcesKey));
        }
Esempio n. 2
0
        public static async Task<HttpResponseMessage> GetResponse(
            string requestUri,
            HttpMethod httpMethod,
            HttpContent requestContent,
            Action<HttpConfiguration, HttpServer> registerOData,
            IEnumerable<KeyValuePair<string, string>> headers = null)
        {
            using (HttpConfiguration config = new HttpConfiguration())
            {
                using (HttpServer server = new HttpServer(config))
                using (HttpMessageInvoker client = new HttpMessageInvoker(server))
                {
                    registerOData(config, server);
                    HttpRequestMessage request = new HttpRequestMessage(httpMethod, requestUri);
                    try
                    {
                        request.Content = requestContent;
                        if (headers != null)
                        {
                            foreach (var header in headers)
                            {
                                request.Headers.Add(header.Key, header.Value);
                            }
                        }

                        return await client.SendAsync(request, CancellationToken.None);
                    }
                    finally
                    {
                        request.DisposeRequestResources();
                        request.Dispose();
                    }
                }
            }
        }
        public void DisposeRequestResources_WhenResourceListExists_DisposesResourceAndClearsReferences()
        {
            HttpRequestMessage request        = CreateRequest();
            Mock <IDisposable> disposableMock = new Mock <IDisposable>();
            IDisposable        disposable     = disposableMock.Object;
            var list = new List <IDisposable> {
                disposable
            };

            request.Properties[HttpPropertyKeys.DisposableRequestResourcesKey] = list;

            request.DisposeRequestResources();

            disposableMock.Verify(d => d.Dispose());
            Assert.Empty(list);
        }
        public void DisposeRequestResources_WhenResourcesDisposeMethodThrowsException_IgnoresExceptionsAndContinuesDisposingOtherResources()
        {
            HttpRequestMessage request = CreateRequest();
            Mock <IDisposable> throwingDisposableMock = new Mock <IDisposable>();

            throwingDisposableMock.Setup(d => d.Dispose()).Throws(new Exception());
            Mock <IDisposable> disposableMock = new Mock <IDisposable>();
            IDisposable        disposable     = disposableMock.Object;
            var list = new List <IDisposable> {
                throwingDisposableMock.Object, disposable
            };

            request.Properties[HttpPropertyKeys.DisposableRequestResourcesKey] = list;

            request.DisposeRequestResources();

            throwingDisposableMock.Verify(d => d.Dispose());
            disposableMock.Verify(d => d.Dispose());
            Assert.Empty(list);
        }
        public static async Task<HttpResponseMessage> GetResponseWithContentValidation(
            string requestUri,
            HttpMethod httpMethod,
            HttpContent requestContent,
            Action<HttpConfiguration, HttpServer> registerOData,
            HttpStatusCode expectedStatusCode,
            string baselineFileName,
            Func<string, string> postProcessContentHandler = null,
            IEnumerable<KeyValuePair<string, string>> headers = null)
        {
            using (HttpConfiguration config = new HttpConfiguration())
            {
                using (HttpServer server = new HttpServer(config))
                using (HttpMessageInvoker client = new HttpMessageInvoker(server))
                {
                    registerOData(config, server);
                    HttpRequestMessage request = new HttpRequestMessage(httpMethod, requestUri);
                    try
                    {
                        request.Content = requestContent;
                        if (headers != null)
                        {
                            foreach (var header in headers)
                            {
                                request.Headers.Add(header.Key, header.Value);
                            }
                        }

                        var response = await client.SendAsync(request, CancellationToken.None);
                        await CheckResponse(response, expectedStatusCode, baselineFileName, postProcessContentHandler);
                        return response;
                    }
                    finally
                    {
                        request.DisposeRequestResources();
                        request.Dispose();
                    }
                }
            }
        }
        /// <summary>
        /// Converts a <see cref="HttpResponseMessage"/> to an <see cref="HttpResponseBase"/> and disposes the 
        /// <see cref="HttpResponseMessage"/> and <see cref="HttpRequestMessage"/> upon completion.
        /// </summary>
        /// <param name="httpContextBase">The HTTP context base.</param>
        /// <param name="response">The response to convert.</param>
        /// <param name="request">The request (which will be disposed).</param>
        /// <returns>A <see cref="Task"/> representing the conversion of an <see cref="HttpResponseMessage"/> to an <see cref="HttpResponseBase"/>
        /// including writing out any entity body.</returns>
        internal static Task ConvertResponse(HttpContextBase httpContextBase, HttpResponseMessage response, HttpRequestMessage request)
        {
            Contract.Assert(httpContextBase != null);
            Contract.Assert(response != null);
            Contract.Assert(request != null);

            HttpResponseBase httpResponseBase = httpContextBase.Response;
            httpResponseBase.StatusCode = (int)response.StatusCode;
            httpResponseBase.StatusDescription = response.ReasonPhrase;
            httpResponseBase.TrySkipIisCustomErrors = true;
            EnsureSuppressFormsAuthenticationRedirect(httpContextBase);
            CopyHeaders(response.Headers, httpContextBase);
            CacheControlHeaderValue cacheControl = response.Headers.CacheControl;

            // TODO 335085: Consider this when coming up with our caching story
            if (cacheControl == null)
            {
                // DevDiv2 #332323. ASP.NET by default always emits a cache-control: private header.
                // However, we don't want requests to be cached by default.
                // If nobody set an explicit CacheControl then explicitly set to no-cache to override the
                // default behavior. This will cause the following response headers to be emitted:
                //     Cache-Control: no-cache
                //     Pragma: no-cache
                //     Expires: -1
                httpContextBase.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            }

            Task responseTask = null;
            bool isBuffered = false;

            if (response.Content != null)
            {
                CopyHeaders(response.Content.Headers, httpContextBase);

                // Select output buffering by the kind of content
                isBuffered = IsOutputBufferingNecessary(response.Content);
                httpResponseBase.BufferOutput = isBuffered;

                responseTask = response.Content.CopyToAsync(httpResponseBase.OutputStream);
            }
            else
            {
                responseTask = TaskHelpers.Completed();
            }

            return responseTask
                .Catch((info) =>
                {
                    if (isBuffered)
                    {
                        // Failure during the CopyToAsync needs to stop any partial content from
                        // reaching the client.  If it was during a buffered write, we will give
                        // them InternalServerError with zero-length content.
                        httpResponseBase.SuppressContent = true;
                        httpResponseBase.Clear();
                        httpResponseBase.ClearContent();
                        httpResponseBase.ClearHeaders();
                        httpResponseBase.StatusCode = (int)Net.HttpStatusCode.InternalServerError;
                    }
                    else
                    {
                        // Any failure in non-buffered mode has already written out StatusCode and possibly content.
                        // This means the client will receive an OK but the content is incomplete.
                        // The proper action here is to abort the connection, but HttpResponse.Abort is a 4.5 feature.
                        // TODO: DevDiv bug #381233 -- call HttpResponse.Abort when it becomes available
                        httpResponseBase.Close();
                    }

                    // We do not propagate any errors up, or we will get the
                    // standard ASP.NET html page.   We want empty content or
                    // a closed connection.
                    return info.Handled();
                })
                .Finally(
                () =>
                {
                    request.DisposeRequestResources();
                    request.Dispose();
                    response.Dispose();
                });
        }
        public void ApiControllerPutsSelfInRequestResourcesToBeDisposed()
        {
            // Arrange
            var config = new HttpConfiguration();
            config.Routes.MapHttpRoute("default", "", new { controller = "SpyDispose" });
            var server = new HttpServer(config);
            var invoker = new HttpMessageInvoker(server);
            var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/");
            invoker.SendAsync(request, CancellationToken.None).WaitUntilCompleted();

            // Act
            request.DisposeRequestResources();

            // Assert
            Assert.True(SpyDisposeController.DisposeWasCalled);
        }
        /// <summary>
        /// Converts a <see cref="HttpResponseMessage"/> to an <see cref="HttpResponseBase"/> and disposes the 
        /// <see cref="HttpResponseMessage"/> and <see cref="HttpRequestMessage"/> upon completion.
        /// </summary>
        /// <param name="httpContextBase">The HTTP context base.</param>
        /// <param name="response">The response to convert.</param>
        /// <param name="request">The request (which will be disposed).</param>
        /// <returns>A <see cref="Task"/> representing the conversion of an <see cref="HttpResponseMessage"/> to an <see cref="HttpResponseBase"/>
        /// including writing out any entity body.</returns>
        internal static async Task ConvertResponse(HttpContextBase httpContextBase, HttpResponseMessage response, HttpRequestMessage request)
        {
            Contract.Assert(httpContextBase != null);
            Contract.Assert(request != null);

            // A null response creates a 500 with no content
            if (response == null)
            {
                CreateEmptyErrorResponse(httpContextBase.Response);
                return;
            }

            CopyResponseStatusAndHeaders(httpContextBase, response);

            // TODO 335085: Consider this when coming up with our caching story
            if (response.Headers.CacheControl == null)
            {
                // DevDiv2 #332323. ASP.NET by default always emits a cache-control: private header.
                // However, we don't want requests to be cached by default.
                // If nobody set an explicit CacheControl then explicitly set to no-cache to override the
                // default behavior. This will cause the following response headers to be emitted:
                //     Cache-Control: no-cache
                //     Pragma: no-cache
                //     Expires: -1
                httpContextBase.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            }

            // Asynchronously write the response body.  If there is no body, we use
            // a completed task to share the Finally() below.
            // The response-writing task will not fault -- it handles errors internally.
            try
            {
                if (response.Content != null)
                {
                    await WriteResponseContentAsync(httpContextBase, response, request);
                }
            }
            finally
            {
                request.DisposeRequestResources();
                request.Dispose();
                response.Dispose();
            }
        }
        public void DisposeRequestResources_WhenRequestParameterIsNull_Throws()
        {
            HttpRequestMessage request = null;

            Assert.ThrowsArgumentNull(() => request.DisposeRequestResources(), "request");
        }