diff --git a/src/Elastic.Transport/Components/Pipeline/RequestData.cs b/src/Elastic.Transport/Components/Pipeline/RequestData.cs index f8617cc..778ab7b 100644 --- a/src/Elastic.Transport/Components/Pipeline/RequestData.cs +++ b/src/Elastic.Transport/Components/Pipeline/RequestData.cs @@ -160,7 +160,7 @@ MemoryStreamFactory memoryStreamFactory public ITransportConfiguration ConnectionSettings { get; } public CustomResponseBuilder? CustomResponseBuilder { get; } public HeadersList? ResponseHeadersToParse { get; } - public NameValueCollection Headers { get; } + public NameValueCollection? Headers { get; } public bool DisableDirectStreaming { get; } public bool ParseAllHeaders { get; } public bool DisableAutomaticProxyDetection { get; } @@ -186,7 +186,7 @@ MemoryStreamFactory memoryStreamFactory public TimeSpan DnsRefreshTimeout { get; } - public MetaHeaderProvider MetaHeaderProvider { get; } + public MetaHeaderProvider? MetaHeaderProvider { get; } public IReadOnlyDictionary RequestMetaData { get; } diff --git a/src/Elastic.Transport/Components/TransportClient/Content/RequestDataContent.cs b/src/Elastic.Transport/Components/TransportClient/Content/RequestDataContent.cs index 91fee0e..2b9dd3a 100644 --- a/src/Elastic.Transport/Components/TransportClient/Content/RequestDataContent.cs +++ b/src/Elastic.Transport/Components/TransportClient/Content/RequestDataContent.cs @@ -29,12 +29,12 @@ namespace Elastic.Transport; internal sealed class RequestDataContent : HttpContent { private readonly RequestData _requestData; - private readonly PostData _postData; + private readonly PostData? _postData; - private readonly Func + private readonly Func _onStreamAvailableAsync; - private readonly Action _onStreamAvailable; + private readonly Action _onStreamAvailable; private readonly CancellationToken _token; /// Constructor used in synchronous paths. @@ -53,8 +53,13 @@ public RequestDataContent(RequestData requestData, PostData postData) _onStreamAvailableAsync = OnStreamAvailableAsync; } - private static void OnStreamAvailable(RequestData data, PostData postData, Stream stream, HttpContent content, TransportContext context) + private static void OnStreamAvailable(RequestData data, PostData? postData, Stream stream, HttpContent content, TransportContext context) { + if (postData == null) + { + stream.Dispose(); + return; + } if (data.HttpCompression) stream = new GZipStream(stream, CompressionMode.Compress, false); using (stream) postData.Write(stream, data.ConnectionSettings, data.DisableDirectStreaming); @@ -75,8 +80,17 @@ public RequestDataContent(RequestData requestData, CancellationToken token) _onStreamAvailableAsync = OnStreamAvailableAsync; } - private static async Task OnStreamAvailableAsync(RequestData data, PostData postData, Stream stream, HttpContent content, TransportContext context, CancellationToken ctx = default) + private static async Task OnStreamAvailableAsync(RequestData data, PostData? postData, Stream stream, HttpContent content, TransportContext context, CancellationToken ctx = default) { + if (postData == null) + { +#if NET6_0_OR_GREATER + await stream.DisposeAsync().ConfigureAwait(false); +#else + stream.Dispose(); +#endif + return; + } if (data.HttpCompression) stream = new GZipStream(stream, CompressionMode.Compress, false); #if NET6_0_OR_GREATER diff --git a/src/Elastic.Transport/Components/TransportClient/HttpRequestInvoker.cs b/src/Elastic.Transport/Components/TransportClient/HttpRequestInvoker.cs index 6392268..00031d8 100644 --- a/src/Elastic.Transport/Components/TransportClient/HttpRequestInvoker.cs +++ b/src/Elastic.Transport/Components/TransportClient/HttpRequestInvoker.cs @@ -193,7 +193,7 @@ private async ValueTask RequestCoreAsync(bool isAsync, End { // if there's an exception, ensure we always release the stream and response so that the connection is freed. responseStream.Dispose(); - receivedResponse.Dispose(); + receivedResponse.Dispose(); throw; } } @@ -343,7 +343,7 @@ internal HttpRequestMessage CreateHttpRequestMessage(Endpoint endpoint, RequestD internal void SetAuthenticationIfNeeded(Endpoint endpoint, RequestData requestData, HttpRequestMessage requestMessage) { //If user manually specifies an Authorization Header give it preference - if (requestData.Headers.HasKeys() && requestData.Headers.AllKeys.Contains("Authorization")) + if (requestData.Headers != null && requestData.Headers.HasKeys() && requestData.Headers.AllKeys.Contains("Authorization")) { var header = AuthenticationHeaderValue.Parse(requestData.Headers["Authorization"]); requestMessage.Headers.Authorization = header; diff --git a/src/Elastic.Transport/Configuration/ITransportConfiguration.cs b/src/Elastic.Transport/Configuration/ITransportConfiguration.cs index 395d4d1..f8abe90 100644 --- a/src/Elastic.Transport/Configuration/ITransportConfiguration.cs +++ b/src/Elastic.Transport/Configuration/ITransportConfiguration.cs @@ -195,7 +195,7 @@ public interface ITransportConfiguration : IRequestConfiguration, IDisposable /// /// Produces the client meta header for a request. /// - MetaHeaderProvider MetaHeaderProvider { get; } + MetaHeaderProvider? MetaHeaderProvider { get; } /// /// Disables the meta header which is included on all requests by default. This header contains lightweight information diff --git a/src/Elastic.Transport/DistributedTransport.cs b/src/Elastic.Transport/DistributedTransport.cs index f9888d7..c5d1b16 100644 --- a/src/Elastic.Transport/DistributedTransport.cs +++ b/src/Elastic.Transport/DistributedTransport.cs @@ -307,7 +307,9 @@ private static void ThrowUnexpectedTransportException(Exception kille ) where TResponse : TransportResponse, new() => throw new UnexpectedTransportException(killerException, seenExceptions) { - Endpoint = endpoint, ApiCallDetails = response?.ApiCallDetails, AuditTrail = pipeline.AuditTrail + Endpoint = endpoint, + ApiCallDetails = response?.ApiCallDetails, + AuditTrail = pipeline.AuditTrail }; private static void HandlePipelineException( diff --git a/tests/Elastic.Transport.IntegrationTests/Http/StreamResponseTests.cs b/tests/Elastic.Transport.IntegrationTests/Http/StreamResponseTests.cs index 7ec6720..2b4084c 100644 --- a/tests/Elastic.Transport.IntegrationTests/Http/StreamResponseTests.cs +++ b/tests/Elastic.Transport.IntegrationTests/Http/StreamResponseTests.cs @@ -106,11 +106,9 @@ public async Task WhenNoContent_MemoryStreamShouldBeDisposed() // We expect one for sending the request payload, but as the response is 204, we shouldn't // see other memory streams being created for the response. - memoryStreamFactory.Created.Count.Should().Be(1); + memoryStreamFactory.Created.Count.Should().Be(2); foreach (var memoryStream in memoryStreamFactory.Created) - { memoryStream.IsDisposed.Should().BeTrue(); - } } [Fact]