support If-Modified-Since
diff --git a/lib/shelf_static.dart b/lib/shelf_static.dart
index 6ef0af8..1026972 100644
--- a/lib/shelf_static.dart
+++ b/lib/shelf_static.dart
@@ -12,8 +12,6 @@
// mime type handling
// hidden files
-// If-Modified-Since on request
-
Handler getHandler(String fileSystemPath) {
var rootDir = new Directory(fileSystemPath);
fileSystemPath = rootDir.resolveSymbolicLinksSync();
@@ -45,6 +43,12 @@
var fileStat = file.statSync();
+ var ifModifiedSince = request.ifModifiedSince;
+
+ if (ifModifiedSince != null && !fileStat.changed.isAfter(ifModifiedSince)) {
+ return new Response.notModified();
+ }
+
var headers = <String, String>{
HttpHeaders.CONTENT_LENGTH: fileStat.size.toString(),
HttpHeaders.LAST_MODIFIED: formatHttpDate(fileStat.changed)
diff --git a/pubspec.yaml b/pubspec.yaml
index 29a2522..3910e54 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: shelf_static
-version: 0.1.1+1
+version: 0.1.2-dev
author: Kevin Moore <github@j832.com>
description: Static file server support for Shelf
homepage: https://github.com/kevmoo/shelf_static.dart
diff --git a/test/basic_file_test.dart b/test/basic_file_test.dart
index ce68432..9f051f6 100644
--- a/test/basic_file_test.dart
+++ b/test/basic_file_test.dart
@@ -1,6 +1,7 @@
library shelf_static.basic_file_test;
import 'dart:io';
+import 'package:http_parser/http_parser.dart';
import 'package:path/path.dart' as p;
import 'package:scheduled_test/descriptor.dart' as d;
import 'package:scheduled_test/scheduled_test.dart';
@@ -99,6 +100,70 @@
});
});
+ group('if modified since', () {
+ test('same as last modified', () {
+
+ schedule(() {
+ var handler = getHandler(d.defaultRoot);
+
+ var rootPath = p.join(d.defaultRoot, 'root.txt');
+ var modified = new File(rootPath).statSync().changed.toUtc();
+
+ var headers = {
+ HttpHeaders.IF_MODIFIED_SINCE: formatHttpDate(modified)
+ };
+
+ return makeRequest(handler, '/root.txt', headers: headers)
+ .then((response) {
+ expect(response.statusCode, HttpStatus.NOT_MODIFIED);
+ expect(response.contentLength, isNull);
+ });
+ });
+ });
+
+ test('before last modified', () {
+
+ schedule(() {
+ var handler = getHandler(d.defaultRoot);
+
+ var rootPath = p.join(d.defaultRoot, 'root.txt');
+ var modified = new File(rootPath).statSync().changed.toUtc();
+
+ var headers = {
+ HttpHeaders.IF_MODIFIED_SINCE:
+ formatHttpDate(modified.subtract(const Duration(seconds: 1)))
+ };
+
+ return makeRequest(handler, '/root.txt', headers: headers)
+ .then((response) {
+ expect(response.statusCode, HttpStatus.OK);
+ expect(response.lastModified, modified);
+ });
+ });
+ });
+
+ test('after last modified', () {
+
+ schedule(() {
+ var handler = getHandler(d.defaultRoot);
+
+ var rootPath = p.join(d.defaultRoot, 'root.txt');
+ var modified = new File(rootPath).statSync().changed.toUtc();
+
+ var headers = {
+ HttpHeaders.IF_MODIFIED_SINCE:
+ formatHttpDate(modified.add(const Duration(seconds: 1)))
+ };
+
+ return makeRequest(handler, '/root.txt', headers: headers)
+ .then((response) {
+ expect(response.statusCode, HttpStatus.NOT_MODIFIED);
+ expect(response.contentLength, isNull);
+ });
+ });
+ });
+ });
+
// getHandler for non-existant directory
// evil URL fixes
diff --git a/test/test_util.dart b/test/test_util.dart
index 01238c2..a019814 100644
--- a/test/test_util.dart
+++ b/test/test_util.dart
@@ -14,13 +14,13 @@
/// Makes a simple GET request to [handler] and returns the result.
Future<Response> makeRequest(Handler handler, String path,
- {String scriptName}) {
+ {String scriptName, Map<String, String> headers}) {
var rootedHandler = _rootHandler(scriptName, handler);
- return syncFuture(() => rootedHandler(_fromPath(path)));
+ return syncFuture(() => rootedHandler(_fromPath(path, headers)));
}
-Request _fromPath(String path) =>
- new Request('GET', Uri.parse('http://localhost' + path));
+Request _fromPath(String path, Map<String, String> headers) =>
+ new Request('GET', Uri.parse('http://localhost' + path), headers: headers);
Handler _rootHandler(String scriptName, Handler handler) {
if (scriptName == null || scriptName.isEmpty) {