-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
98 lines (81 loc) · 2.51 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import app from "../app.js"
async function writeReadableStreamToWritable(stream, writable) {
let reader = stream.getReader()
async function read() {
let { done, value } = await reader.read()
if (done) {
writable.end()
return
}
writable.write(value)
await read()
}
try {
await read()
} catch (error) {
writable.destroy(error)
throw error
}
}
class NodeResponse extends Response {
get headers() {
return super.headers
}
clone() {
return super.clone()
}
}
const getRequestListener = (fetchCallback) => {
return async (incoming, outgoing) => {
const method = incoming.method || 'GET'
const url = `http://${incoming.headers.host}${incoming.url}`
const headerRecord = {}
const len = incoming.rawHeaders.length
for (let i = 0; i < len; i++) {
if (i % 2 === 0) {
const key = incoming.rawHeaders[i]
headerRecord[key] = incoming.rawHeaders[i + 1]
}
}
const init = {
method: method,
headers: headerRecord,
}
if (!(method === 'GET' || method === 'HEAD')) {
const buffers = []
for await (const chunk of incoming) {
buffers.push(chunk)
}
const buffer = Buffer.concat(buffers)
init['body'] = buffer
}
let res
try {
res = (await fetchCallback(new Request(url.toString(), init)))
} catch {
res = new NodeResponse(null, { status: 500 })
}
const contentType = res.headers.get('content-type') || ''
const contentEncoding = res.headers.get('content-encoding')
for (const [k, v] of res.headers) {
if (k === 'set-cookie') {
outgoing.setHeader(k, res.headers.getAll(k))
} else {
outgoing.setHeader(k, v)
}
}
outgoing.statusCode = res.status
if (res.body) {
if (!contentEncoding && contentType.startsWith('text')) {
outgoing.end(await res.text())
} else if (!contentEncoding && contentType.startsWith('application/json')) {
outgoing.end(await res.text())
} else {
await writeReadableStreamToWritable(res.body, outgoing)
}
} else {
outgoing.end()
}
}
}
export default getRequestListener(app.fetch)