diff --git a/src/Elasticsearch.Net/Connection/HttpWebRequestConnection.cs b/src/Elasticsearch.Net/Connection/HttpWebRequestConnection.cs index 071f1a03486..a53be1fb872 100644 --- a/src/Elasticsearch.Net/Connection/HttpWebRequestConnection.cs +++ b/src/Elasticsearch.Net/Connection/HttpWebRequestConnection.cs @@ -19,7 +19,8 @@ namespace Elasticsearch.Net { #if DOTNETCORE - [Obsolete("CoreFX HttpWebRequest uses HttpClient under the covers but does not reuse HttpClient instances, do NOT use on .NET core only used as the default on Full Framework")] + [Obsolete( + "CoreFX HttpWebRequest uses HttpClient under the covers but does not reuse HttpClient instances, do NOT use on .NET core only used as the default on Full Framework")] #endif public class HttpWebRequestConnection : IConnection { @@ -52,8 +53,10 @@ public virtual TResponse Request(RequestData requestData) using (var stream = request.GetRequestStream()) { if (requestData.HttpCompression) + { using (var zipStream = new GZipStream(stream, CompressionMode.Compress)) data.Write(zipStream, requestData.ConnectionSettings); + } else data.Write(stream, requestData.ConnectionSettings); } @@ -68,7 +71,7 @@ public virtual TResponse Request(RequestData requestData) //http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.getresponsestream.aspx //Either the stream or the response object needs to be closed but not both although it won't - //throw any errors if both are closed atleast one of them has to be Closed. + //throw any errors if both are closed at least one of them has to be Closed. //Since we expose the stream we let closing the stream determining when to close the connection var httpWebResponse = (HttpWebResponse)request.GetResponse(); HandleResponse(httpWebResponse, out statusCode, out responseStream, out mimeType); @@ -125,8 +128,10 @@ CancellationToken cancellationToken using (var stream = await apmGetRequestStreamTask.ConfigureAwait(false)) { if (requestData.HttpCompression) + { using (var zipStream = new GZipStream(stream, CompressionMode.Compress)) await data.WriteAsync(zipStream, requestData.ConnectionSettings, cancellationToken).ConfigureAwait(false); + } else await data.WriteAsync(stream, requestData.ConnectionSettings, cancellationToken).ConfigureAwait(false); } @@ -165,8 +170,7 @@ CancellationToken cancellationToken } responseStream ??= Stream.Null; var response = await ResponseBuilder.ToResponseAsync - (requestData, ex, statusCode, warnings, responseStream, mimeType, cancellationToken) - .ConfigureAwait(false); + (requestData, ex, statusCode, warnings, responseStream, mimeType, cancellationToken).ConfigureAwait(false); // set TCP and threadpool stats on the response here so that in the event the request fails after the point of // gathering stats, they are still exposed on the call details. Ideally these would be set inside ResponseBuilder.ToResponse, @@ -205,7 +209,7 @@ protected virtual void SetServerCertificateValidationCallBackIfNeeded(HttpWebReq #else if (callback != null) throw new Exception("Mono misses ServerCertificateValidationCallback on HttpWebRequest"); - #endif +#endif } protected virtual HttpWebRequest CreateWebRequest(RequestData requestData) @@ -311,8 +315,10 @@ protected virtual void SetBasicAuthenticationIfNeeded(HttpWebRequest request, Re if (!string.IsNullOrEmpty(requestData.Uri.UserInfo)) userInfo = Uri.UnescapeDataString(requestData.Uri.UserInfo); else if (requestData.BasicAuthorizationCredentials != null) + { userInfo = $"{requestData.BasicAuthorizationCredentials.Username}:{requestData.BasicAuthorizationCredentials.Password.CreateString()}"; + } if (string.IsNullOrWhiteSpace(userInfo)) return; @@ -336,7 +342,6 @@ protected virtual bool SetApiKeyAuthenticationIfNeeded(HttpWebRequest request, R request.Headers["Authorization"] = $"ApiKey {apiKey}"; return true; - } /// diff --git a/src/Elasticsearch.Net/Transport/Pipeline/ResponseBuilder.cs b/src/Elasticsearch.Net/Transport/Pipeline/ResponseBuilder.cs index afa2a05db3f..3c239c96c50 100644 --- a/src/Elasticsearch.Net/Transport/Pipeline/ResponseBuilder.cs +++ b/src/Elasticsearch.Net/Transport/Pipeline/ResponseBuilder.cs @@ -41,6 +41,8 @@ public static TResponse ToResponse( // Only attempt to set the body if the response may have content if (MayHaveBody(statusCode, requestData.Method)) response = SetBody(details, requestData, responseStream, mimeType); + else + responseStream.Dispose(); response ??= new TResponse(); @@ -67,6 +69,8 @@ public static async Task ToResponseAsync( // Only attempt to set the body if the response may have content if (MayHaveBody(statusCode, requestData.Method)) response = await SetBodyAsync(details, requestData, responseStream, mimeType, cancellationToken).ConfigureAwait(false); + else + responseStream.Dispose(); response ??= new TResponse(); @@ -78,7 +82,7 @@ public static async Task ToResponseAsync( /// A helper which returns true if the response could potentially have a body. /// private static bool MayHaveBody(int? statusCode, HttpMethod httpMethod) => - !statusCode.HasValue || (statusCode.Value != 204 && httpMethod != HttpMethod.HEAD); + !statusCode.HasValue || statusCode.Value != 204 && httpMethod != HttpMethod.HEAD; private static ApiCallDetails Initialize( RequestData requestData, Exception exception, int? statusCode, IEnumerable warnings, string mimeType @@ -91,8 +95,10 @@ private static ApiCallDetails Initialize( if (allowedStatusCodes.Contains(-1) || allowedStatusCodes.Contains(statusCode.Value)) success = true; else + { success = requestData.ConnectionSettings .StatusCodeToResponseSuccess(requestData.Method, statusCode.Value); + } } // We don't validate the content-type (MIME type) for HEAD requests or responses that have no content (204 status code). @@ -170,8 +176,10 @@ private static async Task SetBodyAsync( var serializer = requestData.ConnectionSettings.RequestResponseSerializer; if (requestData.CustomResponseBuilder != null) + { return await requestData.CustomResponseBuilder.DeserializeResponseAsync(serializer, details, responseStream, cancellationToken) .ConfigureAwait(false) as TResponse; + } return !RequestData.ValidResponseContentType(requestData.Accept, mimeType) ? null