1
+ // environment variables
2
+ declare const B2_URL : string ;
3
+
1
4
import { getAssetFromKV } from "@cloudflare/kv-asset-handler" ;
2
5
3
6
addEventListener ( "fetch" , ( event ) => {
@@ -9,10 +12,19 @@ addEventListener("fetch", (event) => {
9
12
} ) ;
10
13
11
14
async function handleEvent ( event : FetchEvent ) : Promise < Response > {
12
- const url = new URL ( event . request . url ) ;
15
+ const request = event . request ;
16
+ const url = new URL ( request . url ) ;
13
17
14
18
if ( url . pathname . startsWith ( "/api" ) ) {
15
- return fetch ( event . request ) ;
19
+ const response = await fetch ( request ) ;
20
+
21
+ return hanldeEtag ( request , response ) ;
22
+ }
23
+
24
+ if ( url . pathname . startsWith ( "/thumbnail" ) ) {
25
+ const response = await getAssetFromB2 ( url . pathname . slice ( 10 ) ) ;
26
+
27
+ return hanldeEtag ( request , response ) ;
16
28
}
17
29
18
30
return getAssetFromKV ( event ) . catch ( ( ) =>
@@ -21,3 +33,48 @@ async function handleEvent(event: FetchEvent): Promise<Response> {
21
33
} )
22
34
) ;
23
35
}
36
+
37
+ async function getAssetFromB2 ( key : string ) : Promise < Response > {
38
+ const response = await fetch ( `${ B2_URL } ${ key } ` , {
39
+ cf : { cacheEverything : true , cacheTtl : 60 } ,
40
+ } ) ;
41
+
42
+ const headers = new Headers ( response . headers ) ;
43
+
44
+ if ( ! response . ok ) {
45
+ headers . set ( "cache-control" , "max-age=0, no-cache, no-store" ) ;
46
+
47
+ return new Response ( null , {
48
+ status : 404 ,
49
+ headers,
50
+ statusText : "Not Found" ,
51
+ } ) ;
52
+ }
53
+
54
+ headers . set ( "cache-control" , "public, max-age=3600" ) ;
55
+ if ( headers . has ( "x-bz-upload-timestamp" ) ) {
56
+ headers . set ( "etag" , headers . get ( "x-bz-upload-timestamp" ) as string ) ;
57
+ }
58
+ headers . delete ( "x-bz-content-sha1" ) ;
59
+ headers . delete ( "x-bz-file-id" ) ;
60
+ headers . delete ( "x-bz-file-name" ) ;
61
+ headers . delete ( "x-bz-upload-timestamp" ) ;
62
+
63
+ return new Response ( response . body , { headers } ) ;
64
+ }
65
+
66
+ function hanldeEtag ( request : Request , response : Response ) : Response {
67
+ if (
68
+ response . headers . has ( "etag" ) &&
69
+ request . headers . has ( "if-none-match" ) &&
70
+ request . headers . get ( "if-none-match" ) === response . headers . get ( "etag" )
71
+ ) {
72
+ return new Response ( null , {
73
+ status : 304 ,
74
+ headers : response . headers ,
75
+ statusText : "Not Modified" ,
76
+ } ) ;
77
+ }
78
+
79
+ return response ;
80
+ }
0 commit comments