-
Notifications
You must be signed in to change notification settings - Fork 876
/
protocol.ts
80 lines (66 loc) · 1.91 KB
/
protocol.ts
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
import { protocol, session, ProtocolRequest, UploadData } from 'electron'
import { IncomingMessage, ServerResponse } from 'http'
import { Readable, Transform } from 'stream'
import { APP_NAME } from './constant'
protocol.registerSchemesAsPrivileged([{
scheme: APP_NAME,
privileges: {
supportFetchAPI: true,
standard: true,
secure: true,
allowServiceWorkers: true,
bypassCSP: true,
corsEnabled: true,
}
}])
async function transformBody (data?: UploadData[]): Promise<Buffer | null> {
if (!data) {
return null
}
let body = Buffer.from([])
for (const payload of data) {
if (payload.bytes) {
body = Buffer.concat([body, payload.bytes])
} else if (payload.blobUUID) {
const file = await session.defaultSession.getBlobData(payload.blobUUID)
body = Buffer.concat([body, file])
}
}
return body
}
export async function transformProtocolRequest (request: ProtocolRequest) {
const req = new IncomingMessage(null as any)
req.method = request.method
req.url = request.url.replace(APP_NAME, 'http')
Object.keys(request.headers).forEach(key => {
req.headers[key.toLowerCase()] = request.headers[key]
})
const body = await transformBody(request.uploadData)
if (body) {
req.headers['content-length'] = body.length.toString()
req._read = Readable.from(body)._read
} else {
req._read = () => req.push(null)
}
const out = new Transform({
transform (chunk, encoding, cb) {
this.push(chunk, encoding)
cb()
},
})
const res = new Proxy(new ServerResponse(req), {
get (target, prop: keyof typeof out) {
const val = out[prop]
if (val && typeof val === 'function') {
return val.bind(out)
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return target[prop]
},
})
res.on('close', () => {
res.emit('finish')
})
return { req, res, out }
}