1- import { logger } from "@coder/logger"
1+ import { field , logger } from "@coder/logger"
22import * as fs from "fs-extra"
33import * as http from "http"
44import * as httpolyglot from "httpolyglot"
@@ -13,6 +13,7 @@ import * as tls from "tls"
1313import * as url from "url"
1414import { HttpCode , HttpError } from "../common/http"
1515import { normalize , plural , split } from "../common/util"
16+ import { SocketProxyProvider } from "./socket"
1617import { getMediaMime , xdgLocalDir } from "./util"
1718
1819export 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