Skip to content

Commit 2aa9016

Browse files
[flutter_tools] ensure etag headers are ascii (flutter#55704)
1 parent 34b8f83 commit 2aa9016

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

packages/flutter_tools/lib/src/build_runner/devfs_web.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,8 @@ class WebAssetServer implements AssetReader {
350350

351351
// For real files, use a serialized file stat plus path as a revision.
352352
// This allows us to update between canvaskit and non-canvaskit SDKs.
353-
final String etag = file.lastModifiedSync().toIso8601String() + file.path;
353+
final String etag = file.lastModifiedSync().toIso8601String()
354+
+ Uri.encodeComponent(file.path);
354355
if (ifNoneMatch == etag) {
355356
return shelf.Response.notModified();
356357
}

packages/flutter_tools/test/general.shard/web/devfs_web_test.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,18 @@ void main() {
324324
expect((await response.read().toList()).first, source.readAsBytesSync());
325325
}));
326326

327+
test('serves valid etag header for asset files with non-ascii chracters', () => testbed.run(() async {
328+
globals.fs.file(globals.fs.path.join('build', 'flutter_assets', 'fooπ'))
329+
..createSync(recursive: true)
330+
..writeAsBytesSync(<int>[1, 2, 3]);
331+
332+
final Response response = await webAssetServer
333+
.handleRequest(Request('GET', Uri.parse('http://foobar/assets/fooπ')));
334+
final String etag = response.headers[HttpHeaders.etagHeader];
335+
336+
expect(etag.runes, everyElement(predicate((int char) => char < 255)));
337+
}));
338+
327339
test('handles serving missing asset file', () => testbed.run(() async {
328340
final Response response = await webAssetServer
329341
.handleRequest(Request('GET', Uri.parse('http://foobar/assets/foo')));

0 commit comments

Comments
 (0)