Archived
1
0

Improve routing

This commit is contained in:
Asher
2020-02-04 18:16:45 -06:00
parent dbc5c065f8
commit 8cc11d1688
26 changed files with 289 additions and 267 deletions

View File

@ -151,6 +151,7 @@ export class ApiHttpProvider extends HttpProvider {
{
name: "VS Code",
path: "/vscode",
embedPath: "/vscode-embed",
},
],
},

View File

@ -1,33 +1,49 @@
import { logger } from "@coder/logger"
import * as http from "http"
import * as querystring from "querystring"
import * as React from "react"
import * as ReactDOMServer from "react-dom/server"
import * as ReactRouterDOM from "react-router-dom"
import App from "../../browser/app"
import { Options } from "../../common/util"
import { HttpProvider, HttpResponse } from "../http"
/**
* Top-level and fallback HTTP provider.
*/
export class MainHttpProvider extends HttpProvider {
public async handleRequest(base: string, requestPath: string): Promise<HttpResponse | undefined> {
public async handleRequest(
base: string,
requestPath: string,
_query: querystring.ParsedUrlQuery,
request: http.IncomingMessage
): Promise<HttpResponse | undefined> {
if (base === "/static") {
const response = await this.getResource(this.rootPath, requestPath)
response.cache = true
if (this.options.commit && this.options.commit !== "development") {
response.cache = true
}
return response
}
// TEMP: Auto-load VS Code for now. In future versions we'll need to check
// the URL for the appropriate application to load, if any.
const app = {
name: "VS Code",
path: "/",
embedPath: "/vscode-embed",
}
const options: Options = {
app,
authed: !!this.authenticated(request),
logLevel: logger.level,
}
const response = await this.getUtf8Resource(this.rootPath, "src/browser/index.html")
response.content = response.content
.replace(/{{COMMIT}}/g, "") // TODO
.replace(/"{{OPTIONS}}"/g, `'${JSON.stringify({ logLevel: logger.level })}'`)
.replace(
/{{COMPONENT}}/g,
ReactDOMServer.renderToString(
<ReactRouterDOM.StaticRouter location={base}>
<App />
</ReactRouterDOM.StaticRouter>
)
)
.replace(/{{COMMIT}}/g, this.options.commit || "development")
.replace(/"{{OPTIONS}}"/g, `'${JSON.stringify(options)}'`)
.replace(/{{COMPONENT}}/g, ReactDOMServer.renderToString(<App options={options} />))
return response
}

View File

@ -23,25 +23,32 @@ const main = async (args: Args = {}): Promise<void> => {
const auth = args.auth || AuthType.Password
const originalPassword = auth === AuthType.Password && (process.env.PASSWORD || (await generatePassword()))
let commit = "development"
try {
commit = require("../../package.json").commit
} catch (error) {
logger.warn(error.message)
}
// Spawn the main HTTP server.
const options = {
auth,
basePath: args["base-path"],
cert: args.cert,
certKey: args["cert-key"],
commit,
host: args.host || (args.auth === AuthType.Password && typeof args.cert !== "undefined" ? "0.0.0.0" : "localhost"),
password: originalPassword ? hash(originalPassword) : undefined,
port: typeof args.port !== "undefined" ? parseInt(args.port, 10) : 8080,
socket: args.socket,
auth,
password: originalPassword ? hash(originalPassword) : undefined,
}
if (!options.cert && typeof options.cert !== "undefined") {
const { cert, certKey } = await generateCertificate()
options.cert = cert
options.certKey = certKey
}
const httpServer = new HttpServer(options)
// Register all the providers.
const httpServer = new HttpServer(options)
httpServer.registerHttpProvider("/", MainHttpProvider)
httpServer.registerHttpProvider("/api", ApiHttpProvider, httpServer)
httpServer.registerHttpProvider("/vscode-embed", VscodeHttpProvider, [])

View File

@ -12,8 +12,8 @@ import * as tarFs from "tar-fs"
import * as tls from "tls"
import * as url from "url"
import { HttpCode, HttpError } from "../common/http"
import { plural, split } from "../common/util"
import { getMediaMime, normalize, xdgLocalDir } from "./util"
import { normalize, plural, split } from "../common/util"
import { getMediaMime, xdgLocalDir } from "./util"
export type Cookies = { [key: string]: string[] | undefined }
export type PostData = { [key: string]: string | string[] | undefined }
@ -92,6 +92,7 @@ export interface HttpServerOptions {
readonly basePath?: string
readonly cert?: string
readonly certKey?: string
readonly commit?: string
readonly host?: string
readonly password?: string
readonly port?: number
@ -111,6 +112,7 @@ export interface HttpProviderOptions {
readonly base: string
readonly auth: AuthType
readonly password?: string
readonly commit?: string
}
/**
@ -120,7 +122,7 @@ export interface HttpProviderOptions {
export abstract class HttpProvider {
protected readonly rootPath = path.resolve(__dirname, "../..")
public constructor(private readonly options: HttpProviderOptions) {}
public constructor(protected readonly options: HttpProviderOptions) {}
public dispose(): void {
// No default behavior.
@ -403,6 +405,7 @@ export class HttpServer {
{
auth: this.options.auth || AuthType.None,
base: endpoint,
commit: this.options.commit,
password: this.options.password,
},
a1

View File

@ -207,10 +207,3 @@ export function extend(...args: any[]): any {
}
return c
}
/**
* Remove extra and trailing slashes in a URL.
*/
export const normalize = (url: string): string => {
return url.replace(/\/\/+/g, "/").replace(/\/+$/, "")
}