Skip to content

Commit d9127b5

Browse files
fix: start server when rest_api is enabled and gate static file servi… (#801)
* fix: start server when rest_api is enabled and gate static file serving behind serve flag * Rename WebServer serve flag, restore rate-limit ordering, log startup mode - IWebServerConfig.serve -> IWebServerConfig.serveStatic. The field only toggles static file serving / the homepage route; the WebServer's HTTP listener is always started when the instance is constructed. The previous name read like it gated server startup, which was confusing for a public API. No external consumers depended on the old name yet. - Register the rate limiter before the static / homepage handlers so the homepage route and any later-registered routes are all rate-limited. The earlier patch moved static+homepage ahead of the limiter, which silently removed rate-limiting from the homepage route. - Log at startup which mode Wilbur is running in so operators can tell REST-only installs from full ones at a glance. - Fold serveStatic into the IWebServerConfig object literal instead of setting it after construction. * Add changeset for REST API startup fix --------- Co-authored-by: Matthew.Cotton <matt@tensorworks.com.au>
1 parent 60da95c commit d9127b5

3 files changed

Lines changed: 45 additions & 20 deletions

File tree

.changeset/silent-lemons-shine.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@epicgames-ps/wilbur": patch
3+
"@epicgames-ps/lib-pixelstreamingsignalling-ue5.7": minor
4+
---
5+
6+
Make the REST API reachable when Wilbur is started with `--rest_api` but without `--serve`. Previously the Express app that hosts the `/api/*` routes was only bound to an HTTP listener inside the `serve` branch, so with `--serve=false --rest_api=true` the listener never started and requests were answered by the WebSocket upgrade handler on the player port (`426 Upgrade Required`). The HTTP listener now starts whenever `rest_api` or `serve` is set. Static file serving and the homepage route are gated by a new `IWebServerConfig.serveStatic` flag (the port listener runs independently of static serving), and the rate limiter is registered before any route handlers so the homepage and any downstream-registered routes are all rate-limited. Wilbur logs at startup which mode it is running in.

Signalling/src/WebServer.ts

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ export interface IWebServerConfig {
3939

4040
// If true, connections to http will be redirected to https.
4141
https_redirect?: boolean;
42+
43+
// If true, serve static content from `root` and a homepage handler at `/`.
44+
// Defaults to false. When false, the HTTP listener still runs (so routes
45+
// registered by other subsystems, such as a REST API, remain reachable),
46+
// but no static files are served.
47+
serveStatic?: boolean;
4248
}
4349

4450
/**
@@ -111,32 +117,36 @@ export class WebServer {
111117
}
112118
}
113119

114-
app.use(express.static(config.root));
115-
116120
const limiter = RateLimit({
117121
windowMs: 60 * 1000, // 1 minute
118122
max: config.perMinuteRateLimit ? config.perMinuteRateLimit : 3000
119123
});
120124

121-
// apply rate limiter to all requests
125+
// apply rate limiter to all requests. Registered before any route
126+
// handler so that static files, the homepage route, and any routes
127+
// registered on `app` by downstream code are all subject to it.
122128
app.use(limiter);
123129

124-
// Request has been sent to site root, send the homepage file
125-
app.get('/', function (req: any, res: any) {
126-
// Try a few paths, see if any resolve to a homepage file the user has set
127-
const p = path.resolve(path.join(config.root, config.homepageFile));
128-
if (fs.existsSync(p)) {
129-
// Send the file for browser to display it
130-
res.sendFile(p);
130+
if (config.serveStatic) {
131+
app.use(express.static(config.root));
132+
133+
// Request has been sent to site root, send the homepage file
134+
app.get('/', function (req: any, res: any) {
135+
// Try a few paths, see if any resolve to a homepage file the user has set
136+
const p = path.resolve(path.join(config.root, config.homepageFile));
137+
if (fs.existsSync(p)) {
138+
// Send the file for browser to display it
139+
res.sendFile(p);
140+
return;
141+
}
142+
143+
// Catch file doesn't exist, and send back 404 if not
144+
const error = 'Unable to locate file ' + config.homepageFile;
145+
Logger.error(error);
146+
res.status(404).send(error);
131147
return;
132-
}
133-
134-
// Catch file doesn't exist, and send back 404 if not
135-
const error = 'Unable to locate file ' + config.homepageFile;
136-
Logger.error(error);
137-
res.status(404).send(error);
138-
return;
139-
});
148+
});
149+
}
140150

141151
/* eslint-enable @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access */
142152
}

SignallingWebServer/src/index.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,21 @@ const serverOpts: IServerConfig = {
248248
maxSubscribers: options.max_players
249249
};
250250

251-
if (options.serve) {
251+
const shouldServerStart = options.serve || options.rest_api;
252+
if (shouldServerStart) {
252253
const webserverOptions: IWebServerConfig = {
253254
httpPort: options.player_port,
254255
root: options.http_root,
255-
homepageFile: options.homepage
256+
homepageFile: options.homepage,
257+
serveStatic: options.serve
256258
};
259+
260+
if (options.serve) {
261+
Logger.info('Static file serving enabled.');
262+
} else if (options.rest_api) {
263+
Logger.info('REST API enabled; static file serving disabled.');
264+
}
265+
257266
if (options.https) {
258267
webserverOptions.httpsPort = options.https_port;
259268
const sslKeyPath = path.join(__dirname, '..', options.ssl_key_path);

0 commit comments

Comments
 (0)