From f5181a186dff4f9efa36c1d2f2b803da554cb814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20So=C3=B3s?= Date: Thu, 12 Dec 2024 10:43:53 +0100 Subject: [PATCH] Fix documentation URL preprocessing to recognize directories with dots. (#8401) --- app/lib/frontend/handlers/documentation.dart | 28 ++++++++++++++++++- .../frontend/handlers/documentation_test.dart | 15 ++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/app/lib/frontend/handlers/documentation.dart b/app/lib/frontend/handlers/documentation.dart index a7fd02ba6..1a96248ff 100644 --- a/app/lib/frontend/handlers/documentation.dart +++ b/app/lib/frontend/handlers/documentation.dart @@ -124,7 +124,7 @@ DocFilePath? parseRequestUri(Uri uri) { final relativeSegments = uri.pathSegments.skip(3).where((s) => s.isNotEmpty).toList(); var pathSegments = relativeSegments; - if (relativeSegments.isEmpty || !relativeSegments.last.contains('.')) { + if (_expandToIndexHtml(relativeSegments)) { pathSegments = [...relativeSegments, 'index.html']; } final path = p.normalize(p.joinAll(pathSegments)); @@ -143,6 +143,32 @@ DocFilePath? parseRequestUri(Uri uri) { return DocFilePath(package, version, path); } +const _nonExpandedExtensions = { + '.html', + '.json', + '.gz', + '.png', + '.svg', +}; +// NOTE: This is a best-effort detection on the segments. +// Instead, we should rather check if the file (or the updated path) +// is in the generated output, and base the decision on the file list. +// However, with the current serving code it is costly, we need to refactor it. +// TODO: Use blob index to decide how the relative path should be handled +bool _expandToIndexHtml(List segments) { + if (segments.isEmpty) { + return true; + } + if (!segments.last.contains('.')) { + return true; + } + if (segments.first.contains('static-assets')) { + return false; + } + final ext = p.extension(segments.last); + return !_nonExpandedExtensions.contains(ext); +} + bool _isValidVersion(String version) { if (version.trim().isEmpty) return false; if (version == 'latest') return true; diff --git a/app/test/frontend/handlers/documentation_test.dart b/app/test/frontend/handlers/documentation_test.dart index 438bb2abf..92c4791a7 100644 --- a/app/test/frontend/handlers/documentation_test.dart +++ b/app/test/frontend/handlers/documentation_test.dart @@ -78,6 +78,18 @@ void main() { testUri( '/documentation/pkg/1.0.0/A%20_0.html', 'pkg', '1.0.0', 'A _0.html'); }); + + test('library with dots are recognized', () { + testUri('/documentation/pkg/latest/a.b.c', 'pkg', 'latest', + 'a.b.c/index.html'); + testUri('/documentation/pkg/latest/a.b.c/', 'pkg', 'latest', + 'a.b.c/index.html'); + }); + + test('static assets are left as-is', () { + testUri('/documentation/pkg/latest/static-assets/search.svg', 'pkg', + 'latest', 'static-assets/search.svg'); + }); }); group('dartdoc handlers', () { @@ -110,6 +122,9 @@ void main() { await expectRedirectResponse( await issueGet('/documentation/oxygen/1.0.0/abc'), '/documentation/oxygen/1.0.0/abc/'); + await expectRedirectResponse( + await issueGet('/documentation/oxygen/1.0.0/abc.def'), + '/documentation/oxygen/1.0.0/abc.def/'); await expectRedirectResponse( await issueGet('/documentation/oxygen/latest/abc/def'), '/documentation/oxygen/latest/abc/def/');