|
| 1 | +import 'dart:io'; |
| 2 | + |
1 | 3 | import 'package:flutter/services.dart';
|
2 |
| -import 'package:shelf/shelf.dart'; |
3 | 4 | import 'package:mime/mime.dart';
|
4 | 5 | import 'package:path/path.dart' as p;
|
5 |
| -import 'dart:io'; |
| 6 | +import 'package:shelf/shelf.dart'; |
6 | 7 |
|
7 | 8 | /// The default resolver for MIME types.
|
8 | 9 | final _defaultMimeTypeResolver = MimeTypeResolver();
|
9 | 10 |
|
10 | 11 | /// Creates a Shelf [Handler] that serves files from Flutter assets.
|
11 | 12 | ///
|
| 13 | +/// If requested resource does not exist and [defaultDocument] is specified, |
| 14 | +/// request path is checked for a resource with that name. |
| 15 | +/// If it exists, it is served. |
| 16 | +/// |
12 | 17 | /// Specify a custom [contentTypeResolver] to customize automatic content type
|
13 | 18 | /// detection.
|
14 |
| -Handler createAssetHandler({MimeTypeResolver? contentTypeResolver}) { |
| 19 | +Handler createAssetHandler( |
| 20 | + {String? defaultDocument, MimeTypeResolver? contentTypeResolver}) { |
15 | 21 | final mimeResolver = contentTypeResolver ?? _defaultMimeTypeResolver;
|
16 | 22 |
|
17 | 23 | return (Request request) async {
|
18 | 24 | final segments = ['assets', ...request.url.pathSegments];
|
19 | 25 |
|
20 |
| - final key = p.joinAll(segments); |
| 26 | + String key = p.joinAll(segments); |
21 | 27 |
|
22 |
| - try { |
23 |
| - final body = await _loadResource(key); |
| 28 | + Uint8List? body; |
24 | 29 |
|
25 |
| - final contentType = mimeResolver.lookup(key); |
| 30 | + body = await _loadResource(key); |
26 | 31 |
|
27 |
| - final headers = { |
28 |
| - HttpHeaders.contentLengthHeader: '${body.length}', |
29 |
| - if (contentType != null) HttpHeaders.contentTypeHeader: contentType, |
30 |
| - }; |
| 32 | + if (body == null && defaultDocument != null) { |
| 33 | + key = p.join(key, defaultDocument); |
31 | 34 |
|
32 |
| - return Response.ok(body, headers: headers); |
33 |
| - } catch (_) { |
| 35 | + body = await _loadResource(key); |
| 36 | + } |
| 37 | + |
| 38 | + if (body == null) { |
34 | 39 | return Response.notFound('Not Found');
|
35 | 40 | }
|
| 41 | + |
| 42 | + final contentType = mimeResolver.lookup(key); |
| 43 | + |
| 44 | + final headers = { |
| 45 | + HttpHeaders.contentLengthHeader: '${body.length}', |
| 46 | + if (contentType != null) HttpHeaders.contentTypeHeader: contentType, |
| 47 | + }; |
| 48 | + |
| 49 | + return Response.ok(body, headers: headers); |
36 | 50 | };
|
37 | 51 | }
|
38 | 52 |
|
39 |
| -Future<Uint8List> _loadResource(String key) async { |
40 |
| - final byteData = await rootBundle.load(key); |
| 53 | +Future<Uint8List?> _loadResource(String key) async { |
| 54 | + try { |
| 55 | + final byteData = await rootBundle.load(key); |
| 56 | + |
| 57 | + return byteData.buffer.asUint8List(); |
| 58 | + } catch (_) {} |
41 | 59 |
|
42 |
| - return byteData.buffer.asUint8List(); |
| 60 | + return null; |
43 | 61 | }
|
0 commit comments