Add support for and use socket host override. (#1682)
* Add support for and use socket host override. Closes #1378 * Fix embeds with the new websocket constructor
This commit is contained in:
parent
9d5bdc320c
commit
d24ddc2b0a
@ -408,6 +408,25 @@ func SetServerURL(w http.ResponseWriter, r *http.Request) {
|
|||||||
controllers.WriteSimpleResponse(w, true, "server url set")
|
controllers.WriteSimpleResponse(w, true, "server url set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSocketHostOverride will set the host override for the websocket.
|
||||||
|
func SetSocketHostOverride(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if !requirePOST(w, r) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
configValue, success := getValueFromRequest(w, r)
|
||||||
|
if !success {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := data.SetWebsocketOverrideHost(configValue.Value.(string)); err != nil {
|
||||||
|
controllers.WriteSimpleResponse(w, false, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controllers.WriteSimpleResponse(w, true, "websocket host override set")
|
||||||
|
}
|
||||||
|
|
||||||
// SetDirectoryEnabled will handle the web config request to enable or disable directory registration.
|
// SetDirectoryEnabled will handle the web config request to enable or disable directory registration.
|
||||||
func SetDirectoryEnabled(w http.ResponseWriter, r *http.Request) {
|
func SetDirectoryEnabled(w http.ResponseWriter, r *http.Request) {
|
||||||
if !requirePOST(w, r) {
|
if !requirePOST(w, r) {
|
||||||
|
@ -53,6 +53,7 @@ func GetServerConfig(w http.ResponseWriter, r *http.Request) {
|
|||||||
RTMPServerPort: data.GetRTMPPortNumber(),
|
RTMPServerPort: data.GetRTMPPortNumber(),
|
||||||
ChatDisabled: data.GetChatDisabled(),
|
ChatDisabled: data.GetChatDisabled(),
|
||||||
ChatJoinMessagesEnabled: data.GetChatJoinMessagesEnabled(),
|
ChatJoinMessagesEnabled: data.GetChatJoinMessagesEnabled(),
|
||||||
|
SocketHostOverride: data.GetWebsocketOverrideHost(),
|
||||||
VideoSettings: videoSettings{
|
VideoSettings: videoSettings{
|
||||||
VideoQualityVariants: videoQualityVariants,
|
VideoQualityVariants: videoQualityVariants,
|
||||||
LatencyLevel: data.GetStreamLatencyLevel().Level,
|
LatencyLevel: data.GetStreamLatencyLevel().Level,
|
||||||
@ -103,6 +104,7 @@ type serverConfigAdminResponse struct {
|
|||||||
ForbiddenUsernames []string `json:"forbiddenUsernames"`
|
ForbiddenUsernames []string `json:"forbiddenUsernames"`
|
||||||
Federation federationConfigResponse `json:"federation"`
|
Federation federationConfigResponse `json:"federation"`
|
||||||
SuggestedUsernames []string `json:"suggestedUsernames"`
|
SuggestedUsernames []string `json:"suggestedUsernames"`
|
||||||
|
SocketHostOverride string `json:"socketHostOverride,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type videoSettings struct {
|
type videoSettings struct {
|
||||||
|
@ -21,6 +21,7 @@ type webConfigResponse struct {
|
|||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
NSFW bool `json:"nsfw"`
|
NSFW bool `json:"nsfw"`
|
||||||
|
SocketHostOverride string `json:"socketHostOverride,omitempty"`
|
||||||
ExtraPageContent string `json:"extraPageContent"`
|
ExtraPageContent string `json:"extraPageContent"`
|
||||||
StreamTitle string `json:"streamTitle,omitempty"` // What's going on with the current stream
|
StreamTitle string `json:"streamTitle,omitempty"` // What's going on with the current stream
|
||||||
SocialHandles []models.SocialHandle `json:"socialHandles"`
|
SocialHandles []models.SocialHandle `json:"socialHandles"`
|
||||||
@ -78,6 +79,7 @@ func GetWebConfig(w http.ResponseWriter, r *http.Request) {
|
|||||||
Tags: data.GetServerMetadataTags(),
|
Tags: data.GetServerMetadataTags(),
|
||||||
Version: config.GetReleaseString(),
|
Version: config.GetReleaseString(),
|
||||||
NSFW: data.GetNSFW(),
|
NSFW: data.GetNSFW(),
|
||||||
|
SocketHostOverride: data.GetWebsocketOverrideHost(),
|
||||||
ExtraPageContent: pageContent,
|
ExtraPageContent: pageContent,
|
||||||
StreamTitle: data.GetStreamTitle(),
|
StreamTitle: data.GetStreamTitle(),
|
||||||
SocialHandles: socialHandles,
|
SocialHandles: socialHandles,
|
||||||
|
@ -24,6 +24,7 @@ const (
|
|||||||
serverURLKey = "server_url"
|
serverURLKey = "server_url"
|
||||||
httpPortNumberKey = "http_port_number"
|
httpPortNumberKey = "http_port_number"
|
||||||
httpListenAddressKey = "http_listen_address"
|
httpListenAddressKey = "http_listen_address"
|
||||||
|
websocketHostOverrideKey = "websocket_host_override"
|
||||||
rtmpPortNumberKey = "rtmp_port_number"
|
rtmpPortNumberKey = "rtmp_port_number"
|
||||||
serverMetadataTagsKey = "server_metadata_tags"
|
serverMetadataTagsKey = "server_metadata_tags"
|
||||||
directoryEnabledKey = "directory_enabled"
|
directoryEnabledKey = "directory_enabled"
|
||||||
@ -200,6 +201,18 @@ func GetHTTPPortNumber() int {
|
|||||||
return int(port)
|
return int(port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetWebsocketOverrideHost will set the host override for websockets.
|
||||||
|
func SetWebsocketOverrideHost(host string) error {
|
||||||
|
return _datastore.SetString(websocketHostOverrideKey, host)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWebsocketOverrideHost will return the host override for websockets.
|
||||||
|
func GetWebsocketOverrideHost() string {
|
||||||
|
host, _ := _datastore.GetString(websocketHostOverrideKey)
|
||||||
|
|
||||||
|
return host
|
||||||
|
}
|
||||||
|
|
||||||
// SetHTTPPortNumber will set the server HTTP port.
|
// SetHTTPPortNumber will set the server HTTP port.
|
||||||
func SetHTTPPortNumber(port float64) error {
|
func SetHTTPPortNumber(port float64) error {
|
||||||
return _datastore.SetNumber(httpPortNumberKey, port)
|
return _datastore.SetNumber(httpPortNumberKey, port)
|
||||||
|
@ -245,6 +245,9 @@ func Start() error {
|
|||||||
// Server rtmp port
|
// Server rtmp port
|
||||||
http.HandleFunc("/api/admin/config/rtmpserverport", middleware.RequireAdminAuth(admin.SetRTMPServerPort))
|
http.HandleFunc("/api/admin/config/rtmpserverport", middleware.RequireAdminAuth(admin.SetRTMPServerPort))
|
||||||
|
|
||||||
|
// Websocket host override
|
||||||
|
http.HandleFunc("/api/admin/config/sockethostoverride", middleware.RequireAdminAuth(admin.SetSocketHostOverride))
|
||||||
|
|
||||||
// Is server marked as NSFW
|
// Is server marked as NSFW
|
||||||
http.HandleFunc("/api/admin/config/nsfw", middleware.RequireAdminAuth(admin.SetNSFW))
|
http.HandleFunc("/api/admin/config/nsfw", middleware.RequireAdminAuth(admin.SetNSFW))
|
||||||
|
|
||||||
|
86
test/automated/browser/package-lock.json
generated
86
test/automated/browser/package-lock.json
generated
@ -2087,9 +2087,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.14.8",
|
"version": "1.14.4",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz",
|
||||||
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
|
"integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -3652,45 +3652,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/node-fetch": {
|
"node_modules/node-fetch": {
|
||||||
"version": "2.6.7",
|
"version": "2.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.2.tgz",
|
||||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
"integrity": "sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
|
||||||
"whatwg-url": "^5.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "4.x || >=6.0.0"
|
"node": "4.x || >=6.0.0"
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"encoding": "^0.1.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"encoding": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/node-fetch/node_modules/tr46": {
|
|
||||||
"version": "0.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
|
||||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/node-fetch/node_modules/webidl-conversions": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
|
||||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/node-fetch/node_modules/whatwg-url": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
|
||||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"tr46": "~0.0.3",
|
|
||||||
"webidl-conversions": "^3.0.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-int64": {
|
"node_modules/node-int64": {
|
||||||
@ -6589,9 +6556,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"follow-redirects": {
|
"follow-redirects": {
|
||||||
"version": "1.14.8",
|
"version": "1.14.4",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz",
|
||||||
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
|
"integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"for-in": {
|
"for-in": {
|
||||||
@ -7780,37 +7747,10 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node-fetch": {
|
"node-fetch": {
|
||||||
"version": "2.6.7",
|
"version": "2.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.2.tgz",
|
||||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
"integrity": "sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"requires": {
|
|
||||||
"whatwg-url": "^5.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"tr46": {
|
|
||||||
"version": "0.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
|
||||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"webidl-conversions": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
|
||||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"whatwg-url": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
|
||||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"tr46": "~0.0.3",
|
|
||||||
"webidl-conversions": "^3.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node-int64": {
|
"node-int64": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
|
@ -20,6 +20,7 @@ import {
|
|||||||
URL_CONFIG,
|
URL_CONFIG,
|
||||||
TIMER_STATUS_UPDATE,
|
TIMER_STATUS_UPDATE,
|
||||||
} from './utils/constants.js';
|
} from './utils/constants.js';
|
||||||
|
import { URL_WEBSOCKET } from './utils/constants.js';
|
||||||
|
|
||||||
export default class StandaloneChat extends Component {
|
export default class StandaloneChat extends Component {
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
@ -53,6 +54,8 @@ export default class StandaloneChat extends Component {
|
|||||||
this.setupChatAuth = this.setupChatAuth.bind(this);
|
this.setupChatAuth = this.setupChatAuth.bind(this);
|
||||||
this.disableChat = this.disableChat.bind(this);
|
this.disableChat = this.disableChat.bind(this);
|
||||||
|
|
||||||
|
this.socketHostOverride = null;
|
||||||
|
|
||||||
// user events
|
// user events
|
||||||
this.handleWebsocketMessage = this.handleWebsocketMessage.bind(this);
|
this.handleWebsocketMessage = this.handleWebsocketMessage.bind(this);
|
||||||
|
|
||||||
@ -98,7 +101,7 @@ export default class StandaloneChat extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setConfigData(data = {}) {
|
setConfigData(data = {}) {
|
||||||
const { chatDisabled } = data;
|
const { chatDisabled, socketHostOverride } = data;
|
||||||
|
|
||||||
// If this is the first time setting the config
|
// If this is the first time setting the config
|
||||||
// then setup chat if it's enabled.
|
// then setup chat if it's enabled.
|
||||||
@ -107,7 +110,7 @@ export default class StandaloneChat extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.hasConfiguredChat = true;
|
this.hasConfiguredChat = true;
|
||||||
|
this.socketHostOverride = socketHostOverride;
|
||||||
this.setState({
|
this.setState({
|
||||||
canChat: !chatDisabled,
|
canChat: !chatDisabled,
|
||||||
configData: {
|
configData: {
|
||||||
@ -277,7 +280,10 @@ export default class StandaloneChat extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Without a valid access token he websocket connection will be rejected.
|
// Without a valid access token he websocket connection will be rejected.
|
||||||
const websocket = new Websocket(accessToken);
|
const websocket = new Websocket(
|
||||||
|
accessToken,
|
||||||
|
this.socketHostOverride || URL_WEBSOCKET
|
||||||
|
);
|
||||||
websocket.addListener(
|
websocket.addListener(
|
||||||
CALLBACKS.RAW_WEBSOCKET_MESSAGE_RECEIVED,
|
CALLBACKS.RAW_WEBSOCKET_MESSAGE_RECEIVED,
|
||||||
this.handleWebsocketMessage
|
this.handleWebsocketMessage
|
||||||
|
@ -2,6 +2,8 @@ import { h, Component } from '/js/web_modules/preact.js';
|
|||||||
import htm from '/js/web_modules/htm.js';
|
import htm from '/js/web_modules/htm.js';
|
||||||
const html = htm.bind(h);
|
const html = htm.bind(h);
|
||||||
|
|
||||||
|
import { URL_WEBSOCKET } from './utils/constants.js';
|
||||||
|
|
||||||
import { OwncastPlayer } from './components/player.js';
|
import { OwncastPlayer } from './components/player.js';
|
||||||
import SocialIconsList from './components/platform-logos-list.js';
|
import SocialIconsList from './components/platform-logos-list.js';
|
||||||
import UsernameForm from './components/chat/username.js';
|
import UsernameForm from './components/chat/username.js';
|
||||||
@ -154,6 +156,7 @@ export default class App extends Component {
|
|||||||
this.hasConfiguredChat = false;
|
this.hasConfiguredChat = false;
|
||||||
this.setupChatAuth = this.setupChatAuth.bind(this);
|
this.setupChatAuth = this.setupChatAuth.bind(this);
|
||||||
this.disableChat = this.disableChat.bind(this);
|
this.disableChat = this.disableChat.bind(this);
|
||||||
|
this.socketHostOverride = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -245,9 +248,11 @@ export default class App extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setConfigData(data = {}) {
|
setConfigData(data = {}) {
|
||||||
const { name, summary, chatDisabled } = data;
|
const { name, summary, chatDisabled, socketHostOverride } = data;
|
||||||
window.document.title = name;
|
window.document.title = name;
|
||||||
|
|
||||||
|
this.socketHostOverride = socketHostOverride;
|
||||||
|
|
||||||
// If this is the first time setting the config
|
// If this is the first time setting the config
|
||||||
// then setup chat if it's enabled.
|
// then setup chat if it's enabled.
|
||||||
if (!this.hasConfiguredChat && !chatDisabled) {
|
if (!this.hasConfiguredChat && !chatDisabled) {
|
||||||
@ -638,8 +643,11 @@ export default class App extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Without a valid access token he websocket connection will be rejected.
|
// Without a valid access token the websocket connection will be rejected.
|
||||||
const websocket = new Websocket(accessToken);
|
const websocket = new Websocket(
|
||||||
|
accessToken,
|
||||||
|
this.socketHostOverride || URL_WEBSOCKET
|
||||||
|
);
|
||||||
websocket.addListener(
|
websocket.addListener(
|
||||||
CALLBACKS.RAW_WEBSOCKET_MESSAGE_RECEIVED,
|
CALLBACKS.RAW_WEBSOCKET_MESSAGE_RECEIVED,
|
||||||
this.handleWebsocketMessage
|
this.handleWebsocketMessage
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { URL_WEBSOCKET } from './constants.js';
|
|
||||||
/**
|
/**
|
||||||
* These are the types of messages that we can handle with the websocket.
|
* These are the types of messages that we can handle with the websocket.
|
||||||
* Mostly used by `websocket.js` but if other components need to handle
|
* Mostly used by `websocket.js` but if other components need to handle
|
||||||
@ -30,8 +29,9 @@ export const CALLBACKS = {
|
|||||||
const TIMER_WEBSOCKET_RECONNECT = 5000; // ms
|
const TIMER_WEBSOCKET_RECONNECT = 5000; // ms
|
||||||
|
|
||||||
export default class Websocket {
|
export default class Websocket {
|
||||||
constructor(accessToken) {
|
constructor(accessToken, path) {
|
||||||
this.websocket = null;
|
this.websocket = null;
|
||||||
|
this.path = path;
|
||||||
this.websocketReconnectTimer = null;
|
this.websocketReconnectTimer = null;
|
||||||
this.accessToken = accessToken;
|
this.accessToken = accessToken;
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ export default class Websocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createAndConnect() {
|
createAndConnect() {
|
||||||
const url = new URL(URL_WEBSOCKET);
|
const url = new URL(this.path);
|
||||||
url.searchParams.append('accessToken', this.accessToken);
|
url.searchParams.append('accessToken', this.accessToken);
|
||||||
|
|
||||||
const ws = new WebSocket(url.toString());
|
const ws = new WebSocket(url.toString());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user