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); } }
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); } }
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); } }
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); } }
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); }