shelf_static: ignore invalid If-Modified-Since headers (#557) A request with a malformed If-Modified-Since header made the static and file handlers throw the FormatException from Request.ifModifiedSince, which shelf_io turns into a 500. RFC 9110 section 13.1.3 requires an invalid value to be ignored, so treat it as absent.
diff --git a/pkgs/shelf_static/CHANGELOG.md b/pkgs/shelf_static/CHANGELOG.md index 48df44f..f6b1ae4 100644 --- a/pkgs/shelf_static/CHANGELOG.md +++ b/pkgs/shelf_static/CHANGELOG.md
@@ -1,3 +1,8 @@ +## 1.2.1-wip + +* Ignore invalid `If-Modified-Since` headers instead of failing the request + with a `FormatException`. + ## 1.2.0 * Fix unhandled `FormatException` / HTTP 500 error when parsing oversized integer
diff --git a/pkgs/shelf_static/lib/src/static_handler.dart b/pkgs/shelf_static/lib/src/static_handler.dart index e5d5ee3..6716343 100644 --- a/pkgs/shelf_static/lib/src/static_handler.dart +++ b/pkgs/shelf_static/lib/src/static_handler.dart
@@ -235,7 +235,7 @@ FileStat? fileStat, }) async { final stat = fileStat ?? await file.stat(); - final ifModifiedSince = request.ifModifiedSince; + final ifModifiedSince = _ifModifiedSince(request); final ifNoneMatch = request.headers[HttpHeaders.ifNoneMatchHeader]; generateETag ??= _defaultGenerateETag; @@ -279,6 +279,18 @@ ); } +/// Returns the parsed `If-Modified-Since` header of [request], or `null` if +/// it is absent or not a valid HTTP date. +/// +/// Per RFC 9110 § 13.1.3, an invalid `If-Modified-Since` value must be ignored. +DateTime? _ifModifiedSince(Request request) { + try { + return request.ifModifiedSince; + } on FormatException { + return null; + } +} + String _defaultGenerateETag(File file, FileStat stat) => 'W/"${stat.size}-${stat.modified.millisecondsSinceEpoch}"';
diff --git a/pkgs/shelf_static/pubspec.yaml b/pkgs/shelf_static/pubspec.yaml index 78c17e3..3ea84ae 100644 --- a/pkgs/shelf_static/pubspec.yaml +++ b/pkgs/shelf_static/pubspec.yaml
@@ -1,5 +1,5 @@ name: shelf_static -version: 1.2.0 +version: 1.2.1-wip description: Static file server support for the shelf package and ecosystem. repository: https://github.com/dart-lang/shelf/tree/master/pkgs/shelf_static issue_tracker: https://github.com/dart-lang/shelf/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Ashelf_static
diff --git a/pkgs/shelf_static/test/basic_file_test.dart b/pkgs/shelf_static/test/basic_file_test.dart index d76ffd9..059f34a 100644 --- a/pkgs/shelf_static/test/basic_file_test.dart +++ b/pkgs/shelf_static/test/basic_file_test.dart
@@ -163,6 +163,18 @@ expect(response.contentLength, 0); }); + test('invalid date is ignored', () async { + final handler = createStaticHandler(d.sandbox); + + final response = await makeRequest( + handler, + '/root.txt', + headers: {HttpHeaders.ifModifiedSinceHeader: 'not a date'}, + ); + expect(response.statusCode, HttpStatus.ok); + expect(await response.readAsString(), 'root txt'); + }); + test('after file modification', () async { // This test updates a file on disk to ensure the file stamp is updated // which was previously not the case on Windows due to the files "changed"