11import express from 'express' ;
22import { createServer } from 'node:http' ;
3- import Ultraviolet from '@titaniumnetwork-dev/ultraviolet' ;
4- import { uvPath } from '@titaniumnetwork-dev/ultraviolet/dist' ;
5- import { join } from 'path' ;
6- import { hostname } from 'os' ;
3+ import { publicPath } from 'ultraviolet-static' ;
4+ import { uvPath } from '@titaniumnetwork-dev/ultraviolet' ;
5+ import { epoxyPath } from '@mercuryworkshop/epoxy-transport' ;
6+ import { baremuxPath } from '@mercuryworkshop/bare-mux/node' ;
7+ import { join } from 'node:path' ;
8+ import { hostname } from 'node:os' ;
9+ import wisp from 'wisp-server-node' ;
710
811const app = express ( ) ;
9- const httpServer = createServer ( app ) ;
10- const port = process . env . PORT || 8080 ;
11-
12- // Serve static Ultraviolet files
12+ // Load our publicPath first and prioritize it over UV.
13+ app . use ( express . static ( publicPath ) ) ;
14+ // Load vendor files last.
15+ // The vendor's uv.config.js won't conflict with our uv.config.js inside the publicPath directory.
1316app . use ( '/uv/' , express . static ( uvPath ) ) ;
17+ app . use ( '/epoxy/' , express . static ( epoxyPath ) ) ;
18+ app . use ( '/baremux/' , express . static ( baremuxPath ) ) ;
19+
20+ // Error for everything else
21+ app . use ( ( req , res ) => {
22+ res . status ( 404 ) ;
23+ res . sendFile ( join ( publicPath , '404.html' ) ) ;
24+ } ) ;
1425
15- // Serve your static frontend files
16- app . use ( express . static ( 'public' ) ) ;
26+ const server = createServer ( ) ;
1727
18- const uv = new Ultraviolet ( {
19- prefix : '/service/' ,
20- bare : '/bare/' ,
21- encodeUrl : Ultraviolet . codec . xor . encode ,
22- decodeUrl : Ultraviolet . codec . xor . decode ,
28+ server . on ( 'request' , ( req , res ) => {
29+ res . setHeader ( 'Cross-Origin-Opener-Policy' , 'same-origin' ) ;
30+ res . setHeader ( 'Cross-Origin-Embedder-Policy' , 'require-corp' ) ;
31+ app ( req , res ) ;
32+ } ) ;
33+ server . on ( 'upgrade' , ( req , socket , head ) => {
34+ if ( req . url . endsWith ( '/wisp/' ) )
35+ wisp . routeRequest ( req , socket , head ) ;
36+ else
37+ socket . end ( ) ;
2338} ) ;
2439
25- // Generate proxied URL
26- app . get ( '/generate-proxy-url' , ( req , res ) => {
27- const serviceUrl = req . query . url ;
28- if ( serviceUrl ) {
29- const encodedUrl = uv . encodeUrl ( serviceUrl ) ;
30- const proxyUrl = `http://${ hostname ( ) } :${ port } /service/${ encodedUrl } ` ;
31- res . send ( proxyUrl ) ;
32- } else {
33- res . status ( 400 ) . send ( 'No URL provided' ) ;
34- }
40+ let port = parseInt ( process . env . PORT || '' ) ;
41+
42+ if ( isNaN ( port ) ) port = 8080 ;
43+
44+ server . on ( 'listening' , ( ) => {
45+ const address = server . address ( ) ;
46+
47+ // by default we are listening on 0.0.0.0 (every interface)
48+ // we just need to list a few
49+ console . log ( 'Listening on:' ) ;
50+ console . log ( `\thttp://localhost:${ address . port } ` ) ;
51+ console . log ( `\thttp://${ hostname ( ) } :${ address . port } ` ) ;
52+ console . log (
53+ `\thttp://${ address . family === 'IPv6' ? `[${ address . address } ]` : address . address
54+ } :${ address . port } `
55+ ) ;
3556} ) ;
3657
37- app . use ( '/service/' , uv . middleware ( ) ) ;
58+ // https://expressjs.com/en/advanced/healthcheck-graceful-shutdown.html
59+ process . on ( 'SIGINT' , shutdown ) ;
60+ process . on ( 'SIGTERM' , shutdown ) ;
61+
62+ function shutdown ( ) {
63+ console . log ( 'SIGTERM signal received: closing HTTP server' ) ;
64+ server . close ( ) ;
65+ process . exit ( 0 ) ;
66+ }
3867
39- httpServer . listen ( port , ( ) => {
40- console . log ( `Ultraviolet Proxy is running on http:// ${ hostname ( ) } : ${ port } ` ) ;
68+ server . listen ( {
69+ port,
4170} ) ;
0 commit comments