diff --git a/src/NzbDrone.Common.Test/Http/HttpUriFixture.cs b/src/NzbDrone.Common.Test/Http/HttpUriFixture.cs index d25d07bfe..18c5c20fb 100644 --- a/src/NzbDrone.Common.Test/Http/HttpUriFixture.cs +++ b/src/NzbDrone.Common.Test/Http/HttpUriFixture.cs @@ -53,6 +53,26 @@ namespace NzbDrone.Common.Test.Http newUri.FullUri.Should().Be(expected); } + [TestCase("", "./relative", "relative")] + [TestCase("/", "./relative", "/relative")] + [TestCase("/base", "./relative", "/relative")] + [TestCase("/base/sub", "./relative", "/base/relative")] + [TestCase("/base/sub/", "./relative", "/base/sub/relative")] + [TestCase("base/sub", "./relative", "base/relative")] + [TestCase("base/sub/", "./relative", "base/sub/relative")] + [TestCase("", "../relative", "relative")] + [TestCase("/", "../relative", "/relative")] + [TestCase("/base", "../relative", "/relative")] + [TestCase("/base/sub", "../relative", "/base/relative")] + [TestCase("/base/sub/", "../relative", "/base/sub/relative")] + [TestCase("base/sub", "../relative", "base/relative")] + [TestCase("base/sub/", "../relative", "base/sub/relative")] + public void should_combine_uri_with_dot_segment(string basePath, string relativePath, string expected) + { + var newUri = new HttpUri(basePath) + new HttpUri(relativePath); + newUri.FullUri.Should().Be(expected); + } + [TestCase("", "", "")] [TestCase("/", "", "/")] [TestCase("base", "", "base")] diff --git a/src/NzbDrone.Common/Http/HttpUri.cs b/src/NzbDrone.Common/Http/HttpUri.cs index 17130b4a2..d3fa7bb00 100644 --- a/src/NzbDrone.Common/Http/HttpUri.cs +++ b/src/NzbDrone.Common/Http/HttpUri.cs @@ -166,6 +166,37 @@ namespace NzbDrone.Common.Http return relativePath; } + if (relativePath.StartsWith("./")) + { + relativePath = relativePath.TrimStart('.').TrimStart('/'); + + var lastIndex = basePath.LastIndexOf("/"); + + if (lastIndex > 0) + { + basePath = basePath.Substring(0, lastIndex) + "/"; + } + } + + if (relativePath.StartsWith("../")) + { + relativePath = relativePath.TrimStart('.').TrimStart('/'); + + var lastIndex = basePath.LastIndexOf("/"); + + if (lastIndex > 0) + { + basePath = basePath.Substring(0, lastIndex) + "/"; + } + + var secondLastIndex = basePath.LastIndexOf("/"); + + if (lastIndex > 0) + { + basePath = basePath.Substring(0, secondLastIndex) + "/"; + } + } + var baseSlashIndex = basePath.LastIndexOf('/'); if (baseSlashIndex >= 0)