feat(config): tighten RTMP URL validation
Some checks failed
ci-build / lint (push) Has been cancelled
ci-build / build (push) Has been cancelled
ci-build / release (push) Has been cancelled

This commit is contained in:
Rob Watson 2025-04-10 22:00:37 +02:00
parent 045498a2ce
commit b257f456ba
5 changed files with 27 additions and 11 deletions

View File

@ -325,7 +325,7 @@ func TestIntegrationDestinationValidations(t *testing.T) {
contents := getContents() contents := getContents()
assert.True(t, contentsIncludes(contents, "Configuration update failed:"), "expected to see config update error") assert.True(t, contentsIncludes(contents, "Configuration update failed:"), "expected to see config update error")
assert.True(t, contentsIncludes(contents, "validate: destination URL must start with"), "expected to see config update error") assert.True(t, contentsIncludes(contents, "validate: destination URL must be an RTMP URL"), "expected to see invalid RTMP URL error")
}, },
10*time.Second, 10*time.Second,
time.Second, time.Second,
@ -345,7 +345,7 @@ func TestIntegrationDestinationValidations(t *testing.T) {
contents := getContents() contents := getContents()
assert.True(t, contentsIncludes(contents, "Configuration update failed:"), "expected to see config update error") assert.True(t, contentsIncludes(contents, "Configuration update failed:"), "expected to see config update error")
assert.True(t, contentsIncludes(contents, "validate: destination URL must start with"), "expected to see config update error") assert.True(t, contentsIncludes(contents, "validate: destination URL must be an RTMP URL"), "expected to see invalid RTMP URL error")
}, },
10*time.Second, 10*time.Second,
time.Second, time.Second,

View File

@ -5,9 +5,9 @@ import (
_ "embed" _ "embed"
"errors" "errors"
"fmt" "fmt"
"net/url"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
@ -204,8 +204,10 @@ func validate(cfg Config) error {
urlCounts := make(map[string]int) urlCounts := make(map[string]int)
for _, dest := range cfg.Destinations { for _, dest := range cfg.Destinations {
if !strings.HasPrefix(dest.URL, "rtmp://") { if u, urlErr := url.Parse(dest.URL); urlErr != nil {
err = errors.Join(err, fmt.Errorf("destination URL must start with rtmp://")) err = errors.Join(err, fmt.Errorf("invalid destination URL: %w", urlErr))
} else if u.Scheme != "rtmp" {
err = errors.Join(err, errors.New("destination URL must be an RTMP URL"))
} }
urlCounts[dest.URL]++ urlCounts[dest.URL]++

View File

@ -25,8 +25,11 @@ var configLogfile []byte
//go:embed testdata/no-logfile.yml //go:embed testdata/no-logfile.yml
var configNoLogfile []byte var configNoLogfile []byte
//go:embed testdata/invalid-destination-url.yml //go:embed testdata/destination-url-not-rtmp.yml
var configInvalidDestinationURL []byte var configDestinationURLNotRTMP []byte
//go:embed testdata/destination-url-not-valid.yml
var configDestinationURLNotValid []byte
//go:embed testdata/multiple-invalid-destination-urls.yml //go:embed testdata/multiple-invalid-destination-urls.yml
var configMultipleInvalidDestinationURLs []byte var configMultipleInvalidDestinationURLs []byte
@ -120,14 +123,19 @@ func TestConfigServiceReadConfig(t *testing.T) {
}, },
}, },
{ {
name: "invalid destination URL", name: "destination URL is not rtmp scheme",
configBytes: configInvalidDestinationURL, configBytes: configDestinationURLNotRTMP,
wantErr: "destination URL must start with rtmp://", wantErr: "destination URL must be an RTMP URL",
},
{
name: "destination URL is not valid",
configBytes: configDestinationURLNotValid,
wantErr: `invalid destination URL: parse "rtmp://rtmp.example.com/%%+": invalid URL escape "%%+"`,
}, },
{ {
name: "multiple invalid destination URLs", name: "multiple invalid destination URLs",
configBytes: configMultipleInvalidDestinationURLs, configBytes: configMultipleInvalidDestinationURLs,
wantErr: "destination URL must start with rtmp://\ndestination URL must start with rtmp://", wantErr: "destination URL must be an RTMP URL\ndestination URL must be an RTMP URL",
}, },
} }

View File

@ -0,0 +1,6 @@
---
logfile:
enabled: true
path: test.log
destinations:
- url: rtmp://rtmp.example.com/%%+