mirror of
https://github.com/strukturag/nextcloud-spreed-signaling
synced 2026-03-14 14:35:44 +01:00
Move SplitEntries helper to internal package.
This commit is contained in:
parent
1c3a03e972
commit
a1ec06d802
16 changed files with 134 additions and 32 deletions
|
|
@ -26,6 +26,8 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
)
|
||||
|
||||
type AllowedIps struct {
|
||||
|
|
@ -83,7 +85,7 @@ func parseIPNet(s string) (*net.IPNet, error) {
|
|||
|
||||
func ParseAllowedIps(allowed string) (*AllowedIps, error) {
|
||||
var allowedIps []*net.IPNet
|
||||
for ip := range SplitEntries(allowed, ",") {
|
||||
for ip := range internal.SplitEntries(allowed, ",") {
|
||||
i, err := parseIPNet(ip)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import (
|
|||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/async"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
)
|
||||
|
||||
|
|
@ -92,7 +93,7 @@ func NewBackendServer(ctx context.Context, config *goconf.ConfigFile, hub *Hub,
|
|||
// TODO(jojo): Make the validity for TURN credentials configurable.
|
||||
turnvalid := 24 * time.Hour
|
||||
|
||||
turnserverslist := slices.Collect(SplitEntries(turnservers, ","))
|
||||
turnserverslist := slices.Collect(internal.SplitEntries(turnservers, ","))
|
||||
if len(turnserverslist) != 0 {
|
||||
if turnapikey == "" {
|
||||
return nil, errors.New("need a TURN API key if TURN servers are configured")
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ func NewBackendStorageStatic(logger log.Logger, config *goconf.ConfigFile, stats
|
|||
} else if allowedUrls, _ := config.GetString("backend", "allowed"); allowedUrls != "" {
|
||||
// Old-style configuration, only hosts are configured and are using a common secret.
|
||||
allowMap := make(map[string]bool)
|
||||
for u := range SplitEntries(allowedUrls, ",") {
|
||||
for u := range internal.SplitEntries(allowedUrls, ",") {
|
||||
if idx := strings.IndexByte(u, '/'); idx != -1 {
|
||||
logger.Printf("WARNING: Removing path from allowed hostname \"%s\", check your configuration!", u)
|
||||
if u = u[:idx]; u == "" {
|
||||
|
|
@ -285,7 +285,7 @@ func (s *backendStorageStatic) UpsertHost(host string, backends []*Backend, seen
|
|||
func getConfiguredBackendIDs(backendIds string) (ids []string) {
|
||||
seen := make(map[string]bool)
|
||||
|
||||
for id := range SplitEntries(backendIds, ",") {
|
||||
for id := range internal.SplitEntries(backendIds, ",") {
|
||||
if seen[id] {
|
||||
continue
|
||||
}
|
||||
|
|
@ -330,7 +330,7 @@ func getConfiguredHosts(logger log.Logger, backendIds string, config *goconf.Con
|
|||
|
||||
var urls []string
|
||||
if u, _ := GetStringOptionWithEnv(config, id, "urls"); u != "" {
|
||||
urls = slices.Sorted(SplitEntries(u, ","))
|
||||
urls = slices.Sorted(internal.SplitEntries(u, ","))
|
||||
urls = slices.Compact(urls)
|
||||
} else if u, _ := GetStringOptionWithEnv(config, id, "url"); u != "" {
|
||||
if u = strings.TrimSpace(u); u != "" {
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ import (
|
|||
"github.com/mailru/easyjson/jwriter"
|
||||
|
||||
signaling "github.com/strukturag/nextcloud-spreed-signaling"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -566,7 +567,7 @@ func main() {
|
|||
|
||||
urls := make([]url.URL, 0)
|
||||
urlstrings := make([]string, 0)
|
||||
for host := range signaling.SplitEntries(*addr, ",") {
|
||||
for host := range internal.SplitEntries(*addr, ",") {
|
||||
u := url.URL{
|
||||
Scheme: "ws",
|
||||
Host: host,
|
||||
|
|
|
|||
16
config.go
16
config.go
|
|
@ -23,10 +23,8 @@ package signaling
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"iter"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/dlintw/goconf"
|
||||
)
|
||||
|
|
@ -87,17 +85,3 @@ func GetStringOptions(config *goconf.ConfigFile, section string, ignoreErrors bo
|
|||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SplitEntries returns an iterator over all non-empty substrings of s separated
|
||||
// by sep.
|
||||
func SplitEntries(s string, sep string) iter.Seq[string] {
|
||||
return func(yield func(entry string) bool) {
|
||||
for entry := range strings.SplitSeq(s, sep) {
|
||||
if entry = strings.TrimSpace(entry); entry != "" {
|
||||
if !yield(entry) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ func (c *EtcdClient) getConfigStringWithFallback(config *goconf.ConfigFile, opti
|
|||
func (c *EtcdClient) load(config *goconf.ConfigFile, ignoreErrors bool) error {
|
||||
var endpoints []string
|
||||
if endpointsString := c.getConfigStringWithFallback(config, "endpoints"); endpointsString != "" {
|
||||
endpoints = slices.Collect(SplitEntries(endpointsString, ","))
|
||||
endpoints = slices.Collect(internal.SplitEntries(endpointsString, ","))
|
||||
} else if discoverySrv := c.getConfigStringWithFallback(config, "discoverysrv"); discoverySrv != "" {
|
||||
discoveryService := c.getConfigStringWithFallback(config, "discoveryservice")
|
||||
clients, err := srv.GetClient("etcd-client", discoverySrv, discoveryService)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import (
|
|||
status "google.golang.org/grpc/status"
|
||||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/async"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
)
|
||||
|
||||
|
|
@ -657,7 +658,7 @@ func (c *GrpcClients) loadTargetsStatic(config *goconf.ConfigFile, fromReload bo
|
|||
}
|
||||
|
||||
targets, _ := config.GetString("grpc", "targets")
|
||||
for target := range SplitEntries(targets, ",") {
|
||||
for target := range internal.SplitEntries(targets, ",") {
|
||||
if entries, found := clientsMap[target]; found {
|
||||
clients = append(clients, entries.clients...)
|
||||
if dnsDiscovery && entries.entry == nil {
|
||||
|
|
|
|||
|
|
@ -887,7 +887,7 @@ func TestWebsocketFeatures(t *testing.T) {
|
|||
assert.True(strings.HasPrefix(serverHeader, "nextcloud-spreed-signaling/"), "expected valid server header, got \"%s\"", serverHeader)
|
||||
features := response.Header.Get("X-Spreed-Signaling-Features")
|
||||
featuresList := make(map[string]bool)
|
||||
for f := range SplitEntries(features, ",") {
|
||||
for f := range internal.SplitEntries(features, ",") {
|
||||
_, found := featuresList[f]
|
||||
assert.False(found, "duplicate feature id \"%s\" in \"%s\"", f, features)
|
||||
featuresList[f] = true
|
||||
|
|
|
|||
41
internal/split_entries.go
Normal file
41
internal/split_entries.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* Standalone signaling server for the Nextcloud Spreed app.
|
||||
* Copyright (C) 2025 struktur AG
|
||||
*
|
||||
* @author Joachim Bauch <bauch@struktur.de>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package internal
|
||||
|
||||
import (
|
||||
"iter"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SplitEntries returns an iterator over all non-empty substrings of s separated
|
||||
// by sep.
|
||||
func SplitEntries(s string, sep string) iter.Seq[string] {
|
||||
return func(yield func(entry string) bool) {
|
||||
for entry := range strings.SplitSeq(s, sep) {
|
||||
if entry = strings.TrimSpace(entry); entry != "" {
|
||||
if !yield(entry) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
68
internal/split_entries_test.go
Normal file
68
internal/split_entries_test.go
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* Standalone signaling server for the Nextcloud Spreed app.
|
||||
* Copyright (C) 2025 struktur AG
|
||||
*
|
||||
* @author Joachim Bauch <bauch@struktur.de>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package internal
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSplitEntries(t *testing.T) {
|
||||
t.Parallel()
|
||||
assert := assert.New(t)
|
||||
testcases := []struct {
|
||||
s string
|
||||
sep string
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
"a b",
|
||||
" ",
|
||||
[]string{"a", "b"},
|
||||
},
|
||||
{
|
||||
"a b",
|
||||
",",
|
||||
[]string{"a b"},
|
||||
},
|
||||
{
|
||||
"a b",
|
||||
" ",
|
||||
[]string{"a", "b"},
|
||||
},
|
||||
{
|
||||
"a,b,",
|
||||
",",
|
||||
[]string{"a", "b"},
|
||||
},
|
||||
{
|
||||
"a,,b",
|
||||
",",
|
||||
[]string{"a", "b"},
|
||||
},
|
||||
}
|
||||
for idx, tc := range testcases {
|
||||
assert.Equal(tc.expected, slices.Collect(SplitEntries(tc.s, tc.sep)), "failed for testcase %d: %s", idx, tc.s)
|
||||
}
|
||||
}
|
||||
|
|
@ -256,7 +256,7 @@ func (p *mcuJanusPublisher) SendMessage(ctx context.Context, message *MessageCli
|
|||
}
|
||||
|
||||
func getFmtpValue(fmtp string, key string) (string, bool) {
|
||||
for part := range SplitEntries(fmtp, ";") {
|
||||
for part := range internal.SplitEntries(fmtp, ";") {
|
||||
kv := strings.SplitN(part, "=", 2)
|
||||
if len(kv) != 2 {
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -1609,7 +1609,7 @@ func (m *mcuProxy) loadContinentsMap(config *goconf.ConfigFile) error {
|
|||
}
|
||||
|
||||
var values []string
|
||||
for v := range SplitEntries(value, ",") {
|
||||
for v := range internal.SplitEntries(value, ",") {
|
||||
v = strings.ToUpper(v)
|
||||
if !IsValidContinent(v) {
|
||||
m.logger.Printf("Ignore unknown continent %s for override %s", v, option)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import (
|
|||
"github.com/gorilla/mux"
|
||||
|
||||
signaling "github.com/strukturag/nextcloud-spreed-signaling"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
signalinglog "github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
)
|
||||
|
||||
|
|
@ -106,7 +107,7 @@ func main() {
|
|||
writeTimeout = defaultWriteTimeout
|
||||
}
|
||||
|
||||
for address := range signaling.SplitEntries(addr, " ") {
|
||||
for address := range internal.SplitEntries(addr, " ") {
|
||||
go func(address string) {
|
||||
logger.Println("Listening on", address)
|
||||
listener, err := net.Listen("tcp", address)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ import (
|
|||
|
||||
signaling "github.com/strukturag/nextcloud-spreed-signaling"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/api"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
)
|
||||
|
||||
|
|
@ -322,7 +323,7 @@ func TestWebsocketFeatures(t *testing.T) {
|
|||
}
|
||||
features := response.Header.Get("X-Spreed-Signaling-Features")
|
||||
featuresList := make(map[string]bool)
|
||||
for f := range signaling.SplitEntries(features, ",") {
|
||||
for f := range internal.SplitEntries(features, ",") {
|
||||
if _, found := featuresList[f]; found {
|
||||
assert.Fail("duplicate feature", "id \"%s\" in \"%s\"", f, features)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import (
|
|||
|
||||
"github.com/dlintw/goconf"
|
||||
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
)
|
||||
|
||||
|
|
@ -89,7 +90,7 @@ func (p *proxyConfigStatic) configure(config *goconf.ConfigFile, fromReload bool
|
|||
remove := maps.Clone(p.connectionsMap)
|
||||
|
||||
mcuUrl, _ := GetStringOptionWithEnv(config, "mcu", "url")
|
||||
for u := range SplitEntries(mcuUrl, " ") {
|
||||
for u := range internal.SplitEntries(mcuUrl, " ") {
|
||||
if existing, found := remove[u]; found {
|
||||
// Proxy connection still exists in new configuration
|
||||
delete(remove, u)
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import (
|
|||
"github.com/nats-io/nats.go"
|
||||
|
||||
signaling "github.com/strukturag/nextcloud-spreed-signaling"
|
||||
"github.com/strukturag/nextcloud-spreed-signaling/internal"
|
||||
signalinglog "github.com/strukturag/nextcloud-spreed-signaling/log"
|
||||
)
|
||||
|
||||
|
|
@ -342,7 +343,7 @@ func main() {
|
|||
if writeTimeout <= 0 {
|
||||
writeTimeout = defaultWriteTimeout
|
||||
}
|
||||
for address := range signaling.SplitEntries(saddr, " ") {
|
||||
for address := range internal.SplitEntries(saddr, " ") {
|
||||
go func(address string) {
|
||||
logger.Println("Listening on", address)
|
||||
listener, err := createTLSListener(address, cert, key)
|
||||
|
|
@ -375,7 +376,7 @@ func main() {
|
|||
writeTimeout = defaultWriteTimeout
|
||||
}
|
||||
|
||||
for address := range signaling.SplitEntries(addr, " ") {
|
||||
for address := range internal.SplitEntries(addr, " ") {
|
||||
go func(address string) {
|
||||
logger.Println("Listening on", address)
|
||||
listener, err := createListener(address)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue