@@ -85,6 +85,40 @@ export class Server {
85
85
}
86
86
87
87
const resp = new APIResponse ( )
88
+ const end = async ( status ?: number ) : Promise < void > => {
89
+ let { body, headers, } = resp
90
+ let contentType : string | null = null
91
+ if ( headers . has ( 'Content-Type' ) ) {
92
+ contentType = headers . get ( 'Content-Type' ) !
93
+ } else if ( typeof body === 'string' ) {
94
+ contentType = 'text/plain; charset=utf-8'
95
+ headers . set ( 'Content-Type' , contentType )
96
+ }
97
+
98
+ const acceptEncoding = req . headers . get ( 'accept-encoding' )
99
+ if ( acceptEncoding && body && contentType ) {
100
+ let data = new Uint8Array ( )
101
+ if ( typeof body === 'string' ) {
102
+ data = new TextEncoder ( ) . encode ( body )
103
+ } else if ( body instanceof Uint8Array ) {
104
+ data = body
105
+ } else if ( body instanceof ArrayBuffer ) {
106
+ data = new Uint8Array ( body )
107
+ }
108
+ const contentEncoding = compress . accept ( acceptEncoding , contentType , data . length )
109
+ if ( contentEncoding ) {
110
+ body = await compress . compress ( data , contentEncoding )
111
+ headers . set ( 'Vary' , 'Origin' )
112
+ headers . set ( 'Content-Encoding' , contentEncoding )
113
+ }
114
+ }
115
+
116
+ try {
117
+ await respondWith ( new Response ( body , { headers, status : status || resp . status } ) )
118
+ } catch ( err ) {
119
+ log . warn ( 'http:' , err . message )
120
+ }
121
+ }
88
122
89
123
// set server header
90
124
resp . setHeader ( 'Server' , 'Aleph.js' )
@@ -107,9 +141,11 @@ export class Server {
107
141
const [ path , search ] = util . splitBy ( util . atobUrl ( util . trimSuffix ( util . trimPrefix ( pathname , '/_aleph/data/' ) , '.json' ) ) , '?' )
108
142
const data = await aleph . getSSRData ( { pathname : path , search : search ? '?' + search : undefined } )
109
143
if ( data === null ) {
110
- resp . json ( null ) . writeTo ( e )
144
+ resp . json ( null )
145
+ end ( )
111
146
} else {
112
- resp . json ( data ) . writeTo ( e )
147
+ resp . json ( data )
148
+ end ( )
113
149
}
114
150
return
115
151
}
@@ -118,7 +154,7 @@ export class Server {
118
154
if ( relPath == '/main.js' ) {
119
155
resp . body = await aleph . createMainJS ( false )
120
156
resp . setHeader ( 'Content-Type' , 'application/javascript; charset=utf-8' )
121
- resp . writeTo ( e )
157
+ end ( )
122
158
return
123
159
}
124
160
@@ -139,14 +175,14 @@ export class Server {
139
175
if ( content ) {
140
176
const hash = aleph . gteModuleHash ( module )
141
177
if ( hash === req . headers . get ( 'If-None-Match' ) ) {
142
- resp . writeTo ( e , 304 )
178
+ end ( 304 )
143
179
return
144
180
}
145
181
146
182
resp . setHeader ( 'ETag' , hash )
147
183
resp . setHeader ( 'Content-Type' , 'application/javascript; charset=utf-8' )
148
184
resp . body = content
149
- resp . writeTo ( e )
185
+ end ( )
150
186
return
151
187
}
152
188
}
@@ -158,19 +194,19 @@ export class Server {
158
194
const info = Deno . lstatSync ( filePath )
159
195
const lastModified = info . mtime ?. toUTCString ( ) ?? ( new Date ) . toUTCString ( )
160
196
if ( lastModified === req . headers . get ( 'If-Modified-Since' ) ) {
161
- resp . writeTo ( e , 304 )
197
+ end ( 304 )
162
198
return
163
199
}
164
200
165
201
resp . body = await Deno . readFile ( filePath )
166
202
resp . setHeader ( 'Last-Modified' , lastModified )
167
203
resp . setHeader ( 'Content-Type' , getContentType ( filePath ) )
168
- resp . writeTo ( e )
204
+ end ( )
169
205
return
170
206
}
171
207
172
208
resp . body = 'file not found'
173
- resp . writeTo ( e , 404 )
209
+ end ( 404 )
174
210
return
175
211
}
176
212
@@ -180,14 +216,14 @@ export class Server {
180
216
const info = Deno . lstatSync ( filePath )
181
217
const lastModified = info . mtime ?. toUTCString ( ) ?? ( new Date ) . toUTCString ( )
182
218
if ( lastModified === req . headers . get ( 'If-Modified-Since' ) ) {
183
- resp . writeTo ( e , 304 )
219
+ end ( 304 )
184
220
return
185
221
}
186
222
187
223
resp . body = await Deno . readFile ( filePath )
188
224
resp . setHeader ( 'Last-Modified' , lastModified )
189
225
resp . setHeader ( 'Content-Type' , getContentType ( filePath ) )
190
- resp . writeTo ( e )
226
+ end ( )
191
227
return
192
228
}
193
229
@@ -207,7 +243,8 @@ export class Server {
207
243
if ( util . isFunction ( h ) ) {
208
244
await h ( context )
209
245
} else {
210
- await resp . json ( { status : 500 , message : 'bad api handler' } ) . writeTo ( e , 500 )
246
+ resp . json ( { status : 500 , message : 'bad api handler' } )
247
+ end ( 500 )
211
248
}
212
249
} ]
213
250
let pointer = 0
@@ -246,14 +283,16 @@ export class Server {
246
283
}
247
284
await next ( )
248
285
if ( ! responded ) {
249
- resp . writeTo ( e )
286
+ end ( )
250
287
}
251
288
} catch ( err ) {
252
- resp . json ( { status : 500 , message : err . message } ) . writeTo ( e , 500 )
289
+ resp . json ( { status : 500 , message : err . message } )
290
+ end ( 500 )
253
291
log . error ( 'invoke API:' , err )
254
292
}
255
293
} else {
256
- resp . json ( { status : 404 , message : 'not found' } ) . writeTo ( e , 404 )
294
+ resp . json ( { status : 404 , message : 'not found' } )
295
+ end ( 404 )
257
296
}
258
297
return
259
298
}
@@ -265,7 +304,7 @@ export class Server {
265
304
} )
266
305
resp . body = html
267
306
resp . setHeader ( 'Content-Type' , 'text/html; charset=utf-8' )
268
- resp . writeTo ( e , status )
307
+ end ( status )
269
308
} catch ( err ) {
270
309
try {
271
310
// todo: custom error page
0 commit comments