1
1
import { readableStreamFromReader } from "https://deno.land/[email protected] /streams/conversion.ts" ;
2
- import log from "../lib/log.ts" ;
3
2
import { builtinModuleExts } from "../lib/helpers.ts" ;
3
+ import log from "../lib/log.ts" ;
4
4
import type { AlephConfig } from "./types.ts" ;
5
5
6
+ const REG_FULL_VERSION = / @ \d + \. \d + \. \d + / ;
7
+
6
8
export default {
7
9
test : ( pathname : string ) => {
8
10
return pathname . startsWith ( "/-/" ) ||
@@ -22,27 +24,39 @@ export default {
22
24
if ( pathname . endsWith ( ".css" ) && ! searchParams . has ( "module" ) ) {
23
25
ctype = "text/css; charset=utf-8" ;
24
26
}
25
- const stat = await Deno . lstat ( filePath ) ;
26
- if ( stat . isFile ) {
27
- const { mtime } = stat ;
28
- const etag = mtime ? mtime . getTime ( ) . toString ( 16 ) + "-" + stat . size . toString ( 16 ) : null ;
29
- if ( etag && req . headers . get ( "If-None-Match" ) === etag ) {
30
- return new Response ( null , { status : 304 } ) ;
27
+ const headers = new Headers ( { "Content-Type" : ctype } ) ;
28
+ const deplyId = Deno . env . get ( "DENO_DEPLOYMENT_ID" ) ;
29
+ let etag : string | null = null ;
30
+ if ( deplyId ) {
31
+ etag = `${ btoa ( pathname ) . replace ( / [ ^ a - z 0 - 9 ] / g, "" ) } -${ deplyId } ` ;
32
+ } else {
33
+ const stat = await Deno . lstat ( filePath ) ;
34
+ if ( ! stat . isFile ) {
35
+ return new Response ( "File Not Found" , { status : 404 } ) ;
31
36
}
32
- const file = await Deno . open ( filePath , { read : true } ) ;
33
- const headers = new Headers ( { "Content-Type" : ctype } ) ;
37
+ const { mtime, size } = stat ;
34
38
if ( mtime ) {
35
- headers . set ( "Etag" , etag ! ) ;
36
- headers . set ( "Last-Modified" , mtime . toUTCString ( ) ) ;
39
+ etag = mtime . getTime ( ) . toString ( 16 ) + "-" + size . toString ( 16 ) ;
40
+ headers . append ( "Last-Modified" , new Date ( mtime ) . toUTCString ( ) ) ;
37
41
}
38
- return new Response ( readableStreamFromReader ( file ) , { headers } ) ;
39
42
}
43
+ if ( etag && req . headers . get ( "If-None-Match" ) === etag ) {
44
+ return new Response ( null , { status : 304 } ) ;
45
+ }
46
+ const file = await Deno . open ( filePath , { read : true } ) ;
47
+ if ( etag ) {
48
+ headers . append ( "Etag" , etag ) ;
49
+ }
50
+ if ( searchParams . get ( "v" ) || ( pathname . startsWith ( "/-/" ) && REG_FULL_VERSION . test ( pathname ) ) ) {
51
+ headers . append ( "Cache-Control" , "public, max-age=31536000, immutable" ) ;
52
+ }
53
+ return new Response ( readableStreamFromReader ( file ) , { headers } ) ;
40
54
} catch ( err ) {
41
- if ( ! ( err instanceof Deno . errors . NotFound ) ) {
42
- log . error ( err ) ;
43
- return new Response ( "Internal Server Error" , { status : 500 } ) ;
55
+ if ( err instanceof Deno . errors . NotFound ) {
56
+ return new Response ( "File Not Found" , { status : 404 } ) ;
44
57
}
58
+ log . error ( err ) ;
59
+ return new Response ( "Internal Server Error" , { status : 500 } ) ;
45
60
}
46
- return new Response ( "Not Found" , { status : 404 } ) ;
47
61
} ,
48
62
} ;
0 commit comments