Using Peertube v5.0.0 websocket capacities.
This commit is contained in:
parent
e7eca75736
commit
0be08c7b57
1
package-lock.json
generated
1
package-lock.json
generated
@ -25076,6 +25076,7 @@
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true
|
||||
},
|
||||
"emoji-regex": {
|
||||
|
@ -1,5 +1,7 @@
|
||||
import type { RegisterServerOptions, PeerTubeHelpers } from '@peertube/peertube-types'
|
||||
import { Response } from 'express'
|
||||
import type { Response } from 'express'
|
||||
import type { IncomingMessage } from 'http'
|
||||
import type { Duplex } from 'stream'
|
||||
|
||||
const packagejson: any = require('../../../package.json')
|
||||
const version: string = packagejson.version || ''
|
||||
@ -19,14 +21,34 @@ function getBaseRouterRoute (options: RegisterServerOptions): string {
|
||||
return options.peertubeHelpers.plugin.getBaseRouterRoute()
|
||||
}
|
||||
|
||||
interface RegisterServerWebSocketRouteOptions {
|
||||
route: string
|
||||
handler: (request: IncomingMessage, socket: Duplex, head: Buffer) => any
|
||||
}
|
||||
// getBaseWebSocketRoute() comes with Peertube 5.0.0.
|
||||
type RegisterServerOptionsV5 = RegisterServerOptions & {
|
||||
registerWebSocketRoute?: (options: RegisterServerWebSocketRouteOptions) => void
|
||||
peertubeHelpers: {
|
||||
plugin: {
|
||||
getBaseWebSocketRoute?: () => string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base router route, but without the plugin version.
|
||||
* Returns the base route for Websocket endpoint.
|
||||
* This features comes with Peertube >=5.0.0.
|
||||
* @param options server options
|
||||
* @returns the route, or undefined if the Peertube version does not provide this feature
|
||||
*/
|
||||
function getBaseRouterCanonicalRoute (options: RegisterServerOptions): string {
|
||||
let route = getBaseRouterRoute(options)
|
||||
route = route.replace(pluginShortName + '/' + version + '/', pluginShortName + '/')
|
||||
return route
|
||||
function getBaseWebSocketRoute (options: RegisterServerOptionsV5): string | undefined {
|
||||
if (!options.peertubeHelpers.plugin) {
|
||||
throw new Error('Missing peertubeHelpers.plugin, have you the correct Peertube version?')
|
||||
}
|
||||
if (!options.peertubeHelpers.plugin.getBaseWebSocketRoute) {
|
||||
return undefined
|
||||
}
|
||||
return options.peertubeHelpers.plugin.getBaseWebSocketRoute()
|
||||
}
|
||||
|
||||
function getBaseStaticRoute (options: RegisterServerOptions): string {
|
||||
@ -71,8 +93,9 @@ async function getUserNickname (options: RegisterServerOptions, user: AuthUserFi
|
||||
}
|
||||
|
||||
export {
|
||||
RegisterServerOptionsV5,
|
||||
getBaseRouterRoute,
|
||||
getBaseRouterCanonicalRoute,
|
||||
getBaseWebSocketRoute,
|
||||
getBaseStaticRoute,
|
||||
isUserAdmin,
|
||||
getUserNickname,
|
||||
|
@ -4,7 +4,9 @@ import type {
|
||||
ProsodyListRoomsResult, ProsodyListRoomsResultRoom
|
||||
} from '../../../shared/lib/types'
|
||||
import { createProxyServer } from 'http-proxy'
|
||||
import { getBaseRouterRoute, getBaseRouterCanonicalRoute, getBaseStaticRoute, isUserAdmin } from '../helpers'
|
||||
import {
|
||||
RegisterServerOptionsV5, getBaseRouterRoute, getBaseWebSocketRoute, getBaseStaticRoute, isUserAdmin
|
||||
} from '../helpers'
|
||||
import { asyncMiddleware } from '../middlewares/async'
|
||||
import { getProsodyDomain } from '../prosody/config/domain'
|
||||
import { getAPIKey } from '../apikey'
|
||||
@ -14,7 +16,6 @@ import * as path from 'path'
|
||||
const got = require('got')
|
||||
|
||||
const fs = require('fs').promises
|
||||
// const proxy = require('express-http-proxy')
|
||||
|
||||
interface ProsodyProxyInfo {
|
||||
host: string
|
||||
@ -23,15 +24,11 @@ interface ProsodyProxyInfo {
|
||||
let currentProsodyProxyInfo: ProsodyProxyInfo | null = null
|
||||
let currentHttpBindProxy: ReturnType<typeof createProxyServer> | null = null
|
||||
let currentWebsocketProxy: ReturnType<typeof createProxyServer> | null = null
|
||||
interface CurrentWebsocketUpgradeEvent {
|
||||
server: any
|
||||
listener: Function
|
||||
}
|
||||
let currentWebsocketUpgradeEvent: CurrentWebsocketUpgradeEvent | null = null
|
||||
|
||||
async function initWebchatRouter (options: RegisterServerOptions): Promise<Router> {
|
||||
async function initWebchatRouter (options: RegisterServerOptionsV5): Promise<Router> {
|
||||
const {
|
||||
getRouter,
|
||||
registerWebSocketRoute,
|
||||
peertubeHelpers,
|
||||
settingsManager
|
||||
} = options
|
||||
@ -50,6 +47,10 @@ async function initWebchatRouter (options: RegisterServerOptions): Promise<Route
|
||||
'converse-theme', 'converse-autocolors'
|
||||
])
|
||||
|
||||
const boshUri = getBaseRouterRoute(options) + 'http-bind'
|
||||
let wsUri = getBaseWebSocketRoute(options) // can be undefined
|
||||
wsUri = wsUri !== undefined ? wsUri + 'xmpp-websocket' : ''
|
||||
|
||||
let room: string
|
||||
let authenticationUrl: string = ''
|
||||
let advancedControls: boolean = false // auto join the chat in viewer mode, if not logged in
|
||||
@ -81,13 +82,7 @@ async function initWebchatRouter (options: RegisterServerOptions): Promise<Route
|
||||
room = '{{VIDEO_UUID}}@room.' + prosodyDomain
|
||||
}
|
||||
}
|
||||
// Here we are using getBaseRouterCanonicalRoute,
|
||||
// which correspond to a path without the plugin version.
|
||||
// We are doing this, so the path is predictible,
|
||||
// and can be optimized in the nginx configuration (to bypass Peertube).
|
||||
const proxyBaseUri = getBaseRouterCanonicalRoute(options) + 'webchat/'
|
||||
const boshUri = proxyBaseUri + 'http-bind'
|
||||
const wsUri = proxyBaseUri + 'xmpp-websocket'
|
||||
|
||||
authenticationUrl = options.peertubeHelpers.config.getWebserverUrl() +
|
||||
getBaseRouterRoute(options) +
|
||||
'api/auth'
|
||||
@ -229,59 +224,19 @@ async function initWebchatRouter (options: RegisterServerOptions): Promise<Route
|
||||
}
|
||||
}
|
||||
)
|
||||
router.all('/xmpp-websocket',
|
||||
(req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
|
||||
// Peertube >=5.0.0: Adding the websocket route.
|
||||
if (registerWebSocketRoute) {
|
||||
registerWebSocketRoute({
|
||||
route: '/xmpp-websocket',
|
||||
handler: (request, socket, head) => {
|
||||
if (!currentWebsocketProxy) {
|
||||
res.status(404)
|
||||
res.send('Not found')
|
||||
return
|
||||
throw new Error('There is no current websocket proxy, should not get here.')
|
||||
}
|
||||
|
||||
// Now, we need to attach an listener for the update event on the server...
|
||||
// But we don't have access to the server.
|
||||
// To get this, we will wait for the first request, and then get the server from there!
|
||||
if (!currentWebsocketUpgradeEvent) {
|
||||
peertubeHelpers.logger.info(
|
||||
'Here is the first websocket proxy connection, we are binding the upgrade listener...'
|
||||
)
|
||||
/**
|
||||
* Get the server object to subscribe to server events;
|
||||
* 'upgrade' for websocket and 'close' for graceful shutdown
|
||||
*
|
||||
* NOTE:
|
||||
* req.socket: node >= 13
|
||||
* req.connection: node < 13 (Remove this when node 12/13 support is dropped)
|
||||
*
|
||||
* This code was inspired by:
|
||||
* https://github.com/chimurai/http-proxy-middleware, file /src/http-proxy-middleware.ts#L53
|
||||
*/
|
||||
const s: any = (req.socket ?? req.connection)
|
||||
const server = 'server' in s ? s.server : null
|
||||
if (!server) {
|
||||
peertubeHelpers.logger.error('Cant access to the ExpressJS server, wont be able to handle websocket.')
|
||||
} else {
|
||||
currentWebsocketUpgradeEvent = {
|
||||
server,
|
||||
listener: (req: any, socket: any, head: any) => {
|
||||
// We are not the only websocket server! Peertube has its own. We must match the url.
|
||||
if (/webchat\/xmpp-websocket/.test(req.url)) {
|
||||
peertubeHelpers.logger.info('Got an http upgrade event that match the correct path')
|
||||
currentWebsocketProxy?.ws(req, socket, head)
|
||||
}
|
||||
}
|
||||
}
|
||||
server.on('upgrade', currentWebsocketUpgradeEvent.listener)
|
||||
}
|
||||
}
|
||||
|
||||
req.url = 'xmpp-websocket'
|
||||
currentWebsocketProxy.web(req, res)
|
||||
} catch (err) {
|
||||
next(err)
|
||||
currentWebsocketProxy.ws(request, socket, head)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
router.get('/prosody-list-rooms', asyncMiddleware(
|
||||
async (req: Request, res: Response, _next: NextFunction) => {
|
||||
@ -356,10 +311,6 @@ async function disableProxyRoute ({ peertubeHelpers }: RegisterServerOptions): P
|
||||
currentWebsocketProxy.close()
|
||||
currentWebsocketProxy = null
|
||||
}
|
||||
if (currentWebsocketUpgradeEvent) {
|
||||
peertubeHelpers.logger.info('Removing the upgrade listener')
|
||||
currentWebsocketUpgradeEvent.server.off('upgrade', currentWebsocketUpgradeEvent.listener)
|
||||
}
|
||||
} catch (err) {
|
||||
peertubeHelpers.logger.error('Seems that the http bind proxy close has failed: ' + (err as string))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user