Skip to content

Commit 5806932

Browse files
Refactor proxy code to pass strict-null checks
1 parent dc7ce83 commit 5806932

File tree

2 files changed

+64
-51
lines changed

2 files changed

+64
-51
lines changed

.changeset/loud-radios-bake.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
Refactor proxy code to pass strict-null checks

packages/wrangler/src/proxy.ts

+59-51
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { connect } from "node:http2";
2-
import type { ServerHttp2Stream } from "node:http2";
2+
import type { ClientHttp2Session, ServerHttp2Stream } from "node:http2";
33
import { createServer } from "node:http";
44
import type {
55
IncomingHttpHeaders,
@@ -64,32 +64,7 @@ export function usePreviewServer({
6464
}) {
6565
/** Creates an HTTP/1 proxy that sends requests over HTTP/2. */
6666
const proxyServer = useRef<Server>();
67-
if (!proxyServer.current) {
68-
proxyServer.current = createServer()
69-
.on("request", function (req, res) {
70-
// log all requests
71-
console.log(
72-
new Date().toLocaleTimeString(),
73-
req.method,
74-
req.url,
75-
res.statusCode
76-
);
77-
})
78-
.on("upgrade", (req) => {
79-
// log all websocket connections
80-
console.log(
81-
new Date().toLocaleTimeString(),
82-
req.method,
83-
req.url,
84-
101,
85-
"(WebSocket)"
86-
);
87-
})
88-
.on("error", (err) => {
89-
// log all connection errors
90-
console.error(new Date().toLocaleTimeString(), err);
91-
});
92-
}
67+
const proxy = (proxyServer.current ??= createProxyServer());
9368

9469
/**
9570
* When we're not connected / getting a fresh token on changes,
@@ -106,8 +81,6 @@ export function usePreviewServer({
10681
>([]);
10782

10883
useEffect(() => {
109-
const proxy = proxyServer.current;
110-
11184
// If we don't have a token, that means either we're just starting up,
11285
// or we're refreshing the token.
11386
if (!previewToken) {
@@ -147,23 +120,7 @@ export function usePreviewServer({
147120
cleanupListeners.push(() => remote.destroy());
148121

149122
/** HTTP/2 -> HTTP/2 */
150-
function handleStream(
151-
stream: ServerHttp2Stream,
152-
headers: IncomingHttpHeaders
153-
) {
154-
addCfPreviewTokenHeader(headers, previewToken.value);
155-
headers[":authority"] = previewToken.host;
156-
const request = stream.pipe(remote.request(headers));
157-
request.on("response", (responseHeaders: IncomingHttpHeaders) => {
158-
rewriteRemoteHostToLocalHostInHeaders(
159-
responseHeaders,
160-
previewToken.host,
161-
port
162-
);
163-
stream.respond(responseHeaders);
164-
request.pipe(stream, { end: true });
165-
});
166-
}
123+
const handleStream = createStreamHandler(previewToken, remote, port);
167124
proxy.on("stream", handleStream);
168125
cleanupListeners.push(() => proxy.off("stream", handleStream));
169126

@@ -194,7 +151,7 @@ export function usePreviewServer({
194151
}
195152
const request = message.pipe(remote.request(headers));
196153
request.on("response", (responseHeaders) => {
197-
const status = responseHeaders[":status"];
154+
const status = responseHeaders[":status"] ?? 500;
198155
rewriteRemoteHostToLocalHostInHeaders(
199156
responseHeaders,
200157
previewToken.host,
@@ -254,18 +211,18 @@ export function usePreviewServer({
254211
return () => {
255212
cleanupListeners.forEach((d) => d());
256213
};
257-
}, [previewToken, publicRoot, port]);
214+
}, [previewToken, publicRoot, port, proxy]);
258215

259216
// Start/stop the server whenever the
260217
// containing component is mounted/unmounted.
261218
useEffect(() => {
262-
proxyServer.current.listen(port);
219+
proxy.listen(port);
263220
console.log(`⬣ Listening at http://localhost:${port}`);
264221

265222
return () => {
266-
proxyServer.current.close();
223+
proxy.close();
267224
};
268-
}, [port]);
225+
}, [port, proxy]);
269226
}
270227

271228
function createHandleAssetsRequest(
@@ -292,3 +249,54 @@ const HTTP1_HEADERS = new Set([
292249
"transfer-encoding",
293250
"http2-settings",
294251
]);
252+
253+
function createProxyServer() {
254+
return createServer()
255+
.on("request", function (req, res) {
256+
// log all requests
257+
console.log(
258+
new Date().toLocaleTimeString(),
259+
req.method,
260+
req.url,
261+
res.statusCode
262+
);
263+
})
264+
.on("upgrade", (req) => {
265+
// log all websocket connections
266+
console.log(
267+
new Date().toLocaleTimeString(),
268+
req.method,
269+
req.url,
270+
101,
271+
"(WebSocket)"
272+
);
273+
})
274+
.on("error", (err) => {
275+
// log all connection errors
276+
console.error(new Date().toLocaleTimeString(), err);
277+
});
278+
}
279+
280+
function createStreamHandler(
281+
previewToken: CfPreviewToken,
282+
remote: ClientHttp2Session,
283+
port: number
284+
) {
285+
return function handleStream(
286+
stream: ServerHttp2Stream,
287+
headers: IncomingHttpHeaders
288+
) {
289+
addCfPreviewTokenHeader(headers, previewToken.value);
290+
headers[":authority"] = previewToken.host;
291+
const request = stream.pipe(remote.request(headers));
292+
request.on("response", (responseHeaders: IncomingHttpHeaders) => {
293+
rewriteRemoteHostToLocalHostInHeaders(
294+
responseHeaders,
295+
previewToken.host,
296+
port
297+
);
298+
stream.respond(responseHeaders);
299+
request.pipe(stream, { end: true });
300+
});
301+
};
302+
}

0 commit comments

Comments
 (0)