예제 #1
0
            public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
            {
                // Wait for response headers to be read.
                bool emptyResponse;
                bool wait;

                // Process all informational responses if any and wait for final status.
                (wait, emptyResponse) = TryEnsureHeaders();
                if (wait)
                {
                    await GetWaiterTask(cancellationToken).ConfigureAwait(false);

                    (wait, emptyResponse) = TryEnsureHeaders();
                    Debug.Assert(!wait);
                }

                // Start to process the response body.
                ((HttpConnectionResponseContent)_response.Content).SetStream(emptyResponse ?
                                                                             EmptyReadStream.Instance :
                                                                             (Stream) new Http2ReadStream(this));

                // Process Set-Cookie headers.
                if (_connection._pool.Settings._useCookies)
                {
                    CookieHelper.ProcessReceivedCookies(_response, _connection._pool.Settings._cookieContainer);
                }
            }
예제 #2
0
            public async Task ReadResponseHeadersAsync()
            {
                // Wait for response headers to be read.
                bool emptyResponse = await _responseHeadersAvailable.Task.ConfigureAwait(false);

                // Start to process the response body.
                ((HttpConnectionResponseContent)_response.Content).SetStream(emptyResponse ?
                                                                             EmptyReadStream.Instance :
                                                                             (Stream) new Http2ReadStream(this));

                // Process Set-Cookie headers.
                if (_connection._pool.Settings._useCookies)
                {
                    CookieHelper.ProcessReceivedCookies(_response, _connection._pool.Settings._cookieContainer);
                }
            }
예제 #3
0
            public async Task ReadResponseHeadersAsync()
            {
                // Wait for response headers to be read.
                (Task waiterTask, bool emptyResponse) = TryEnsureHeaders();
                if (waiterTask != null)
                {
                    await waiterTask.ConfigureAwait(false);

                    (waiterTask, emptyResponse) = TryEnsureHeaders();
                    Debug.Assert(waiterTask == null);
                }

                // Start to process the response body.
                ((HttpConnectionResponseContent)_response.Content).SetStream(emptyResponse ?
                                                                             EmptyReadStream.Instance :
                                                                             (Stream) new Http2ReadStream(this));

                // Process Set-Cookie headers.
                if (_connection._pool.Settings._useCookies)
                {
                    CookieHelper.ProcessReceivedCookies(_response, _connection._pool.Settings._cookieContainer);
                }
            }
예제 #4
0
            public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
            {
                // Wait for response headers to be read.
                bool emptyResponse;
                bool wait;

                // Process all informational responses if any and wait for final status.
                (wait, emptyResponse) = TryEnsureHeaders();
                if (wait)
                {
                    await GetWaiterTask(cancellationToken).ConfigureAwait(false);

                    (wait, emptyResponse) = TryEnsureHeaders();
                    Debug.Assert(!wait);
                }

                // Start to process the response body.
                var responseContent = (HttpConnectionResponseContent)_response.Content;

                if (emptyResponse)
                {
                    // If there are any trailers, copy them over to the response.  Normally this would be handled by
                    // the response stream hitting EOF, but if there is no response body, we do it here.
                    CopyTrailersToResponseMessage(_response);
                    responseContent.SetStream(EmptyReadStream.Instance);
                }
                else
                {
                    responseContent.SetStream(new Http2ReadStream(this));
                }

                // Process Set-Cookie headers.
                if (_connection._pool.Settings._useCookies)
                {
                    CookieHelper.ProcessReceivedCookies(_response, _connection._pool.Settings._cookieContainer);
                }
            }
예제 #5
0
            public async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
            {
                // TODO: ISSUE 31310: Cancellation support

                try
                {
                    HttpConnectionResponseContent responseContent = new HttpConnectionResponseContent();
                    _response = new HttpResponseMessage()
                    {
                        Version = HttpVersion.Version20, RequestMessage = request, Content = responseContent
                    };

                    // TODO: ISSUE 31312: Expect: 100-continue and early response handling
                    // Note that in an "early response" scenario, where we get a response before we've finished sending the request body
                    // (either with a 100-continue that timed out, or without 100-continue),
                    // we can stop send a RST_STREAM on the request stream and stop sending the request without tearing down the entire connection.

                    // TODO: ISSUE 31313: Avoid allocating a TaskCompletionSource repeatedly by using a resettable ValueTaskSource.
                    // See: https://github.com/dotnet/corefx/blob/master/src/Common/tests/System/Threading/Tasks/Sources/ManualResetValueTaskSource.cs
                    Debug.Assert(_responseDataAvailable == null);
                    _responseDataAvailable = new TaskCompletionSource <bool>();
                    Task readDataAvailableTask = _responseDataAvailable.Task;

                    // Send headers
                    await _connection.SendHeadersAsync(_streamId, request).ConfigureAwait(false);

                    // Send request body, if any
                    if (request.Content != null)
                    {
                        using (Http2WriteStream writeStream = new Http2WriteStream(this))
                        {
                            await request.Content.CopyToAsync(writeStream).ConfigureAwait(false);
                        }
                    }

                    // Wait for response headers to be read.
                    await readDataAvailableTask.ConfigureAwait(false);

                    // Start to process the response body.
                    bool emptyResponse = false;
                    lock (_syncObject)
                    {
                        if (_responseComplete && _responseBuffer.ActiveSpan.Length == 0)
                        {
                            if (_responseAborted)
                            {
                                throw new IOException(SR.net_http_invalid_response);
                            }

                            emptyResponse = true;
                        }
                    }

                    if (emptyResponse)
                    {
                        responseContent.SetStream(EmptyReadStream.Instance);
                    }
                    else
                    {
                        responseContent.SetStream(new Http2ReadStream(this));
                    }

                    // Process Set-Cookie headers.
                    if (_connection._pool.Settings._useCookies)
                    {
                        CookieHelper.ProcessReceivedCookies(_response, _connection._pool.Settings._cookieContainer);
                    }
                }
                catch (Exception e)
                {
                    Dispose();

                    if (e is IOException ioe)
                    {
                        throw new HttpRequestException(SR.net_http_client_execution_error, ioe);
                    }
                    else if (e is ObjectDisposedException)
                    {
                        throw new HttpRequestException(SR.net_http_client_execution_error);
                    }
                    else if (e is Http2ProtocolException)
                    {
                        // ISSUE 31315: Determine if/how to expose HTTP2 error codes
                        throw new HttpRequestException(SR.net_http_client_execution_error);
                    }
                    else
                    {
                        throw;
                    }
                }

                return(_response);
            }