Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Commit 4cb9003

Browse files
prepare 5.14.2 release (#136)
1 parent 430d363 commit 4cb9003

File tree

7 files changed

+130
-9
lines changed

7 files changed

+130
-9
lines changed

src/LaunchDarkly.ServerSdk/FeatureRequestor.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Collections.Generic;
88
using Common.Logging;
99
using LaunchDarkly.Client.Interfaces;
10+
using LaunchDarkly.Client.Utils;
1011
using LaunchDarkly.Common;
1112

1213
namespace LaunchDarkly.Client
@@ -21,7 +22,7 @@ internal class FeatureRequestor : IFeatureRequestor
2122

2223
internal FeatureRequestor(Configuration config, Uri baseUri)
2324
{
24-
_allUri = new Uri(baseUri.AbsoluteUri + "sdk/latest-all");
25+
_allUri = baseUri.AddPath("sdk/latest-all");
2526
_httpClient = Util.MakeHttpClient(config.HttpRequestConfiguration, ServerSideClientEnvironment.Instance);
2627
_httpConfig = config.HttpConfiguration;
2728
}

src/LaunchDarkly.ServerSdk/Integrations/EventProcessorBuilder.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Collections.Immutable;
44
using LaunchDarkly.Client.Interfaces;
5+
using LaunchDarkly.Client.Utils;
56
using LaunchDarkly.Common;
67

78
namespace LaunchDarkly.Client.Integrations
@@ -267,8 +268,8 @@ IEventProcessor IEventProcessorFactoryWithDiagnostics.CreateEventProcessor(Confi
267268
EventCapacity = _capacity,
268269
EventFlushInterval = _flushInterval,
269270
EventSamplingInterval = _samplingInterval,
270-
EventsUri = new Uri(_baseUri, "bulk"),
271-
DiagnosticUri = new Uri(_baseUri, "diagnostic"),
271+
EventsUri = _baseUri.AddPath("bulk"),
272+
DiagnosticUri = _baseUri.AddPath("diagnostic"),
272273
HttpClientTimeout = httpConfig.ConnectTimeout,
273274
InlineUsersInEvents = _inlineUsersInEvents,
274275
PrivateAttributeNames = _privateAttributes.ToImmutableHashSet(),

src/LaunchDarkly.ServerSdk/StreamProcessor.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Newtonsoft.Json;
66
using Newtonsoft.Json.Linq;
77
using LaunchDarkly.Client.Interfaces;
8+
using LaunchDarkly.Client.Utils;
89
using LaunchDarkly.Common;
910

1011
namespace LaunchDarkly.Client
@@ -30,7 +31,7 @@ TimeSpan initialReconnectDelay
3031
)
3132
{
3233
var httpConfig = config.HttpConfiguration;
33-
var streamProperties = new StreamProperties(new Uri(baseUri, "/all"),
34+
var streamProperties = new StreamProperties(baseUri.AddPath("/all"),
3435
HttpMethod.Get, null);
3536
var streamManagerConfig = new StreamManagerConfigImpl
3637
{
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
3+
namespace LaunchDarkly.Client.Utils
4+
{
5+
internal static class UriExtensions
6+
{
7+
// This differs from "new Uri(baseUri, path)" in that it always assumes a trailing "/" in
8+
// baseUri. For instance, if baseUri is http://hostname/basepath and path is "relativepath",
9+
// baseUri.AddPath(path) will return http://hostname/basepath/relativepath, whereas
10+
// new Uri(baseUri, path) would return http://hostname/relativepath (since, with no trailing
11+
// slash, it would treat "basepath" as the equivalent of a filename rather than the
12+
// equivalent of a directory name). We should assume that if an application has specified a
13+
// base URL with a non-empty path, the intention is to use that as a prefix for everything.
14+
public static Uri AddPath(this Uri baseUri, string path)
15+
{
16+
var ub = new UriBuilder(baseUri);
17+
ub.Path = ub.Path.TrimEnd('/') + "/" + path.TrimStart('/');
18+
return ub.Uri;
19+
}
20+
}
21+
}

test/LaunchDarkly.ServerSdk.Tests/FeatureRequestorTest.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using LaunchDarkly.Client;
22
using System;
33
using System.Collections.Generic;
4+
using System.Net.Http;
45
using System.Threading.Tasks;
56
using WireMock;
67
using WireMock.Logging;
@@ -23,6 +24,35 @@ private IFeatureRequestor MakeRequestor(FluentMockServer server)
2324
return new FeatureRequestor(config, new Uri(server.Urls[0]));
2425
}
2526

27+
[Theory]
28+
[InlineData("", "/sdk/latest-all")]
29+
[InlineData("/basepath", "/basepath/sdk/latest-all")]
30+
[InlineData("/basepath/", "/basepath/sdk/latest-all")]
31+
public async Task GetAllUsesCorrectUriAndMethodAsync(
32+
string baseUriExtraPath,
33+
string expectedPath
34+
)
35+
{
36+
using (var server = await TestHttpUtils.StartServerAsync())
37+
{
38+
server.Given(Request.Create().UsingGet())
39+
.RespondWith(Response.Create().WithStatusCode(200).WithBody(AllDataJson));
40+
41+
var config = Configuration.Builder("key")
42+
.Http(Components.HttpConfiguration().ConnectTimeout(TimeSpan.FromDays(1)))
43+
.Build();
44+
var baseUri = new Uri(server.Urls[0] + baseUriExtraPath);
45+
46+
using (var requestor = new FeatureRequestor(config, baseUri))
47+
{
48+
await requestor.GetAllDataAsync();
49+
50+
var req = GetLastRequest(server);
51+
Assert.Equal("GET", req.Method.ToUpper());
52+
}
53+
}
54+
}
55+
2656
[Fact]
2757
public async Task GetAllUsesCorrectUriAndParsesResponseAsync()
2858
{
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System;
2+
using System.Collections.Concurrent;
3+
using System.Threading.Tasks;
4+
using LaunchDarkly.Client;
5+
using WireMock;
6+
using WireMock.RequestBuilders;
7+
using WireMock.ResponseBuilders;
8+
using Xunit;
9+
10+
namespace LaunchDarkly.Tests
11+
{
12+
public class LdClientEndToEndTest
13+
{
14+
[Theory]
15+
[InlineData("", "")]
16+
[InlineData("/", "")]
17+
[InlineData("/basepath", "/basepath")]
18+
[InlineData("/basepath/", "/basepath")]
19+
public async Task EventsAreSentToCorrectEndpointsAsync(
20+
string baseUriExtraPath,
21+
string expectedBasePath
22+
)
23+
{
24+
using (var server = await TestHttpUtils.StartServerAsync())
25+
{
26+
var requests = new BlockingCollection<RequestMessage>();
27+
server.Given(Request.Create()).RespondWith(Response.Create().WithCallback(req =>
28+
{
29+
requests.Add(req);
30+
return new ResponseMessage() { StatusCode = 202 };
31+
32+
}));
33+
34+
var baseUri = server.Urls[0].TrimEnd('/') + baseUriExtraPath;
35+
var config = Configuration.Builder("key")
36+
.DataSource(Components.ExternalUpdatesOnly)
37+
.Events(Components.SendEvents().BaseUri(new Uri(baseUri)))
38+
.Build();
39+
40+
using (var client = new LdClient(config))
41+
{
42+
client.Identify(User.WithKey("userkey"));
43+
client.Flush();
44+
45+
Assert.True(requests.TryTake(out var request1, TimeSpan.FromSeconds(5)));
46+
Assert.True(requests.TryTake(out var request2, TimeSpan.FromSeconds(5)));
47+
48+
if (request1.Path.EndsWith("diagnostic"))
49+
{
50+
var temp = request1;
51+
request1 = request2;
52+
request2 = temp;
53+
}
54+
55+
Assert.Equal("POST", request1.Method.ToUpper());
56+
Assert.Equal(expectedBasePath + "/bulk", request1.Path);
57+
58+
Assert.Equal("POST", request2.Method.ToUpper());
59+
Assert.Equal(expectedBasePath + "/diagnostic", request2.Path);
60+
}
61+
}
62+
}
63+
}
64+
}

test/LaunchDarkly.ServerSdk.Tests/StreamProcessorTest.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,18 @@ public StreamProcessorTest()
4040
.EventSourceCreator(_eventSourceFactory.Create());
4141
}
4242

43-
[Fact]
44-
public void StreamUriHasCorrectEndpoint()
43+
[Theory]
44+
[InlineData("", "/all")]
45+
[InlineData("/basepath", "/basepath/all")]
46+
[InlineData("/basepath/", "/basepath/all")]
47+
public void StreamRequestHasCorrectUriAndMethod(string baseUriExtraPath, string expectedPath)
4548
{
46-
_dataSourceBuilder.BaseUri(new Uri("http://stream.test.com"));
49+
_dataSourceBuilder.BaseUri(new Uri("http://stream.test.com" + baseUriExtraPath));
4750
StreamProcessor sp = CreateAndStartProcessor();
48-
Assert.Equal(new Uri("http://stream.test.com/all"),
51+
Assert.Equal(new Uri("http://stream.test.com" + expectedPath),
4952
_eventSourceFactory.ReceivedProperties.StreamUri);
5053
}
51-
54+
5255
[Fact]
5356
public void PutCausesFeatureToBeStored()
5457
{

0 commit comments

Comments
 (0)