Skip to content

Commit

Permalink
Make the forward slash optional
Browse files Browse the repository at this point in the history
  • Loading branch information
shaan1337 committed Jul 7, 2020
1 parent f4ffa9c commit 52ffeab
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 18 deletions.
24 changes: 18 additions & 6 deletions src/EventStore.Client/EventStoreClientSettings.ConnectionString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,28 @@ public static EventStoreClientSettings Parse(string connectionString) {
currentIndex = userInfoIndex + UserInfoSeparator.Length;
}


var slashIndex = connectionString.IndexOf(Slash, currentIndex, StringComparison.Ordinal);
if (slashIndex == -1)
throw new ConnectionStringParseException("The connection string must contain a / (forward slash) after specifying the hosts");
var questionMarkIndex = connectionString.IndexOf(QuestionMark, Math.Max(currentIndex, slashIndex), StringComparison.Ordinal);
var endIndex = connectionString.Length;

//for simpler substring operations:
if (slashIndex == -1) slashIndex = int.MaxValue;
if (questionMarkIndex == -1) questionMarkIndex = int.MaxValue;

var hostSeparatorIndex = Math.Min(Math.Min(slashIndex, questionMarkIndex), endIndex);
var hosts = ParseHosts(connectionString.Substring(currentIndex,hostSeparatorIndex - currentIndex));
currentIndex = hostSeparatorIndex;

string path = "";
if (slashIndex != int.MaxValue)
path = connectionString.Substring(currentIndex,Math.Min(questionMarkIndex, endIndex) - currentIndex);

var hosts = ParseHosts(connectionString.Substring(currentIndex, slashIndex - currentIndex));
currentIndex = slashIndex + Slash.Length;
if (path != "" && path != "/")
throw new ConnectionStringParseException($"The specified path must be either an empty string or a forward slash (/) but the following path was found instead: '{path}'");

var questionMarkIndex = connectionString.IndexOf(QuestionMark, currentIndex);
var options = new Dictionary<string, string>();
if (questionMarkIndex != -1) {
if (questionMarkIndex != int.MaxValue) {
currentIndex = questionMarkIndex + QuestionMark.Length;
options = ParseKeyValuePairs(connectionString.Substring(currentIndex));
}
Expand Down
63 changes: 51 additions & 12 deletions test/EventStore.Client.Tests/ConnectionStringTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,39 +42,78 @@ public void connection_string_with_invalid_userinfo_should_throw() {
}

[Fact]
public void connection_string_without_forward_slash_after_host_should_throw() {
Assert.Throws<ConnectionStringParseException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1");
public void connection_string_with_invalid_host_should_throw() {
Assert.Throws<InvalidHostException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1:abc");
});

Assert.Throws<ConnectionStringParseException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1:1234");
Assert.Throws<InvalidHostException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1:abc/");
});
}

[Fact]
public void connection_string_with_invalid_host_should_throw() {
Assert.Throws<InvalidHostException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1:abc/");
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1:1234,127.0.0.2:abc,127.0.0.3:4321");
});

Assert.Throws<InvalidHostException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1:1234,127.0.0.2:abc,127.0.0.3:4321/");
});

Assert.Throws<InvalidHostException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1:abc:def");
});

Assert.Throws<InvalidHostException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1:abc:def/");
});

Assert.Throws<InvalidHostException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@localhost:1234,127.0.0.2:abc:def,127.0.0.3:4321");
});

Assert.Throws<InvalidHostException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@localhost:1234,127.0.0.2:abc:def,127.0.0.3:4321/");
});

Assert.Throws<InvalidHostException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@localhost:1234,,127.0.0.3:4321");
});

Assert.Throws<InvalidHostException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@localhost:1234,,127.0.0.3:4321/");
});
}

[Fact]
public void connection_string_with_empty_path_after_host_should_not_throw() {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1");
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1:1234");
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1/");
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1?maxDiscoverAttempts=10");
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1/?maxDiscoverAttempts=10");
}

[Fact]
public void connection_string_with_non_empty_path_should_throw() {
Assert.Throws<ConnectionStringParseException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1/test");
});

Assert.Throws<ConnectionStringParseException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1/maxDiscoverAttempts=10");
});

Assert.Throws<ConnectionStringParseException>(() => {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1/hello?maxDiscoverAttempts=10");
});
}

[Fact]
public void connection_string_with_no_key_value_pairs_specified_should_not_throw() {
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1");
EventStoreClientSettings.Create("esdb://user:pass@127.0.0.1/");
}

[Fact]
public void connection_string_with_invalid_key_value_pair_should_throw() {
Assert.Throws<InvalidKeyValuePairException>(() => {
Expand Down Expand Up @@ -157,7 +196,7 @@ public void with_valid_single_node_connection_string() {
Assert.Equal(NodePreference.Follower, settings.ConnectivitySettings.NodePreference);
Assert.NotNull(settings.CreateHttpMessageHandler);

settings = EventStoreClientSettings.Create("esdb://127.0.0.1/?connectionName=test&maxDiscoverAttempts=13&DiscoveryInterval=37&nOdEPrEfErence=FoLLoWer&tls=true&tlsVerifyCert=true&operationTimeout=330&throwOnAppendFailure=faLse");
settings = EventStoreClientSettings.Create("esdb://127.0.0.1?connectionName=test&maxDiscoverAttempts=13&DiscoveryInterval=37&nOdEPrEfErence=FoLLoWer&tls=true&tlsVerifyCert=true&operationTimeout=330&throwOnAppendFailure=faLse");
Assert.Null(settings.DefaultCredentials);
Assert.Equal("test", settings.ConnectionName);
Assert.Equal("https://127.0.0.1:2113/",settings.ConnectivitySettings.Address.ToString());
Expand Down Expand Up @@ -252,7 +291,7 @@ public void with_different_tls_settings() {
settings = EventStoreClientSettings.Create("esdb://127.0.0.1/");
Assert.Equal(Uri.UriSchemeHttps, settings.ConnectivitySettings.Address.Scheme);

settings = EventStoreClientSettings.Create("esdb://127.0.0.1/?tls=true");
settings = EventStoreClientSettings.Create("esdb://127.0.0.1?tls=true");
Assert.Equal(Uri.UriSchemeHttps, settings.ConnectivitySettings.Address.Scheme);

settings = EventStoreClientSettings.Create("esdb://127.0.0.1/?tls=FaLsE");
Expand All @@ -261,7 +300,7 @@ public void with_different_tls_settings() {
settings = EventStoreClientSettings.Create("esdb://127.0.0.1,127.0.0.2:3321,127.0.0.3/");
Assert.True(settings.ConnectivitySettings.GossipOverHttps);

settings = EventStoreClientSettings.Create("esdb://127.0.0.1,127.0.0.2:3321,127.0.0.3/?tls=true");
settings = EventStoreClientSettings.Create("esdb://127.0.0.1,127.0.0.2:3321,127.0.0.3?tls=true");
Assert.True(settings.ConnectivitySettings.GossipOverHttps);

settings = EventStoreClientSettings.Create("esdb://127.0.0.1,127.0.0.2:3321,127.0.0.3/?tls=fAlSe");
Expand Down

0 comments on commit 52ffeab

Please sign in to comment.