From 7697fbfe8a6bb8eeb18e4b95faf767ad90d90d01 Mon Sep 17 00:00:00 2001 From: Eli Bishop Date: Fri, 31 May 2019 10:40:55 -0700 Subject: [PATCH] prepare 5.6.5 release (#104) --- CHANGELOG.md | 4 +++ .../FeatureRequestor.cs | 15 +++++++--- .../LaunchDarkly.ServerSdk.csproj | 2 +- .../FeatureRequestorTest.cs | 28 +++++++++++++++++++ 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58a37d91..71606653 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to the LaunchDarkly .NET Server-Side SDK will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org). +## [5.6.5] - 2019-05-30 +### Fixed: +- If streaming is disabled, polling requests could stop working if the client ever received an HTTP error from LaunchDarkly. This bug was introduced in the 5.6.3 release. + ## [5.6.4] - 2019-05-10 ### Changed: - The NuGet package name and assembly name have changed: they are now `LaunchDarkly.ServerSdk` instead of `LaunchDarkly.Client`. There are no other changes in this release; the namespace used in .NET code is still `LaunchDarkly.Client`. Substituting `LaunchDarkly.Client` version 5.6.3 with `LaunchDarkly.ServerSdk` version 5.6.4 will not affect functionality. diff --git a/src/LaunchDarkly.ServerSdk/FeatureRequestor.cs b/src/LaunchDarkly.ServerSdk/FeatureRequestor.cs index f7fa17cc..e0f0a513 100644 --- a/src/LaunchDarkly.ServerSdk/FeatureRequestor.cs +++ b/src/LaunchDarkly.ServerSdk/FeatureRequestor.cs @@ -94,15 +94,22 @@ private async Task GetAsync(Uri path) where T : class Log.Debug("Get all flags returned 304: not modified"); return null; } - lock (_etags) - { - _etags[path] = response.Headers.ETag; - } //We ensure the status code after checking for 304, because 304 isn't considered success if (!response.IsSuccessStatusCode) { throw new UnsuccessfulResponseException((int)response.StatusCode); } + lock (_etags) + { + if (response.Headers.ETag != null) + { + _etags[path] = response.Headers.ETag; + } + else + { + _etags.Remove(path); + } + } var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); return string.IsNullOrEmpty(content) ? null : (T)JsonConvert.DeserializeObject(content); } diff --git a/src/LaunchDarkly.ServerSdk/LaunchDarkly.ServerSdk.csproj b/src/LaunchDarkly.ServerSdk/LaunchDarkly.ServerSdk.csproj index 5283e216..e6e4bab9 100644 --- a/src/LaunchDarkly.ServerSdk/LaunchDarkly.ServerSdk.csproj +++ b/src/LaunchDarkly.ServerSdk/LaunchDarkly.ServerSdk.csproj @@ -1,6 +1,6 @@  - 5.6.4 + 5.6.5 netstandard1.4;netstandard1.6;netstandard2.0;net45 https://raw.githubusercontent.com/launchdarkly/dotnet-server-sdk/master/LICENSE portable diff --git a/test/LaunchDarkly.ServerSdk.Tests/FeatureRequestorTest.cs b/test/LaunchDarkly.ServerSdk.Tests/FeatureRequestorTest.cs index 316490a6..1a840ff8 100644 --- a/test/LaunchDarkly.ServerSdk.Tests/FeatureRequestorTest.cs +++ b/test/LaunchDarkly.ServerSdk.Tests/FeatureRequestorTest.cs @@ -173,6 +173,34 @@ public async Task ETagsDoNotConflict() Assert.Equal(new List { etag1 }, reqs[4].RequestMessage.Headers["If-None-Match"]); } + [Fact] + public async Task ResponseWithoutEtagClearsPriorEtag() + { + var etag = @"""abc123"""; + + _server.Given(Request.Create().UsingGet()) + .AtPriority(2) + .RespondWith(Response.Create().WithStatusCode(200).WithHeader("Etag", etag).WithBody(AllDataJson)); + _server.Given(Request.Create().UsingGet().WithHeader("If-None-Match", etag)) + .AtPriority(1) + .RespondWith(Response.Create().WithStatusCode(200).WithBody(AllDataJson)); // respond with no etag + + var fetch1 = await _requestor.GetAllDataAsync(); + var fetch2 = await _requestor.GetAllDataAsync(); + + _server.Given(Request.Create().UsingGet()) + .AtPriority(1) + .RespondWith(Response.Create().WithStatusCode(200).WithHeader("Etag", etag).WithBody(AllDataJson)); + + var fetch3 = await _requestor.GetAllDataAsync(); + + var reqs = new List(_server.LogEntries); + Assert.Equal(3, reqs.Count); + Assert.False(reqs[0].RequestMessage.Headers.ContainsKey("If-None-Match")); + Assert.Equal(new List { etag }, reqs[1].RequestMessage.Headers["If-None-Match"]); + Assert.False(reqs[2].RequestMessage.Headers.ContainsKey("If-None-Match")); + } + private RequestMessage GetLastRequest() { foreach (LogEntry le in _server.LogEntries)