Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History
106 lines (94 loc) · 3.15 KB

File metadata and controls

106 lines (94 loc) · 3.15 KB
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
99
100
101
102
103
104
105
106
import { logger } from "@coder/logger"
import * as express from "express"
import * as http from "http"
import nodeFetch, { RequestInit, Response } from "node-fetch"
import Websocket from "ws"
import { Disposable } from "../../src/common/emitter"
import * as util from "../../src/common/util"
import { ensureAddress } from "../../src/node/app"
import { disposer } from "../../src/node/http"
import { handleUpgrade } from "../../src/node/wsRouter"
// Perhaps an abstraction similar to this should be used in app.ts as well.
export class HttpServer {
private hs: http.Server
public dispose: Disposable["dispose"]
/**
* Expects a server and a disposal that cleans up the server (and anything
* else that may need cleanup).
*
* Otherwise a new server is created.
*/
public constructor(server?: { server: http.Server; dispose: Disposable["dispose"] }) {
this.hs = server?.server || http.createServer()
this.dispose = server?.dispose || disposer(this.hs)
}
/**
* listen starts the server on a random localhost port.
* Use close to cleanup when done.
*/
public listen(fn: http.RequestListener): Promise<void> {
this.hs.on("request", fn)
return new Promise((resolve, reject) => {
this.hs.on("error", reject)
this.hs.listen(0, "127.0.0.1", () => {
this.hs.off("error", reject)
resolve()
this.hs.on("error", (err) => {
// Promise resolved earlier so this is some other error.
util.logError(logger, "http server error", err)
})
})
})
}
/**
* Send upgrade requests to an Express app.
*/
public listenUpgrade(app: express.Express): void {
handleUpgrade(app, this.hs)
}
/**
* fetch fetches the request path.
* The request path must be rooted!
*/
public fetch(requestPath: string, opts?: RequestInit, query?: { [key: string]: string }): Promise<Response> {
const address = ensureAddress(this.hs, "http")
if (typeof address === "string") {
throw new Error("Cannot fetch socket path")
}
address.pathname = requestPath
if (query) {
Object.keys(query).forEach((key) => {
address.searchParams.append(key, query[key])
})
}
return nodeFetch(address.toString(), opts)
}
/**
* Open a websocket against the request path.
*/
public ws(requestPath: string, options?: Websocket.ClientOptions): Websocket {
const address = ensureAddress(this.hs, "ws")
if (typeof address === "string") {
throw new Error("Cannot open websocket to socket path")
}
address.pathname = requestPath
return new Websocket(address.toString(), options)
}
/**
* Open a websocket and wait for it to fully open.
*/
public wsWait(requestPath: string, options?: Websocket.ClientOptions): Promise<Websocket> {
const ws = this.ws(requestPath, options)
return new Promise<Websocket>((resolve, reject) => {
ws.on("error", (err) => reject(err))
ws.on("open", () => resolve(ws))
})
}
public port(): number {
const addr = this.hs.address()
if (addr && typeof addr === "object") {
return addr.port
}
throw new Error("server not listening or listening on unix socket")
}
}
Morty Proxy This is a proxified and sanitized view of the page, visit original site.