Inheritance: System.IO.Stream
Exemple #1
0
        private HttpResponseMessage CreateResponseMessage(SafeWinHttpHandle requestHandle, HttpRequestMessage request)
        {
            var response = new HttpResponseMessage();
            bool useDeflateDecompression = false;
            bool useGzipDecompression = false;

            // Get HTTP version, status code, reason phrase from the response headers.
            string version = GetResponseHeaderStringInfo(requestHandle, Interop.WinHttp.WINHTTP_QUERY_VERSION);
            if (string.Compare("HTTP/1.1", version, StringComparison.OrdinalIgnoreCase) == 0)
            {
                response.Version = new Version(1, 1);
            }
            else if (string.Compare("HTTP/1.0", version, StringComparison.OrdinalIgnoreCase) == 0)
            {
                response.Version = new Version(1, 0);
            }
            else
            {
                response.Version = null;
            }

            response.StatusCode = (HttpStatusCode)GetResponseHeaderNumberInfo(
                requestHandle,
                Interop.WinHttp.WINHTTP_QUERY_STATUS_CODE);
            response.ReasonPhrase = GetResponseHeaderStringInfo(
                requestHandle,
                Interop.WinHttp.WINHTTP_QUERY_STATUS_TEXT);

            if (_doManualDecompressionCheck)
            {
                string contentEncoding = GetResponseHeaderStringInfo(
                    requestHandle,
                    Interop.WinHttp.WINHTTP_QUERY_CONTENT_ENCODING);
                if (!string.IsNullOrEmpty(contentEncoding))
                {
                    if (contentEncoding.IndexOf(EncodingNameDeflate, StringComparison.OrdinalIgnoreCase) > -1)
                    {
                        useDeflateDecompression = true;
                    }
                    else if (contentEncoding.IndexOf(EncodingNameGzip, StringComparison.OrdinalIgnoreCase) > -1)
                    {
                        useGzipDecompression = true;
                    }
                }
            }

            // Create response stream and wrap it in a StreamContent object.
            var responseStream = new WinHttpResponseStream(requestHandle);
            Stream decompressedStream = responseStream;
            if (_doManualDecompressionCheck)
            {
                if (useDeflateDecompression)
                {
                    decompressedStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                }
                else if (useGzipDecompression)
                {
                    decompressedStream = new GZipStream(responseStream, CompressionMode.Decompress);
                }
            }

            var content = new StreamContent(decompressedStream);

            response.Content = content;
            response.RequestMessage = request;

            // Parse raw response headers and place them into response message.
            ParseResponseHeaders(requestHandle, response, useDeflateDecompression || useGzipDecompression);

            // Store response header cookies into custom CookieContainer.
            if (_cookieUsePolicy == CookieUsePolicy.UseSpecifiedCookieContainer)
            {
                Debug.Assert(_cookieContainer != null);

                if (response.Headers.Contains(HeaderNameSetCookie))
                {
                    IEnumerable<string> cookieHeaders = response.Headers.GetValues(HeaderNameSetCookie);
                    foreach (var cookieHeader in cookieHeaders)
                    {
                        try
                        {
                            _cookieContainer.SetCookies(request.RequestUri, cookieHeader);
                        }
                        catch (CookieException)
                        {
                            // We ignore malformed cookies in the response.
                        }
                    }
                }
            }

            // Since the headers have been read, set the "receive" timeout to be based on each read
            // call of the response body data. WINHTTP_OPTION_RECEIVE_TIMEOUT sets a timeout on each
            // lower layer winsock read.
            uint optionData = (uint)_receiveDataTimeout.TotalMilliseconds;
            SetWinHttpOption(requestHandle, Interop.WinHttp.WINHTTP_OPTION_RECEIVE_TIMEOUT, ref optionData);

            return response;
        }
        public static HttpResponseMessage CreateResponseMessage(
            WinHttpRequestState state,
            bool doManualDecompressionCheck)
        {
            HttpRequestMessage request = state.RequestMessage;
            SafeWinHttpHandle requestHandle = state.RequestHandle;
            CookieUsePolicy cookieUsePolicy = state.Handler.CookieUsePolicy;
            CookieContainer cookieContainer = state.Handler.CookieContainer;
            var response = new HttpResponseMessage();
            bool stripEncodingHeaders = false;

            // Get HTTP version, status code, reason phrase from the response headers.
            string version = GetResponseHeaderStringInfo(requestHandle, Interop.WinHttp.WINHTTP_QUERY_VERSION);
            if (string.Compare("HTTP/1.1", version, StringComparison.OrdinalIgnoreCase) == 0)
            {
                response.Version = HttpVersion.Version11;
            }
            else if (string.Compare("HTTP/1.0", version, StringComparison.OrdinalIgnoreCase) == 0)
            {
                response.Version = HttpVersion.Version10;
            }
            else
            {
                response.Version = HttpVersion.Unknown;
            }

            response.StatusCode = (HttpStatusCode)GetResponseHeaderNumberInfo(
                requestHandle,
                Interop.WinHttp.WINHTTP_QUERY_STATUS_CODE);
            response.ReasonPhrase = GetResponseHeaderStringInfo(
                requestHandle,
                Interop.WinHttp.WINHTTP_QUERY_STATUS_TEXT);

            // Create response stream and wrap it in a StreamContent object.
            var responseStream = new WinHttpResponseStream(state);
            Stream decompressedStream = responseStream;

            if (doManualDecompressionCheck)
            {
                string contentEncoding = GetResponseHeaderStringInfo(
                    requestHandle,
                    Interop.WinHttp.WINHTTP_QUERY_CONTENT_ENCODING);
                if (!string.IsNullOrEmpty(contentEncoding))
                {
                    if (contentEncoding.IndexOf(EncodingNameDeflate, StringComparison.OrdinalIgnoreCase) > -1)
                    {
                        decompressedStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                        stripEncodingHeaders = true;
                    }
                    else if (contentEncoding.IndexOf(EncodingNameGzip, StringComparison.OrdinalIgnoreCase) > -1)
                    {
                        decompressedStream = new GZipStream(responseStream, CompressionMode.Decompress);
                        stripEncodingHeaders = true;
                    }
                }
            }

            var content = new StreamContent(decompressedStream);

            response.Content = content;
            response.RequestMessage = request;

            // Parse raw response headers and place them into response message.
            ParseResponseHeaders(requestHandle, response, stripEncodingHeaders);

            // Store response header cookies into custom CookieContainer.
            if (cookieUsePolicy == CookieUsePolicy.UseSpecifiedCookieContainer)
            {
                Debug.Assert(cookieContainer != null);

                if (response.Headers.Contains(HeaderNameSetCookie))
                {
                    IEnumerable<string> cookieHeaders = response.Headers.GetValues(HeaderNameSetCookie);
                    foreach (var cookieHeader in cookieHeaders)
                    {
                        try
                        {
                            cookieContainer.SetCookies(request.RequestUri, cookieHeader);
                        }
                        catch (CookieException)
                        {
                            // We ignore malformed cookies in the response.
                        }
                    }
                }
            }

            return response;
        }
Exemple #3
0
        public static HttpResponseMessage CreateResponseMessage(
            WinHttpRequestState state,
            bool doManualDecompressionCheck)
        {
            HttpRequestMessage request         = state.RequestMessage;
            SafeWinHttpHandle  requestHandle   = state.RequestHandle;
            CookieUsePolicy    cookieUsePolicy = state.Handler.CookieUsePolicy;
            CookieContainer    cookieContainer = state.Handler.CookieContainer;
            var  response             = new HttpResponseMessage();
            bool stripEncodingHeaders = false;

            // Create a single buffer to use for all subsequent WinHttpQueryHeaders string interop calls.
            // This buffer is the length needed for WINHTTP_QUERY_RAW_HEADERS_CRLF, which includes the status line
            // and all headers separated by CRLF, so it should be large enough for any individual status line or header queries.
            int bufferLength = GetResponseHeaderCharBufferLength(requestHandle, Interop.WinHttp.WINHTTP_QUERY_RAW_HEADERS_CRLF);

            char[] buffer = ArrayPool <char> .Shared.Rent(bufferLength);

            try
            {
                // Get HTTP version, status code, reason phrase from the response headers.

                if (IsResponseHttp2(requestHandle))
                {
                    response.Version = WinHttpHandler.HttpVersion20;
                }
                else
                {
                    int versionLength = GetResponseHeader(requestHandle, Interop.WinHttp.WINHTTP_QUERY_VERSION, buffer);
                    response.Version =
                        CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase("HTTP/1.1", buffer, 0, versionLength) ? HttpVersionInternal.Version11 :
                        CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase("HTTP/1.0", buffer, 0, versionLength) ? HttpVersionInternal.Version10 :
                        WinHttpHandler.HttpVersionUnknown;
                }

                response.StatusCode = (HttpStatusCode)GetResponseHeaderNumberInfo(
                    requestHandle,
                    Interop.WinHttp.WINHTTP_QUERY_STATUS_CODE);

                int reasonPhraseLength = GetResponseHeader(requestHandle, Interop.WinHttp.WINHTTP_QUERY_STATUS_TEXT, buffer);
                response.ReasonPhrase = reasonPhraseLength > 0 ?
                                        GetReasonPhrase(response.StatusCode, buffer, reasonPhraseLength) :
                                        string.Empty;

                // Create response stream and wrap it in a StreamContent object.
                var responseStream = new WinHttpResponseStream(requestHandle, state);
                state.RequestHandle = null; // ownership successfully transfered to WinHttpResponseStram.
                Stream decompressedStream = responseStream;

                if (doManualDecompressionCheck)
                {
                    int contentEncodingStartIndex = 0;
                    int contentEncodingLength     = GetResponseHeader(
                        requestHandle,
                        Interop.WinHttp.WINHTTP_QUERY_CONTENT_ENCODING,
                        buffer);

                    CharArrayHelpers.Trim(buffer, ref contentEncodingStartIndex, ref contentEncodingLength);

                    if (contentEncodingLength > 0)
                    {
                        if (CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase(
                                EncodingNameGzip, buffer, contentEncodingStartIndex, contentEncodingLength))
                        {
                            decompressedStream   = new GZipStream(responseStream, CompressionMode.Decompress);
                            stripEncodingHeaders = true;
                        }
                        else if (CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase(
                                     EncodingNameDeflate, buffer, contentEncodingStartIndex, contentEncodingLength))
                        {
                            decompressedStream   = new DeflateStream(responseStream, CompressionMode.Decompress);
                            stripEncodingHeaders = true;
                        }
                    }
                }

                response.Content        = new NoWriteNoSeekStreamContent(decompressedStream);
                response.RequestMessage = request;

                // Parse raw response headers and place them into response message.
                ParseResponseHeaders(requestHandle, response, buffer, stripEncodingHeaders);

                if (response.RequestMessage.Method != HttpMethod.Head)
                {
                    state.ExpectedBytesToRead = response.Content.Headers.ContentLength;
                }

                return(response);
            }
            finally
            {
                ArrayPool <char> .Shared.Return(buffer);
            }
        }
Exemple #4
0
        public static HttpResponseMessage CreateResponseMessage(
            WinHttpRequestState state,
            bool doManualDecompressionCheck)
        {
            HttpRequestMessage request         = state.RequestMessage;
            SafeWinHttpHandle  requestHandle   = state.RequestHandle;
            CookieUsePolicy    cookieUsePolicy = state.Handler.CookieUsePolicy;
            CookieContainer    cookieContainer = state.Handler.CookieContainer;
            var  response             = new HttpResponseMessage();
            bool stripEncodingHeaders = false;

            // Get HTTP version, status code, reason phrase from the response headers.
            string version = GetResponseHeaderStringInfo(requestHandle, Interop.WinHttp.WINHTTP_QUERY_VERSION);

            if (string.Compare("HTTP/1.1", version, StringComparison.OrdinalIgnoreCase) == 0)
            {
                response.Version = HttpVersion.Version11;
            }
            else if (string.Compare("HTTP/1.0", version, StringComparison.OrdinalIgnoreCase) == 0)
            {
                response.Version = HttpVersion.Version10;
            }
            else
            {
                response.Version = HttpVersion.Unknown;
            }

            response.StatusCode = (HttpStatusCode)GetResponseHeaderNumberInfo(
                requestHandle,
                Interop.WinHttp.WINHTTP_QUERY_STATUS_CODE);
            response.ReasonPhrase = GetResponseHeaderStringInfo(
                requestHandle,
                Interop.WinHttp.WINHTTP_QUERY_STATUS_TEXT);

            // Create response stream and wrap it in a StreamContent object.
            var    responseStream     = new WinHttpResponseStream(state);
            Stream decompressedStream = responseStream;

            if (doManualDecompressionCheck)
            {
                string contentEncoding = GetResponseHeaderStringInfo(
                    requestHandle,
                    Interop.WinHttp.WINHTTP_QUERY_CONTENT_ENCODING);
                if (!string.IsNullOrEmpty(contentEncoding))
                {
                    if (contentEncoding.IndexOf(EncodingNameDeflate, StringComparison.OrdinalIgnoreCase) > -1)
                    {
                        decompressedStream   = new DeflateStream(responseStream, CompressionMode.Decompress);
                        stripEncodingHeaders = true;
                    }
                    else if (contentEncoding.IndexOf(EncodingNameGzip, StringComparison.OrdinalIgnoreCase) > -1)
                    {
                        decompressedStream   = new GZipStream(responseStream, CompressionMode.Decompress);
                        stripEncodingHeaders = true;
                    }
                }
            }

            var content = new StreamContent(decompressedStream);

            response.Content        = content;
            response.RequestMessage = request;

            // Parse raw response headers and place them into response message.
            ParseResponseHeaders(requestHandle, response, stripEncodingHeaders);

            return(response);
        }
        public static HttpResponseMessage CreateResponseMessage(
            WinHttpRequestState state,
            bool doManualDecompressionCheck)
        {
            HttpRequestMessage request         = state.RequestMessage;
            SafeWinHttpHandle  requestHandle   = state.RequestHandle;
            CookieUsePolicy    cookieUsePolicy = state.Handler.CookieUsePolicy;
            CookieContainer    cookieContainer = state.Handler.CookieContainer;
            var  response             = new HttpResponseMessage();
            bool stripEncodingHeaders = false;

            // Create a single buffer to use for all subsequent WinHttpQueryHeaders string interop calls.
            // This buffer is the length needed for WINHTTP_QUERY_RAW_HEADERS_CRLF, which includes the status line
            // and all headers separated by CRLF, so it should be large enough for any individual status line or header queries.
            int bufferLength = GetResponseHeaderCharBufferLength(requestHandle, Interop.WinHttp.WINHTTP_QUERY_RAW_HEADERS_CRLF);

            char[] buffer = new char[bufferLength];

            // Get HTTP version, status code, reason phrase from the response headers.

            int versionLength = GetResponseHeader(requestHandle, Interop.WinHttp.WINHTTP_QUERY_VERSION, buffer);

            response.Version =
                CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase("HTTP/1.1", buffer, 0, versionLength) ? HttpVersion.Version11 :
                CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase("HTTP/1.0", buffer, 0, versionLength) ? HttpVersion.Version10 :
                HttpVersion.Unknown;

            response.StatusCode = (HttpStatusCode)GetResponseHeaderNumberInfo(
                requestHandle,
                Interop.WinHttp.WINHTTP_QUERY_STATUS_CODE);

            int reasonPhraseLength = GetResponseHeader(requestHandle, Interop.WinHttp.WINHTTP_QUERY_STATUS_TEXT, buffer);

            response.ReasonPhrase = reasonPhraseLength > 0 ?
                                    GetReasonPhrase(response.StatusCode, buffer, reasonPhraseLength) :
                                    string.Empty;

            // Create response stream and wrap it in a StreamContent object.
            var responseStream = new WinHttpResponseStream(requestHandle, state);

            state.RequestHandle = null; // ownership successfully transfered to WinHttpResponseStram.
            Stream decompressedStream = responseStream;

            if (doManualDecompressionCheck)
            {
                int contentEncodingStartIndex = 0;
                int contentEncodingLength     = GetResponseHeader(
                    requestHandle,
                    Interop.WinHttp.WINHTTP_QUERY_CONTENT_ENCODING,
                    buffer);

                CharArrayHelpers.Trim(buffer, ref contentEncodingStartIndex, ref contentEncodingLength);

                if (contentEncodingLength > 0)
                {
                    if (CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase(
                            EncodingNameGzip, buffer, contentEncodingStartIndex, contentEncodingLength))
                    {
                        decompressedStream   = new GZipStream(responseStream, CompressionMode.Decompress);
                        stripEncodingHeaders = true;
                    }
                    else if (CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase(
                                 EncodingNameDeflate, buffer, contentEncodingStartIndex, contentEncodingLength))
                    {
                        decompressedStream   = new DeflateStream(responseStream, CompressionMode.Decompress);
                        stripEncodingHeaders = true;
                    }
                }
            }

#if HTTP_DLL
            var content = new StreamContent(decompressedStream, state.CancellationToken);
#else
            // TODO: Issue https://github.com/dotnet/corefx/issues/9071
            // We'd like to be able to pass state.CancellationToken into the StreamContent so that its
            // SerializeToStreamAsync method can use it, but that ctor isn't public, nor is there a
            // SerializeToStreamAsync override that takes a CancellationToken.
            var content = new StreamContent(decompressedStream);
#endif

            response.Content        = content;
            response.RequestMessage = request;

            // Parse raw response headers and place them into response message.
            ParseResponseHeaders(requestHandle, response, buffer, stripEncodingHeaders);

            if (response.RequestMessage.Method != HttpMethod.Head)
            {
                state.ExpectedBytesToRead = response.Content.Headers.ContentLength;
            }

            return(response);
        }
        public static HttpResponseMessage CreateResponseMessage(
            WinHttpRequestState state,
            bool doManualDecompressionCheck)
        {
            HttpRequestMessage request = state.RequestMessage;
            SafeWinHttpHandle requestHandle = state.RequestHandle;
            CookieUsePolicy cookieUsePolicy = state.Handler.CookieUsePolicy;
            CookieContainer cookieContainer = state.Handler.CookieContainer;
            var response = new HttpResponseMessage();
            bool stripEncodingHeaders = false;

            // Create a single buffer to use for all subsequent WinHttpQueryHeaders string interop calls.
            // This buffer is the length needed for WINHTTP_QUERY_RAW_HEADERS_CRLF, which includes the status line
            // and all headers separated by CRLF, so it should be large enough for any individual status line or header queries.
            int bufferLength = GetResponseHeaderCharBufferLength(requestHandle, Interop.WinHttp.WINHTTP_QUERY_RAW_HEADERS_CRLF);
            char[] buffer = ArrayPool<char>.Shared.Rent(bufferLength);
            try
            {
                // Get HTTP version, status code, reason phrase from the response headers.

                if (IsResponseHttp2(requestHandle))
                {
                    response.Version = WinHttpHandler.HttpVersion20;
                }
                else
                {
                    int versionLength = GetResponseHeader(requestHandle, Interop.WinHttp.WINHTTP_QUERY_VERSION, buffer);
                    response.Version =
                        CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase("HTTP/1.1", buffer, 0, versionLength) ? HttpVersionInternal.Version11 :
                        CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase("HTTP/1.0", buffer, 0, versionLength) ? HttpVersionInternal.Version10 :
                        WinHttpHandler.HttpVersionUnknown;
                }

                response.StatusCode = (HttpStatusCode)GetResponseHeaderNumberInfo(
                    requestHandle,
                    Interop.WinHttp.WINHTTP_QUERY_STATUS_CODE);

                int reasonPhraseLength = GetResponseHeader(requestHandle, Interop.WinHttp.WINHTTP_QUERY_STATUS_TEXT, buffer);
                response.ReasonPhrase = reasonPhraseLength > 0 ?
                    GetReasonPhrase(response.StatusCode, buffer, reasonPhraseLength) :
                    string.Empty;

                // Create response stream and wrap it in a StreamContent object.
                var responseStream = new WinHttpResponseStream(requestHandle, state);
                state.RequestHandle = null; // ownership successfully transfered to WinHttpResponseStram.
                Stream decompressedStream = responseStream;

                if (doManualDecompressionCheck)
                {
                    int contentEncodingStartIndex = 0;
                    int contentEncodingLength = GetResponseHeader(
                        requestHandle,
                        Interop.WinHttp.WINHTTP_QUERY_CONTENT_ENCODING,
                        buffer);

                    CharArrayHelpers.Trim(buffer, ref contentEncodingStartIndex, ref contentEncodingLength);

                    if (contentEncodingLength > 0)
                    {
                        if (CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase(
                            EncodingNameGzip, buffer, contentEncodingStartIndex, contentEncodingLength))
                        {
                            decompressedStream = new GZipStream(responseStream, CompressionMode.Decompress);
                            stripEncodingHeaders = true;
                        }
                        else if (CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase(
                            EncodingNameDeflate, buffer, contentEncodingStartIndex, contentEncodingLength))
                        {
                            decompressedStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                            stripEncodingHeaders = true;
                        }
                    }
                }

                response.Content = new NoWriteNoSeekStreamContent(decompressedStream, state.CancellationToken);
                response.RequestMessage = request;

                // Parse raw response headers and place them into response message.
                ParseResponseHeaders(requestHandle, response, buffer, stripEncodingHeaders);

                if (response.RequestMessage.Method != HttpMethod.Head)
                {
                    state.ExpectedBytesToRead = response.Content.Headers.ContentLength;
                }

                return response;
            }
            finally
            {
                ArrayPool<char>.Shared.Return(buffer);
            }
        }
        public static HttpResponseMessage CreateResponseMessage(
            WinHttpRequestState state,
            bool doManualDecompressionCheck)
        {
            HttpRequestMessage request = state.RequestMessage;
            SafeWinHttpHandle requestHandle = state.RequestHandle;
            CookieUsePolicy cookieUsePolicy = state.Handler.CookieUsePolicy;
            CookieContainer cookieContainer = state.Handler.CookieContainer;
            var response = new HttpResponseMessage();
            bool stripEncodingHeaders = false;

            // Create a single buffer to use for all subsequent WinHttpQueryHeaders string interop calls.
            // This buffer is the length needed for WINHTTP_QUERY_RAW_HEADERS_CRLF, which includes the status line
            // and all headers separated by CRLF, so it should be large enough for any individual status line or header queries.
            int bufferLength = GetResponseHeaderCharBufferLength(requestHandle, Interop.WinHttp.WINHTTP_QUERY_RAW_HEADERS_CRLF);
            char[] buffer = new char[bufferLength];

            // Get HTTP version, status code, reason phrase from the response headers.

            int versionLength = GetResponseHeader(requestHandle, Interop.WinHttp.WINHTTP_QUERY_VERSION, buffer);
            response.Version =
                CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase("HTTP/1.1", buffer, 0, versionLength) ? HttpVersion.Version11 :
                CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase("HTTP/1.0", buffer, 0, versionLength) ? HttpVersion.Version10 :
                HttpVersion.Unknown;

            response.StatusCode = (HttpStatusCode)GetResponseHeaderNumberInfo(
                requestHandle,
                Interop.WinHttp.WINHTTP_QUERY_STATUS_CODE);

            int reasonPhraseLength = GetResponseHeader(requestHandle, Interop.WinHttp.WINHTTP_QUERY_STATUS_TEXT, buffer);
            response.ReasonPhrase = reasonPhraseLength > 0 ?
                GetReasonPhrase(response.StatusCode, buffer, reasonPhraseLength) :
                string.Empty;

            // Create response stream and wrap it in a StreamContent object.
            var responseStream = new WinHttpResponseStream(requestHandle, state);
            state.RequestHandle = null; // ownership successfully transfered to WinHttpResponseStram.
            Stream decompressedStream = responseStream;

            if (doManualDecompressionCheck)
            {
                int contentEncodingStartIndex = 0;
                int contentEncodingLength = GetResponseHeader(
                    requestHandle,
                    Interop.WinHttp.WINHTTP_QUERY_CONTENT_ENCODING,
                    buffer);

                CharArrayHelpers.Trim(buffer, ref contentEncodingStartIndex, ref contentEncodingLength);

                if (contentEncodingLength > 0)
                {
                    if (CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase(
                        EncodingNameGzip, buffer, contentEncodingStartIndex, contentEncodingLength))
                    {
                        decompressedStream = new GZipStream(responseStream, CompressionMode.Decompress);
                        stripEncodingHeaders = true;
                    }
                    else if (CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase(
                        EncodingNameDeflate, buffer, contentEncodingStartIndex, contentEncodingLength))
                    {
                        decompressedStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                        stripEncodingHeaders = true;
                    }
                }
            }

#if HTTP_DLL
            var content = new StreamContent(decompressedStream, state.CancellationToken);
#else
            // TODO: Issue https://github.com/dotnet/corefx/issues/9071
            // We'd like to be able to pass state.CancellationToken into the StreamContent so that its
            // SerializeToStreamAsync method can use it, but that ctor isn't public, nor is there a
            // SerializeToStreamAsync override that takes a CancellationToken.
            var content = new StreamContent(decompressedStream);
#endif

            response.Content = content;
            response.RequestMessage = request;

            // Parse raw response headers and place them into response message.
            ParseResponseHeaders(requestHandle, response, buffer, stripEncodingHeaders);

            if (response.RequestMessage.Method != HttpMethod.Head)
            {
                state.ExpectedBytesToRead = response.Content.Headers.ContentLength;
            }

            return response;
        }
        public static HttpResponseMessage CreateResponseMessage(
            WinHttpRequestState state,
            bool doManualDecompressionCheck)
        {
            HttpRequestMessage request = state.RequestMessage;
            SafeWinHttpHandle requestHandle = state.RequestHandle;
            CookieUsePolicy cookieUsePolicy = state.Handler.CookieUsePolicy;
            CookieContainer cookieContainer = state.Handler.CookieContainer;
            var response = new HttpResponseMessage();
            bool stripEncodingHeaders = false;

            // Create a single buffer to use for all subsequent WinHttpQueryHeaders string interop calls.
            // This buffer is the length needed for WINHTTP_QUERY_RAW_HEADERS_CRLF, which includes the status line
            // and all headers separated by CRLF, so it should be large enough for any individual status line or header queries.
            int bufferLength = GetResponseHeaderCharBufferLength(requestHandle, Interop.WinHttp.WINHTTP_QUERY_RAW_HEADERS_CRLF);
            char[] buffer = new char[bufferLength];

            // Get HTTP version, status code, reason phrase from the response headers.

            int versionLength = GetResponseHeader(requestHandle, Interop.WinHttp.WINHTTP_QUERY_VERSION, buffer);
            response.Version =
                CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase("HTTP/1.1", buffer, 0, versionLength) ? HttpVersion.Version11 :
                CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase("HTTP/1.0", buffer, 0, versionLength) ? HttpVersion.Version10 :
                HttpVersion.Unknown;

            response.StatusCode = (HttpStatusCode)GetResponseHeaderNumberInfo(
                requestHandle,
                Interop.WinHttp.WINHTTP_QUERY_STATUS_CODE);

            int reasonPhraseLength = GetResponseHeader(requestHandle, Interop.WinHttp.WINHTTP_QUERY_STATUS_TEXT, buffer);
            if (reasonPhraseLength > 0)
            {
                response.ReasonPhrase = GetReasonPhrase(response.StatusCode, buffer, reasonPhraseLength);
            }

            // Create response stream and wrap it in a StreamContent object.
            var responseStream = new WinHttpResponseStream(state);
            Stream decompressedStream = responseStream;

            if (doManualDecompressionCheck)
            {
                int contentEncodingStartIndex = 0;
                int contentEncodingLength = GetResponseHeader(
                    requestHandle,
                    Interop.WinHttp.WINHTTP_QUERY_CONTENT_ENCODING,
                    buffer);

                CharArrayHelpers.Trim(buffer, ref contentEncodingStartIndex, ref contentEncodingLength);

                if (contentEncodingLength > 0)
                {
                    if (CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase(
                        EncodingNameGzip, buffer, contentEncodingStartIndex, contentEncodingLength))
                    {
                        decompressedStream = new GZipStream(responseStream, CompressionMode.Decompress);
                        stripEncodingHeaders = true;
                    }
                    else if (CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase(
                        EncodingNameDeflate, buffer, contentEncodingStartIndex, contentEncodingLength))
                    {
                        decompressedStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                        stripEncodingHeaders = true;
                    }
                }
            }

            var content = new StreamContent(decompressedStream);

            response.Content = content;
            response.RequestMessage = request;

            // Parse raw response headers and place them into response message.
            ParseResponseHeaders(requestHandle, response, buffer, stripEncodingHeaders);

            return response;
        }