Decrease redundancy by changing the way the websocket fallback is included; Adding new env var SIGNALING_SERVER to host client files but use another server for signaling.

This commit is contained in:
schlagmichdoch 2023-11-08 20:31:57 +01:00
parent cb72edef20
commit 3439e7f6d4
62 changed files with 439 additions and 10101 deletions

View file

@ -46,18 +46,9 @@ conf.rtcConfig = process.env.RTC_CONFIG
]
};
let ipv6Localize = parseInt(process.env.IPV6_LOCALIZE) || false;
if (ipv6Localize) {
if (!(0 < ipv6Localize && ipv6Localize < 8)) {
console.error("ipv6Localize must be an integer between 1 and 7");
process.exit(1);
}
console.log("IPv6 client IPs will be localized to",
ipv6Localize,
ipv6Localize === 1 ? "segment" : "segments");
}
conf.ipv6Localize = ipv6Localize;
conf.signalingServer = process.env.SIGNALING_SERVER || false;
conf.ipv6Localize = parseInt(process.env.IPV6_LOCALIZE) || false;
let rateLimit = false;
if (process.argv.includes('--rate-limit') || process.env.RATE_LIMIT === "true") {
@ -75,6 +66,40 @@ conf.rateLimit = rateLimit;
conf.autoStart = process.argv.includes('--auto-restart');
conf.localhostOnly = process.argv.includes('--localhost-only');
// Validate configuration
if (conf.ipv6Localize) {
if (!(0 < conf.ipv6Localize && conf.ipv6Localize < 8)) {
console.error("ipv6Localize must be an integer between 1 and 7");
process.exit(1);
}
console.log("IPv6 client IPs will be localized to",
conf.ipv6Localize,
conf.ipv6Localize === 1 ? "segment" : "segments");
}
if (conf.signalingServer) {
const isValidUrl = /[a-z|0-9|\-._~:\/?#\[\]@!$&'()*+,;=]+$/.test(conf.signalingServer);
const containsProtocol = /:\/\//.test(conf.signalingServer)
const endsWithSlash = /\/$/.test(conf.signalingServer)
if (!isValidUrl || containsProtocol) {
console.error("SIGNALING_SERVER must be a valid url without the protocol prefix.\n" +
"Examples of valid values: `pairdrop.net`, `pairdrop.example.com:3000`, `example.com/pairdrop`");
process.exit(1);
}
if (!endsWithSlash) {
conf.signalingServer += "/";
}
if (process.env.RTC_CONFIG || conf.wsFallback || conf.ipv6Localize) {
console.error("SIGNALING_SERVER cannot be used alongside WS_FALLBACK, RTC_CONFIG or IPV6_LOCALIZE as these " +
"configurations are specified by the signaling server.\n" +
"To use this instance as the signaling server do not set SIGNALING_SERVER");
process.exit(1);
}
}
// Logs for debugging
if (conf.debugMode) {
console.log("DEBUG_MODE is active. To protect privacy, do not use in production.");
@ -109,6 +134,11 @@ if (conf.autoStart) {
// Start server to serve client files
const pairDropServer = new PairDropServer(conf);
// Start websocket Server
const pairDropWsServer = new PairDropWsServer(pairDropServer.server, conf);
if (!conf.signalingServer) {
// Start websocket server if SIGNALING_SERVER is not set
new PairDropWsServer(pairDropServer.server, conf);
} else {
console.log("This instance does not include a signaling server. Clients on this instance connect to the following signaling server:", conf.signalingServer);
}
console.log('\nPairDrop is running on port', conf.port);

View file

@ -17,8 +17,8 @@ export default class Peer {
// set peer id
this._setPeerId(request);
// is WebRTC supported ?
this.rtcSupported = request.url.indexOf('webrtc') > -1;
// is WebRTC supported
this._setRtcSupported(request);
// set name
this._setName(request);
@ -133,6 +133,11 @@ export default class Peer {
}
}
_setRtcSupported(request) {
const searchParams = new URL(request.url, "http://server").searchParams;
this.rtcSupported = searchParams.get("webrtc_supported") === "true";
}
_setName(req) {
let ua = parser(req.headers['user-agent']);

View file

@ -32,21 +32,28 @@ export default class PairDropServer {
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const publicPathAbs = conf.wsFallback
? path.join(__dirname, '../public_included_ws_fallback')
: path.join(__dirname, '../public');
const publicPathAbs = path.join(__dirname, '../public');
app.use(express.static(publicPathAbs));
app.use((req, res) => {
if (conf.debugMode && conf.rateLimit && req.path === "/ip") {
console.debug("\n");
console.debug("----DEBUG RATE_LIMIT----")
console.debug("To find out the correct value for RATE_LIMIT go to '/ip' and ensure the returned IP-address is the IP-address of your client.")
console.debug("See https://github.com/express-rate-limit/express-rate-limit#troubleshooting-proxy-issues for more info")
if (conf.debugMode && conf.rateLimit) {
console.debug("\n");
console.debug("----DEBUG RATE_LIMIT----")
console.debug("To find out the correct value for RATE_LIMIT go to '/ip' and ensure the returned IP-address is the IP-address of your client.")
console.debug("See https://github.com/express-rate-limit/express-rate-limit#troubleshooting-proxy-issues for more info")
app.get('/ip', (req, res) => {
res.send(req.ip);
}
})
}
// By default, clients connecting to your instance use the signaling server of your instance to connect to other devices.
// By using `WS_SERVER`, you can host an instance that uses another signaling server.
app.get('/config', (req, res) => {
res.send({
signalingServer: conf.signalingServer
});
});
app.use((req, res) => {
res.redirect(301, '/');
});

View file

@ -16,7 +16,6 @@ export default class PairDropWsServer {
this._wss = new WebSocketServer({ server });
this._wss.on('connection', (socket, request) => this._onConnection(new Peer(socket, request, conf)));
console.log('\nPairDrop is running on port', this._conf.port);
}
_onConnection(peer) {
@ -26,8 +25,11 @@ export default class PairDropWsServer {
this._keepAlive(peer);
this._send(peer, {
type: 'rtc-config',
config: this._conf.rtcConfig
type: 'ws-config',
wsConfig: {
rtcConfig: this._conf.rtcConfig,
wsFallback: this._conf.wsFallback
}
});
// send displayName
@ -87,8 +89,26 @@ export default class PairDropWsServer {
this._onLeavePublicRoom(sender);
break;
case 'signal':
default:
this._signalAndRelay(sender, message);
break;
case 'request':
case 'header':
case 'partition':
case 'partition-received':
case 'progress':
case 'files-transfer-response':
case 'file-transfer-complete':
case 'message-transfer-complete':
case 'text':
case 'display-name-changed':
case 'ws-chunk':
// relay ws-fallback
if (this._conf.wsFallback) {
this._signalAndRelay(sender, message);
}
else {
console.log("Websocket fallback is not activated on this instance.")
}
}
}