@@ -2,7 +2,8 @@ import { renderHome } from "./home.tsx";
2
2
import oldMappings from "./old_redirects.json" assert { type : "json" } ;
3
3
import { tryResolveLatestJson , tryResolvePluginUrl , tryResolveSchemaUrl } from "./plugins.ts" ;
4
4
import { readInfoFile } from "./readInfoFile.ts" ;
5
- import { fetchCached , getCliInfo } from "./utils/mod.ts" ;
5
+ import { Clock } from "./utils/clock.ts" ;
6
+ import { createFetchCacher , getCliInfo } from "./utils/mod.ts" ;
6
7
7
8
const contentTypes = {
8
9
css : "text/css; charset=utf-8" ,
@@ -12,73 +13,112 @@ const contentTypes = {
12
13
wasm : "application/wasm" ,
13
14
} ;
14
15
15
- export async function handleRequest ( request : Request ) {
16
- const url = new URL ( request . url ) ;
17
- const newUrl = await resolvePluginOrSchemaUrl ( url ) ;
18
- if ( newUrl != null ) {
19
- const contentType = newUrl . endsWith ( ".json" )
20
- ? contentTypes . json
21
- : newUrl . endsWith ( ".wasm" )
22
- ? contentTypes . wasm
23
- : contentTypes . plain ;
24
- return handleConditionalRedirectRequest ( {
25
- request,
26
- url : newUrl ,
27
- contentType,
28
- } ) ;
29
- }
30
-
31
- const userLatestInfo = await tryResolveLatestJson ( url ) ;
32
- if ( userLatestInfo != null ) {
33
- if ( userLatestInfo === 404 ) {
34
- return new Response ( "Not Found" , {
35
- status : 404 ,
36
- } ) ;
16
+ export function createRequestHandler ( clock : Clock ) {
17
+ const { fetchCached } = createFetchCacher ( clock ) ;
18
+ return {
19
+ async handleRequest ( request : Request , info : Deno . ServeHandlerInfo ) {
20
+ const url = new URL ( request . url ) ;
21
+ const newUrl = await resolvePluginOrSchemaUrl ( url ) ;
22
+ if ( newUrl != null ) {
23
+ const contentType = newUrl . endsWith ( ".json" )
24
+ ? contentTypes . json
25
+ : newUrl . endsWith ( ".wasm" )
26
+ ? contentTypes . wasm
27
+ : contentTypes . plain ;
28
+ return handleConditionalRedirectRequest ( {
29
+ request,
30
+ url : newUrl ,
31
+ contentType,
32
+ hostname : info . remoteAddr . hostname ,
33
+ } ) ;
34
+ }
35
+
36
+ const userLatestInfo = await tryResolveLatestJson ( url ) ;
37
+ if ( userLatestInfo != null ) {
38
+ if ( userLatestInfo === 404 ) {
39
+ return new Response ( "Not Found" , {
40
+ status : 404 ,
41
+ } ) ;
42
+ } else {
43
+ return createJsonResponse ( JSON . stringify ( userLatestInfo , undefined , 2 ) , request ) ;
44
+ }
45
+ }
46
+
47
+ if ( url . pathname . startsWith ( "/info.json" ) ) {
48
+ const infoFileData = await readInfoFile ( ) ;
49
+ return createJsonResponse ( JSON . stringify ( infoFileData , null , 2 ) , request ) ;
50
+ }
51
+
52
+ if ( url . pathname . startsWith ( "/cli.json" ) ) {
53
+ const cliInfo = await getCliInfo ( ) ;
54
+ return createJsonResponse ( JSON . stringify ( cliInfo , null , 2 ) , request ) ;
55
+ }
56
+
57
+ if ( url . pathname === "/style.css" ) {
58
+ return Deno . readTextFile ( "./style.css" ) . then ( text =>
59
+ new Response ( text , {
60
+ headers : {
61
+ "content-type" : "text/css; charset=utf-8" ,
62
+ } ,
63
+ status : 200 ,
64
+ } )
65
+ ) ;
66
+ }
67
+
68
+ if ( url . pathname === "/" ) {
69
+ return renderHome ( ) . then ( home =>
70
+ new Response ( home , {
71
+ headers : {
72
+ "content-type" : contentTypes . html ,
73
+ } ,
74
+ status : 200 ,
75
+ } )
76
+ ) . catch ( err =>
77
+ new Response ( `${ err . toString ?.( ) ?? err } ` , {
78
+ headers : {
79
+ "content-type" : contentTypes . plain ,
80
+ } ,
81
+ status : 500 ,
82
+ } )
83
+ ) ;
84
+ }
85
+
86
+ return create404Response ( ) ;
87
+ } ,
88
+ } ;
89
+
90
+ // This is done to allow the playground to access these files
91
+ function handleConditionalRedirectRequest ( params : {
92
+ request : Request ;
93
+ url : string ;
94
+ contentType : string ;
95
+ hostname : string ;
96
+ } ) {
97
+ if ( shouldDirectlyServeFile ( params . request ) ) {
98
+ return fetchCached ( params )
99
+ . then ( result => {
100
+ if ( result . kind === "error" ) {
101
+ return result . response ;
102
+ }
103
+
104
+ return new Response ( result . body , {
105
+ headers : {
106
+ "content-type" : params . contentType ,
107
+ // allow the playground to download this
108
+ "Access-Control-Allow-Origin" : getAccessControlAllowOrigin ( params . request ) ,
109
+ } ,
110
+ status : 200 ,
111
+ } ) ;
112
+ } ) . catch ( err => {
113
+ console . error ( err ) ;
114
+ return new Response ( "Internal Server Error" , {
115
+ status : 500 ,
116
+ } ) ;
117
+ } ) ;
37
118
} else {
38
- return createJsonResponse ( JSON . stringify ( userLatestInfo , undefined , 2 ) , request ) ;
119
+ return createRedirectResponse ( params . url ) ;
39
120
}
40
121
}
41
-
42
- if ( url . pathname . startsWith ( "/info.json" ) ) {
43
- const infoFileData = await readInfoFile ( ) ;
44
- return createJsonResponse ( JSON . stringify ( infoFileData , null , 2 ) , request ) ;
45
- }
46
-
47
- if ( url . pathname . startsWith ( "/cli.json" ) ) {
48
- const cliInfo = await getCliInfo ( ) ;
49
- return createJsonResponse ( JSON . stringify ( cliInfo , null , 2 ) , request ) ;
50
- }
51
-
52
- if ( url . pathname === "/style.css" ) {
53
- return Deno . readTextFile ( "./style.css" ) . then ( text =>
54
- new Response ( text , {
55
- headers : {
56
- "content-type" : "text/css; charset=utf-8" ,
57
- } ,
58
- status : 200 ,
59
- } )
60
- ) ;
61
- }
62
-
63
- if ( url . pathname === "/" ) {
64
- return renderHome ( ) . then ( home =>
65
- new Response ( home , {
66
- headers : {
67
- "content-type" : contentTypes . html ,
68
- } ,
69
- status : 200 ,
70
- } )
71
- ) . catch ( err =>
72
- new Response ( `${ err . toString ?.( ) ?? err } ` , {
73
- headers : {
74
- "content-type" : contentTypes . plain ,
75
- } ,
76
- status : 500 ,
77
- } )
78
- ) ;
79
- }
80
-
81
- return create404Response ( ) ;
82
122
}
83
123
84
124
async function resolvePluginOrSchemaUrl ( url : URL ) {
@@ -87,41 +127,13 @@ async function resolvePluginOrSchemaUrl(url: URL) {
87
127
?? await tryResolveSchemaUrl ( url ) ;
88
128
}
89
129
90
- // This is done to allow the playground to access these files
91
- function handleConditionalRedirectRequest ( params : { request : Request ; url : string ; contentType : string } ) {
92
- if ( shouldDirectlyServeFile ( params . request ) ) {
93
- return fetchCached ( params . url )
94
- . then ( result => {
95
- if ( result . kind === "error" ) {
96
- return result . response ;
97
- }
98
-
99
- return new Response ( result . body , {
100
- headers : {
101
- "content-type" : params . contentType ,
102
- // allow the playground to download this
103
- "Access-Control-Allow-Origin" : getAccessControlAllowOrigin ( params . request ) ,
104
- } ,
105
- status : 200 ,
106
- } ) ;
107
- } ) . catch ( err => {
108
- console . error ( err ) ;
109
- return new Response ( "Internal Server Error" , {
110
- status : 500 ,
111
- } ) ;
112
- } ) ;
113
- } else {
114
- return createRedirectResponse ( params . url ) ;
115
- }
116
- }
117
-
118
130
function getAccessControlAllowOrigin ( request : Request ) {
119
131
const origin = request . headers . get ( "origin" ) ;
120
132
return origin != null && new URL ( origin ) . hostname === "localhost" ? origin : "https://dprint.dev" ;
121
133
}
122
134
123
135
function shouldDirectlyServeFile ( request : Request ) {
124
- // directly serve for when Deno makes a request
136
+ // directly serve for when Deno makes a request in order to fix the content type
125
137
if ( request . headers . get ( "user-agent" ) ?. startsWith ( "Deno/" ) ) {
126
138
return true ;
127
139
}
0 commit comments