Skip to content

Commit f5181a1

Browse files
authored
Fix documentation URL preprocessing to recognize directories with dots. (#8401)
1 parent 8cac40c commit f5181a1

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

app/lib/frontend/handlers/documentation.dart

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ DocFilePath? parseRequestUri(Uri uri) {
124124
final relativeSegments =
125125
uri.pathSegments.skip(3).where((s) => s.isNotEmpty).toList();
126126
var pathSegments = relativeSegments;
127-
if (relativeSegments.isEmpty || !relativeSegments.last.contains('.')) {
127+
if (_expandToIndexHtml(relativeSegments)) {
128128
pathSegments = [...relativeSegments, 'index.html'];
129129
}
130130
final path = p.normalize(p.joinAll(pathSegments));
@@ -143,6 +143,32 @@ DocFilePath? parseRequestUri(Uri uri) {
143143
return DocFilePath(package, version, path);
144144
}
145145

146+
const _nonExpandedExtensions = {
147+
'.html',
148+
'.json',
149+
'.gz',
150+
'.png',
151+
'.svg',
152+
};
153+
// NOTE: This is a best-effort detection on the segments.
154+
// Instead, we should rather check if the file (or the updated path)
155+
// is in the generated output, and base the decision on the file list.
156+
// However, with the current serving code it is costly, we need to refactor it.
157+
// TODO: Use blob index to decide how the relative path should be handled
158+
bool _expandToIndexHtml(List<String> segments) {
159+
if (segments.isEmpty) {
160+
return true;
161+
}
162+
if (!segments.last.contains('.')) {
163+
return true;
164+
}
165+
if (segments.first.contains('static-assets')) {
166+
return false;
167+
}
168+
final ext = p.extension(segments.last);
169+
return !_nonExpandedExtensions.contains(ext);
170+
}
171+
146172
bool _isValidVersion(String version) {
147173
if (version.trim().isEmpty) return false;
148174
if (version == 'latest') return true;

app/test/frontend/handlers/documentation_test.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@ void main() {
7878
testUri(
7979
'/documentation/pkg/1.0.0/A%20_0.html', 'pkg', '1.0.0', 'A _0.html');
8080
});
81+
82+
test('library with dots are recognized', () {
83+
testUri('/documentation/pkg/latest/a.b.c', 'pkg', 'latest',
84+
'a.b.c/index.html');
85+
testUri('/documentation/pkg/latest/a.b.c/', 'pkg', 'latest',
86+
'a.b.c/index.html');
87+
});
88+
89+
test('static assets are left as-is', () {
90+
testUri('/documentation/pkg/latest/static-assets/search.svg', 'pkg',
91+
'latest', 'static-assets/search.svg');
92+
});
8193
});
8294

8395
group('dartdoc handlers', () {
@@ -110,6 +122,9 @@ void main() {
110122
await expectRedirectResponse(
111123
await issueGet('/documentation/oxygen/1.0.0/abc'),
112124
'/documentation/oxygen/1.0.0/abc/');
125+
await expectRedirectResponse(
126+
await issueGet('/documentation/oxygen/1.0.0/abc.def'),
127+
'/documentation/oxygen/1.0.0/abc.def/');
113128
await expectRedirectResponse(
114129
await issueGet('/documentation/oxygen/latest/abc/def'),
115130
'/documentation/oxygen/latest/abc/def/');

0 commit comments

Comments
 (0)