Skip to content

Commit b87ae6c

Browse files
committed
Fix issue with requests to delivery API by path where URL segment contains special characters (#19390)
1 parent 3db0ec7 commit b87ae6c

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed

src/Umbraco.Cms.Api.Delivery/Services/RoutingServiceBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ protected Uri GetDefaultRequestUri(string requestedPath)
3636
}
3737

3838
protected static string GetContentRoute(DomainAndUri domainAndUri, Uri contentRoute)
39-
=> $"{domainAndUri.ContentId}{DomainUtilities.PathRelativeToDomain(domainAndUri.Uri, contentRoute.AbsolutePath)}";
39+
=> $"{domainAndUri.ContentId}{DomainUtilities.PathRelativeToDomain(domainAndUri.Uri, contentRoute.LocalPath)}"; // Use LocalPath over AbsolutePath to keep the path decoded.
4040

4141
protected DomainAndUri? GetDomainAndUriForRoute(Uri contentUrl)
4242
{

src/Umbraco.Cms.Api.Delivery/Umbraco.Cms.Api.Delivery.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
2323
<_Parameter1>Umbraco.Tests.UnitTests</_Parameter1>
2424
</AssemblyAttribute>
25+
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
26+
<_Parameter1>Umbraco.Tests.Integration</_Parameter1>
27+
</AssemblyAttribute>
2528
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
2629
<_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
2730
</AssemblyAttribute>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using Microsoft.AspNetCore.Http;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using Moq;
4+
using NUnit.Framework;
5+
using Umbraco.Cms.Api.Delivery.Services;
6+
using Umbraco.Cms.Core.Cache;
7+
using Umbraco.Cms.Core.DeliveryApi;
8+
using Umbraco.Cms.Core.PublishedCache;
9+
using Umbraco.Cms.Core.Routing;
10+
using Umbraco.Cms.Tests.Common.Testing;
11+
using Umbraco.Cms.Tests.Integration.Testing;
12+
13+
namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.DeliveryApi;
14+
15+
[TestFixture]
16+
[UmbracoTest(
17+
Database = UmbracoTestOptions.Database.NewSchemaPerFixture,
18+
WithApplication = true)]
19+
public class RequestRoutingServiceTests : UmbracoIntegrationTest
20+
{
21+
private IRequestRoutingService RequestRoutingService => GetRequiredService<IRequestRoutingService>();
22+
23+
protected override void CustomTestSetup(IUmbracoBuilder builder)
24+
{
25+
builder.Services.AddUnique<IRequestRoutingService, RequestRoutingService>();
26+
27+
var elementCache = new FastDictionaryAppCache();
28+
var snapshotCache = new FastDictionaryAppCache();
29+
30+
var domainCacheMock = new Mock<IDomainCache>();
31+
domainCacheMock.Setup(x => x.GetAll(It.IsAny<bool>()))
32+
.Returns(
33+
[
34+
new Domain(1, "localhost/en", 1000, "en-us", false, 0),
35+
new Domain(2, "localhost/jp", 1000, "ja-jp", false, 1),
36+
]);
37+
builder.Services.AddSingleton(provider => domainCacheMock.Object);
38+
}
39+
40+
[TestCase(null, "")]
41+
[TestCase("", "")]
42+
[TestCase("/", "/")]
43+
[TestCase("/en/test/", "1000/test/")] // Verifies matching a domain.
44+
[TestCase("/da/test/", "/da/test/")] // Verifies that with no matching domain, so route will be returned as is.
45+
[TestCase("/jp/オフィス/", "1000/オフィス/")] // Verifies that with a URL segment containing special characters, the route remains decoded.
46+
public void GetContentRoute_ReturnsExpectedRoute(string? requestedRoute, string expectedResult)
47+
{
48+
if (!string.IsNullOrEmpty(requestedRoute))
49+
{
50+
var httpContextAccessor = GetRequiredService<IHttpContextAccessor>();
51+
52+
httpContextAccessor.HttpContext = new DefaultHttpContext
53+
{
54+
Request =
55+
{
56+
Scheme = "https",
57+
Host = new HostString("localhost"),
58+
Path = requestedRoute,
59+
},
60+
};
61+
}
62+
63+
var result = RequestRoutingService.GetContentRoute(requestedRoute);
64+
Assert.AreEqual(expectedResult, result);
65+
}
66+
}

0 commit comments

Comments
 (0)