Skip to content

Commit

Permalink
BootProbes: add a websocket probe
Browse files Browse the repository at this point in the history
This self-test isn't perfect because we're running it from the backend
instead of the frontend. Conceivably the backend might have trouble
resolving its own url. Eventually we should move this test or
something like it to something that executes in the frontend.
  • Loading branch information
jordigh committed May 9, 2024
1 parent f0c11c5 commit 556a197
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
10 changes: 10 additions & 0 deletions app/client/models/AdminChecks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,16 @@ It is good practice not to run Grist as the root user.
'reachable': {
info: `
The main page of Grist should be available.
`
},

'websockets': {
info: `
Websocket connections need HTTP 1.1 and the ability to pass a few
extra headers in order to work. Sometimes a reverse proxy can
interfere with these requirements. See <a
href="https://support.getgrist.com/self-managed/#how-do-i-run-grist-on-a-server">this
documentation</a> for more explanation.
`
},
};
Expand Down
3 changes: 2 additions & 1 deletion app/common/BootProbe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ export type BootProbeIds =
'reachable' |
'host-header' |
'sandboxing' |
'system-user'
'system-user' |
'websockets'
;

export interface BootProbeResult {
Expand Down
33 changes: 33 additions & 0 deletions app/server/lib/BootProbes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { removeTrailingSlash } from 'app/common/gutil';
import { expressWrap, jsonErrorHandler } from 'app/server/lib/expressWrap';
import { GristServer } from 'app/server/lib/GristServer';
import * as express from 'express';
import WS from 'ws';
import fetch from 'node-fetch';

/**
Expand Down Expand Up @@ -58,6 +59,7 @@ export class BootProbes {
this._probes.push(_bootProbe);
this._probes.push(_hostHeaderProbe);
this._probes.push(_sandboxingProbe);
this._probes.push(_webSocketsProbe);
this._probeById = new Map(this._probes.map(p => [p.id, p]));
}
}
Expand Down Expand Up @@ -104,6 +106,37 @@ const _homeUrlReachableProbe: Probe = {
}
};

const _webSocketsProbe: Probe = {
id: 'websockets',
name: 'Can we open a websocket with the server',
apply: async (server, req) => {
return new Promise((resolve) => {
const url = new URL(server.getHomeUrl(req));
url.protocol = (url.protocol === 'https:') ? 'wss:' : 'ws:';
const ws = new WS.WebSocket(url.href);
const details: Record<string, any> = {
url,
};
ws.on('open', () => {
ws.send('Just nod if you can hear me.');
resolve({
success: true,
details,
});
ws.close();
});
ws.on('error', (ev) => {
details.error = ev.message;
resolve({
success: false,
details,
});
ws.close();
});
});
}
};

const _statusCheckProbe: Probe = {
id: 'health-check',
name: 'Is an internal health check passing',
Expand Down

0 comments on commit 556a197

Please sign in to comment.