Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/next/lib/share/virtual-hosts.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6Support for virtual hosts.7*/89import type { Request, Response } from "express";1011import basePath from "@cocalc/backend/base-path";12import { getLogger } from "@cocalc/backend/logger";13import isAuthenticated from "./authenticate";14import getVirtualHostInfo from "./get-vhost-info";15import { staticHandler } from "./handle-raw";16import pathToFiles from "./path-to-files";1718const logger = getLogger("virtual-hosts");1920export default function virtualHostsMiddleware() {21// we return the middleware to match the standard pattern for express,22// and give more flexibility.23return async function (24req: Request,25res: Response,26next: Function,27): Promise<void> {28// For debugging in cc-in-cc dev, just manually set host to something29// else and comment this out. That's the only way, since dev is otherwise30// impossible because otherwise the haproxy server sends queries31// all straight to the production share server!32const vhost: string | undefined = req.headers.host?.toLowerCase();33// const vhost = "vertramp.org";34// const vhost = "python-wasm.org";35if (vhost == null) {36// logger.debug("no host header set");37next();38return;39}40logger.debug("checking for vhost", vhost);4142const info = await getVirtualHostInfo(vhost);43if (info == null) {44// logger.debug("no vhost info for ", vhost);45next();46return;47}4849let path = req.url;50if (basePath && basePath != "/") {51// This is only going to happen in case of doing52// cc-in-cc development.53path = req.url.slice(basePath.length);54}55if (path == "") {56path = "/";57}5859// logger.debug({ vhost, url: req.url, info, path });6061const isAuth: boolean = isAuthenticated({62req,63res,64path,65auth: info.auth,66});6768if (!isAuth) {69logger.debug(70"not authenticated -- denying vhost='%s', path='%s'",71vhost,72path,73);74res.status(403).end();75return;76}7778if (info.cross_origin_isolation) {79// The following two headers make it possible to serve content that used80// SharedArrayBuffer from vhosts and raw shared content. This is very81// important as it is a prerequisite for modern use of WebAssembly.82// E.g., https://python-wasm.cocalc.com uses this.83res.setHeader("Cross-origin-Embedder-Policy", "require-corp");84res.setHeader("Cross-origin-Opener-Policy", "same-origin");85}8687const dir = pathToFiles(info.project_id, info.path);88/* logger.debug(89"serving virtual host path -- vhost='%s',dir='%s'",90vhost,91dir92); */93req.url = path;94staticHandler(dir, req, res, () => {95res.status(404).end();96});97};98}99100101