Skip to content

Commit c567a06

Browse files
committed
Fix HTTPS redirects and TLS sockets
It still won't work behind a base path, but if you're using a reverse proxy you can just redirect to HTTPS yourself. And should probably handle TLS termination there too. For sockets I just needed to add back the proxy call.
1 parent e5b68a8 commit c567a06

1 file changed

Lines changed: 14 additions & 6 deletions

File tree

src/node/http.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { logger } from "@coder/logger"
1+
import { field, logger } from "@coder/logger"
22
import * as fs from "fs-extra"
33
import * as http from "http"
44
import * as httpolyglot from "httpolyglot"
@@ -13,6 +13,7 @@ import * as tls from "tls"
1313
import * as url from "url"
1414
import { HttpCode, HttpError } from "../common/http"
1515
import { normalize, plural, split } from "../common/util"
16+
import { SocketProxyProvider } from "./socket"
1617
import { getMediaMime, xdgLocalDir } from "./util"
1718

1819
export type Cookies = { [key: string]: string[] | undefined }
@@ -370,6 +371,7 @@ export class HttpServer {
370371
public readonly protocol: "http" | "https"
371372
private readonly providers = new Map<string, HttpProvider>()
372373
private readonly heart: Heart
374+
private readonly socketProvider = new SocketProxyProvider()
373375

374376
public constructor(private readonly options: HttpServerOptions) {
375377
this.heart = new Heart(path.join(xdgLocalDir, "heartbeat"), async () => {
@@ -392,6 +394,7 @@ export class HttpServer {
392394
}
393395

394396
public dispose(): void {
397+
this.socketProvider.stop()
395398
this.providers.forEach((p) => p.dispose())
396399
}
397400

@@ -510,6 +513,7 @@ export class HttpServer {
510513
if (error.code === "ENOENT" || error.code === "EISDIR") {
511514
e = new HttpError("Not found", HttpCode.NotFound)
512515
}
516+
logger.debug("Request error", field("url", request.url))
513517
logger.debug(error.stack)
514518
const code = typeof e.code === "number" ? e.code : HttpCode.ServerError
515519
const content = (await route.provider.getErrorRoot(route, code, code, e.message)).content
@@ -547,11 +551,13 @@ export class HttpServer {
547551
}
548552
})
549553

550-
return (
551-
(this.options.cert ? `${this.protocol}://${request.headers.host}` : "") +
554+
const secure = (request.connection as tls.TLSSocket).encrypted
555+
const redirect =
556+
(this.options.cert && !secure ? `${this.protocol}://${request.headers.host}/` : "") +
552557
normalize(`${route.provider.base(route)}/${payload.redirect}`, true) +
553558
(Object.keys(query).length > 0 ? `?${querystring.stringify(query)}` : "")
554-
)
559+
logger.debug("Redirecting", field("secure", !!secure), field("from", request.url), field("to", redirect))
560+
return redirect
555561
}
556562

557563
private onUpgrade = async (request: http.IncomingMessage, socket: net.Socket, head: Buffer): Promise<void> => {
@@ -572,7 +578,9 @@ export class HttpServer {
572578
throw new HttpError("Not found", HttpCode.NotFound)
573579
}
574580

575-
if (!(await route.provider.handleWebSocket(route, request, socket, head))) {
581+
if (
582+
!(await route.provider.handleWebSocket(route, request, await this.socketProvider.createProxy(socket), head))
583+
) {
576584
throw new HttpError("Not found", HttpCode.NotFound)
577585
}
578586
} catch (error) {
@@ -609,7 +617,7 @@ export class HttpServer {
609617

610618
const parsedUrl = request.url ? url.parse(request.url, true) : { query: {}, pathname: "" }
611619
const originalPath = parsedUrl.pathname || "/"
612-
const fullPath = normalize(originalPath)
620+
const fullPath = normalize(originalPath, true)
613621
const { base, requestPath } = parse(fullPath)
614622

615623
// Providers match on the path after their base so we need to account for

0 commit comments

Comments
 (0)