add destFingerprint parameter (#6106)

this allows to validate self-signed certificates of forward
destinations.
This commit is contained in:
Alessandro Ros
2026-08-18 09:35:37 +02:00
committed by GitHub
parent b39d0af7f1
commit b80737c122
19 changed files with 151 additions and 54 deletions
+2
View File
@@ -1269,6 +1269,8 @@ components:
properties: properties:
dest: dest:
type: string type: string
destFingerprint:
type: string
whipBearerToken: whipBearerToken:
type: string type: string
+23 -1
View File
@@ -28,8 +28,16 @@ We support forwarding streams by using the WebRTC protocol and the WHIP extensio
paths: paths:
mypath: mypath:
forward: forward:
# use whip:// for HTTP and whips:// for HTTPS.
- dest: whip://host:port/mystream/whip - dest: whip://host:port/mystream/whip
whipBearerToken: mytoken # If the destination is HTTPS and the destination TLS certificate is self-signed
# or invalid, you can provide the fingerprint of the certificate in order to
# validate it anyway. It can be obtained by running:
# openssl s_client -connect dest_ip:dest_port </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
# openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
destFingerprint:
# Token to insert in the Authorization: Bearer header.
whipBearerToken: ""
``` ```
If the remote server is a _MediaMTX_ instance, remember to add a `/whip` suffix after the stream name, since in _MediaMTX_ [it's part of the WHIP URL](../3-publish/05-webrtc-clients.md). If the remote server is a _MediaMTX_ instance, remember to add a `/whip` suffix after the stream name, since in _MediaMTX_ [it's part of the WHIP URL](../3-publish/05-webrtc-clients.md).
@@ -42,7 +50,14 @@ Add the target URL inside `dest` of a `forward` entry:
paths: paths:
mypath: mypath:
forward: forward:
# Use rtsp:// for plain RTSP and rtsps:// for encrypted RTSP.
- dest: rtsp://user:pass@host:port/path - dest: rtsp://user:pass@host:port/path
# If the destination is RTSPS and the destination TLS certificate is self-signed
# or invalid, you can provide the fingerprint of the certificate in order to
# validate it anyway. It can be obtained by running:
# openssl s_client -connect dest_ip:dest_port </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
# openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
destFingerprint:
``` ```
## RTMP ## RTMP
@@ -53,7 +68,14 @@ Add the target URL inside `dest` of a `forward` entry:
paths: paths:
mypath: mypath:
forward: forward:
# Use rtmp:// for plain RTMP and rtmps:// for encrypted RTMP.
- dest: rtmp://user:pass@host:port/path#streamKey - dest: rtmp://user:pass@host:port/path#streamKey
# If the destination is RTMPS and the destination TLS certificate is self-signed
# or invalid, you can provide the fingerprint of the certificate in order to
# validate it anyway. It can be obtained by running:
# openssl s_client -connect dest_ip:dest_port </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
# openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
destFingerprint:
``` ```
## FFmpeg ## FFmpeg
+1 -1
View File
@@ -103,7 +103,7 @@ paths:
source: rtsp+http://standard-rtsp-url source: rtsp+http://standard-rtsp-url
``` ```
There are also the `rtsps+http`, `rtsp+ws`, `rtsps+ws` schemas to handle any variant. There are also the `rtsps+http`, `rtsp+ws`, `rtsps+ws` schemes to handle any variant.
## MPEG-TS inside RTSP ## MPEG-TS inside RTSP
+7 -1
View File
@@ -10,8 +10,14 @@ In order to ingest a WebRTC stream from a remote server, add the corresponding W
```yml ```yml
paths: paths:
proxied: proxied:
# url of the source stream. Use whep:// for HTTP and wheps:// for HTTPS # Use whep:// for HTTP and wheps:// for HTTPS.
source: whep://host:port/path source: whep://host:port/path
# If the source is HTTPS and the source TLS certificate is self-signed
# or invalid, you can provide the fingerprint of the certificate in order to
# validate it anyway. It can be obtained by running:
# openssl s_client -connect source_ip:source_port </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
# openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
sourceFingerprint:
# Token to insert in the Authorization: Bearer header. # Token to insert in the Authorization: Bearer header.
whepBearerToken: "" whepBearerToken: ""
``` ```
@@ -11,7 +11,14 @@ Most IP cameras expose their video stream by using a RTSP server that is embedde
```yml ```yml
paths: paths:
proxied: proxied:
# Use rtsp:// for plain RTSP and rtsps:// for encrypted RTSP.
source: rtsp://user:pass@host:port/path source: rtsp://user:pass@host:port/path
# If the source is RTSPS and the source TLS certificate is self-signed
# or invalid, you can provide the fingerprint of the certificate in order to
# validate it anyway. It can be obtained by running:
# openssl s_client -connect source_ip:source_port </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
# openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
sourceFingerprint:
``` ```
If username or password contain special characters (like ?, :, etc), they need to be [url-encoded](https://www.urlencoder.org/). If username or password contain special characters (like ?, :, etc), they need to be [url-encoded](https://www.urlencoder.org/).
@@ -10,7 +10,14 @@ You can use _MediaMTX_ to connect to one or several existing RTMP servers and re
```yml ```yml
paths: paths:
proxied: proxied:
# Use rtmp:// for plain RTMP and rtmps:// for encrypted RTMP.
source: rtmp://user:pass@host:port/path#streamKey source: rtmp://user:pass@host:port/path#streamKey
# If the source is RTMPS and the source TLS certificate is self-signed
# or invalid, you can provide the fingerprint of the certificate in order to
# validate it anyway. It can be obtained by running:
# openssl s_client -connect source_ip:source_port </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
# openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
sourceFingerprint:
``` ```
If username or password contain special characters (like ?, :, etc), they need to be [url-encoded](https://www.urlencoder.org/). If username or password contain special characters (like ?, :, etc), they need to be [url-encoded](https://www.urlencoder.org/).
@@ -11,7 +11,14 @@ HLS is a streaming protocol that works by splitting streams into segments, and b
```yml ```yml
paths: paths:
proxied: proxied:
# Use http:// for plain HTTP and https:// for HTTPS.
source: http://user:pass@host:port/path source: http://user:pass@host:port/path
# If the source is HTTPS and the source TLS certificate is self-signed
# or invalid, you can provide the fingerprint of the certificate in order to
# validate it anyway. It can be obtained by running:
# openssl s_client -connect source_ip:source_port </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
# openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
sourceFingerprint:
``` ```
If username or password contain special characters (like ?, :, etc), they need to be [url-encoded](https://www.urlencoder.org/). If username or password contain special characters (like ?, :, etc), they need to be [url-encoded](https://www.urlencoder.org/).
+3 -3
View File
@@ -71,7 +71,7 @@ func TestForward(t *testing.T) {
ID: whipID, ID: whipID,
Pos: 2, Pos: 2,
Created: time.Date(2026, 6, 18, 9, 1, 0, 0, time.UTC), Created: time.Date(2026, 6, 18, 9, 1, 0, 0, time.UTC),
Conf: conf.ForwardDest{Dest: "whip://localhost/live/stream/whip", WhipBearerToken: "mytoken"}, Conf: conf.ForwardDest{Dest: "whip://localhost/live/stream/whip", WHIPBearerToken: "mytoken"},
Protocol: defs.APIForwardDestProtocolWHIP, Protocol: defs.APIForwardDestProtocolWHIP,
State: defs.APIForwardDestStateForwarding, State: defs.APIForwardDestStateForwarding,
OutboundBytes: 456, OutboundBytes: 456,
@@ -117,7 +117,7 @@ func TestForward(t *testing.T) {
ID: whipID, ID: whipID,
Pos: 2, Pos: 2,
Created: time.Date(2026, 6, 18, 9, 1, 0, 0, time.UTC), Created: time.Date(2026, 6, 18, 9, 1, 0, 0, time.UTC),
Conf: conf.ForwardDest{Dest: "whip://localhost/live/stream/whip", WhipBearerToken: "mytoken"}, Conf: conf.ForwardDest{Dest: "whip://localhost/live/stream/whip", WHIPBearerToken: "mytoken"},
Protocol: defs.APIForwardDestProtocolWHIP, Protocol: defs.APIForwardDestProtocolWHIP,
State: defs.APIForwardDestStateForwarding, State: defs.APIForwardDestStateForwarding,
OutboundBytes: 456, OutboundBytes: 456,
@@ -128,7 +128,7 @@ func TestForward(t *testing.T) {
httpRequest(t, hc, http.MethodGet, httpRequest(t, hc, http.MethodGet,
"http://localhost:9997/v3/paths/forward/get?path=my%2Fnested%2Fstream&id="+whipID.String(), nil, &item) "http://localhost:9997/v3/paths/forward/get?path=my%2Fnested%2Fstream&id="+whipID.String(), nil, &item)
require.Equal(t, "whip://localhost/live/stream/whip", item.Conf.Dest) require.Equal(t, "whip://localhost/live/stream/whip", item.Conf.Dest)
require.Equal(t, "mytoken", item.Conf.WhipBearerToken) require.Equal(t, "mytoken", item.Conf.WHIPBearerToken)
require.Equal(t, defs.APIForwardDestProtocolWHIP, item.Protocol) require.Equal(t, defs.APIForwardDestProtocolWHIP, item.Protocol)
require.Equal(t, defs.APIForwardDestStateForwarding, item.State) require.Equal(t, defs.APIForwardDestStateForwarding, item.State)
require.Equal(t, uint64(456), item.OutboundBytes) require.Equal(t, uint64(456), item.OutboundBytes)
+1
View File
@@ -890,6 +890,7 @@ func TestConfErrors(t *testing.T) {
" mypath:\n" + " mypath:\n" +
" forward:\n" + " forward:\n" +
" - dest: whip://localhost/stream/whip\n" + " - dest: whip://localhost/stream/whip\n" +
" destFingerprint: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n" +
" whipBearerToken: mytoken\n", " whipBearerToken: mytoken\n",
"", "",
}, },
+2 -1
View File
@@ -9,7 +9,8 @@ import (
// ForwardDest is a destination to which a path is forwarded. // ForwardDest is a destination to which a path is forwarded.
type ForwardDest struct { type ForwardDest struct {
Dest string `json:"dest"` Dest string `json:"dest"`
WhipBearerToken string `json:"whipBearerToken"` DestFingerprint string `json:"destFingerprint"`
WHIPBearerToken string `json:"whipBearerToken"`
} }
func validateForwardDest(dest string) (*url.URL, error) { func validateForwardDest(dest string) (*url.URL, error) {
+2 -2
View File
@@ -538,7 +538,7 @@ func TestPathForwardWHIP(t *testing.T) {
require.Len(t, list.Items, 1) require.Len(t, list.Items, 1)
added := list.Items[0] added := list.Items[0]
require.Equal(t, dest, added.Conf.Dest) require.Equal(t, dest, added.Conf.Dest)
require.Equal(t, bearerToken, added.Conf.WhipBearerToken) require.Equal(t, bearerToken, added.Conf.WHIPBearerToken)
require.Equal(t, defs.APIForwardDestProtocolWHIP, added.Protocol) require.Equal(t, defs.APIForwardDestProtocolWHIP, added.Protocol)
require.Equal(t, 1, added.Pos) require.Equal(t, 1, added.Pos)
@@ -550,7 +550,7 @@ func TestPathForwardWHIP(t *testing.T) {
"http://localhost:9997/v3/paths/forward/get?path=source&id="+added.ID.String(), nil, &item) "http://localhost:9997/v3/paths/forward/get?path=source&id="+added.ID.String(), nil, &item)
return item.State == defs.APIForwardDestStateForwarding && return item.State == defs.APIForwardDestStateForwarding &&
item.Protocol == defs.APIForwardDestProtocolWHIP && item.Protocol == defs.APIForwardDestProtocolWHIP &&
item.Conf.WhipBearerToken == bearerToken && item.Conf.WHIPBearerToken == bearerToken &&
item.OutboundBytes > 0 item.OutboundBytes > 0
}, 5*time.Second, 100*time.Millisecond) }, 5*time.Second, 100*time.Millisecond)
} }
+13 -10
View File
@@ -185,19 +185,21 @@ func (h *DestHandler) runOnce(strm *stream.Stream) error {
switch h.protocol { switch h.protocol {
case defs.APIForwardDestProtocolRTMP, defs.APIForwardDestProtocolRTMPS: case defs.APIForwardDestProtocolRTMP, defs.APIForwardDestProtocolRTMPS:
dest = &forwardrtmp.Dest{ dest = &forwardrtmp.Dest{
Stream: strm, Stream: strm,
Dest: resolvedDest, Dest: resolvedDest,
WriteTimeout: h.WriteTimeout, DestFingerprint: h.Conf.DestFingerprint,
Parent: h, WriteTimeout: h.WriteTimeout,
Parent: h,
} }
case defs.APIForwardDestProtocolRTSP, defs.APIForwardDestProtocolRTSPS: case defs.APIForwardDestProtocolRTSP, defs.APIForwardDestProtocolRTSPS:
dest = &forwardrtsp.Dest{ dest = &forwardrtsp.Dest{
Stream: strm, Stream: strm,
Dest: resolvedDest, Dest: resolvedDest,
ReadTimeout: h.ReadTimeout, DestFingerprint: h.Conf.DestFingerprint,
WriteTimeout: h.WriteTimeout, ReadTimeout: h.ReadTimeout,
Parent: h, WriteTimeout: h.WriteTimeout,
Parent: h,
} }
case defs.APIForwardDestProtocolSRT: case defs.APIForwardDestProtocolSRT:
@@ -213,8 +215,9 @@ func (h *DestHandler) runOnce(strm *stream.Stream) error {
dest = &forwardwebrtc.Dest{ dest = &forwardwebrtc.Dest{
Stream: strm, Stream: strm,
Dest: resolvedDest, Dest: resolvedDest,
DestFingerprint: h.Conf.DestFingerprint,
ReadTimeout: h.ReadTimeout, ReadTimeout: h.ReadTimeout,
WhipBearerToken: h.Conf.WhipBearerToken, BearerToken: h.Conf.WHIPBearerToken,
Parent: h, Parent: h,
} }
+1 -1
View File
@@ -75,7 +75,7 @@ func (m *Manager) ReloadConf(forward conf.Forward) {
toClose := make([]*DestHandler, 0) toClose := make([]*DestHandler, 0)
for i, dest := range forward { for i, dest := range forward {
if i < len(m.destHandlers) && m.destHandlers[i].Conf.Dest == dest.Dest { if i < len(m.destHandlers) && m.destHandlers[i].Conf == dest {
newHandlers[i] = m.destHandlers[i] newHandlers[i] = m.destHandlers[i]
} else { } else {
if i < len(m.destHandlers) { if i < len(m.destHandlers) {
+33 -12
View File
@@ -83,6 +83,7 @@ func TestManagerReloadConf(t *testing.T) {
Forward: conf.Forward{ Forward: conf.Forward{
{Dest: "rtmp://localhost:5788/app/stream"}, {Dest: "rtmp://localhost:5788/app/stream"},
{Dest: "rtsp://localhost:5789/stream"}, {Dest: "rtsp://localhost:5789/stream"},
{Dest: "whip://localhost:5790/teststream/whip", WHIPBearerToken: "mytoken"},
}, },
Parent: test.NilLogger, Parent: test.NilLogger,
} }
@@ -126,13 +127,25 @@ func TestManagerReloadConf(t *testing.T) {
Protocol: "rtsp", Protocol: "rtsp",
State: list1.Items[1].State, State: list1.Items[1].State,
}, },
{
ID: list1.Items[2].ID,
Pos: 3,
Created: list1.Items[2].Created,
Conf: conf.ForwardDest{
Dest: "whip://localhost:5790/teststream/whip",
WHIPBearerToken: "mytoken",
},
Protocol: "whip",
State: list1.Items[2].State,
LastError: list1.Items[2].LastError,
},
}, },
}, list1) }, list1)
m.ReloadConf(conf.Forward{ m.ReloadConf(conf.Forward{
{Dest: "rtmp://localhost:5788/app/stream"}, // unchanged {Dest: "rtmp://localhost:5788/app/stream"}, // unchanged
{Dest: "whip://localhost:5790/teststream/whip", WhipBearerToken: "mytoken"}, {Dest: "rtsp://localhost:5789/stream", DestFingerprint: "fingerprint"}, // changed params
{Dest: "rtsp://localhost:5789/stream"}, {Dest: "whip://localhost:5790/teststream/whip", WHIPBearerToken: "othertoken"},
}) })
list2 := m.APIList() list2 := m.APIList()
@@ -152,23 +165,31 @@ func TestManagerReloadConf(t *testing.T) {
Pos: 2, Pos: 2,
Created: list2.Items[1].Created, Created: list2.Items[1].Created,
Conf: conf.ForwardDest{ Conf: conf.ForwardDest{
Dest: "whip://localhost:5790/teststream/whip", Dest: "rtsp://localhost:5789/stream",
WhipBearerToken: "mytoken", DestFingerprint: "fingerprint",
}, },
Protocol: "whip", Protocol: "rtsp",
State: list2.Items[1].State, State: list2.Items[1].State,
LastError: list2.Items[1].LastError, LastError: list2.Items[1].LastError,
}, },
{ {
ID: list2.Items[2].ID, ID: list2.Items[2].ID,
Pos: 3, Pos: 3,
Created: list2.Items[2].Created, Created: list2.Items[2].Created,
Conf: conf.ForwardDest{Dest: "rtsp://localhost:5789/stream"}, Conf: conf.ForwardDest{
Protocol: "rtsp", Dest: "whip://localhost:5790/teststream/whip",
State: list2.Items[2].State, WHIPBearerToken: "othertoken",
},
Protocol: "whip",
State: list2.Items[2].State,
LastError: list2.Items[2].LastError,
}, },
}, },
}, list2) }, list2)
require.Equal(t, list1.Items[0].ID, list2.Items[0].ID)
require.NotEqual(t, list1.Items[1].ID, list2.Items[1].ID)
require.NotEqual(t, list1.Items[2].ID, list2.Items[2].ID)
}) })
} }
} }
+9 -6
View File
@@ -17,6 +17,7 @@ import (
"github.com/bluenviron/mediamtx/internal/conf" "github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/logger"
rtmpprotocol "github.com/bluenviron/mediamtx/internal/protocols/rtmp" rtmpprotocol "github.com/bluenviron/mediamtx/internal/protocols/rtmp"
ptls "github.com/bluenviron/mediamtx/internal/protocols/tls"
"github.com/bluenviron/mediamtx/internal/stream" "github.com/bluenviron/mediamtx/internal/stream"
) )
@@ -65,10 +66,11 @@ func fourCCList(desc *description.Session) amf0.StrictArray {
// Dest is a RTMP forward destination. // Dest is a RTMP forward destination.
type Dest struct { type Dest struct {
Stream *stream.Stream Stream *stream.Stream
Dest string Dest string
WriteTimeout conf.Duration DestFingerprint string
Parent logger.Writer WriteTimeout conf.Duration
Parent logger.Writer
mutex sync.RWMutex mutex sync.RWMutex
outboundBytesFunc func() uint64 outboundBytesFunc func() uint64
@@ -98,8 +100,9 @@ func (d *Dest) Run(ctx context.Context) error {
} }
conn := &gortmplib.Client{ conn := &gortmplib.Client{
URL: u, URL: u,
Publish: true, Publish: true,
TLSConfig: ptls.MakeConfig(d.DestFingerprint),
} }
err = conn.Initialize(ctx) err = conn.Initialize(ctx)
+8 -5
View File
@@ -13,17 +13,19 @@ import (
"github.com/bluenviron/mediamtx/internal/conf" "github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/logger"
ptls "github.com/bluenviron/mediamtx/internal/protocols/tls"
"github.com/bluenviron/mediamtx/internal/stream" "github.com/bluenviron/mediamtx/internal/stream"
"github.com/bluenviron/mediamtx/internal/unit" "github.com/bluenviron/mediamtx/internal/unit"
) )
// Dest is a RTSP forward destination. // Dest is a RTSP forward destination.
type Dest struct { type Dest struct {
Stream *stream.Stream Stream *stream.Stream
Dest string Dest string
ReadTimeout conf.Duration DestFingerprint string
WriteTimeout conf.Duration ReadTimeout conf.Duration
Parent logger.Writer WriteTimeout conf.Duration
Parent logger.Writer
mutex sync.RWMutex mutex sync.RWMutex
outboundBytesFunc func() uint64 outboundBytesFunc func() uint64
@@ -59,6 +61,7 @@ func (d *Dest) Run(ctx context.Context) error {
Host: u.Host, Host: u.Host,
ReadTimeout: time.Duration(d.ReadTimeout), ReadTimeout: time.Duration(d.ReadTimeout),
WriteTimeout: time.Duration(d.WriteTimeout), WriteTimeout: time.Duration(d.WriteTimeout),
TLSConfig: ptls.MakeConfig(d.DestFingerprint),
OnRequest: func(req *base.Request) { OnRequest: func(req *base.Request) {
d.Log(logger.Debug, "[c->s] %v", req) d.Log(logger.Debug, "[c->s] %v", req)
}, },
+14 -6
View File
@@ -12,6 +12,7 @@ import (
"github.com/bluenviron/mediamtx/internal/conf" "github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/logger"
ptls "github.com/bluenviron/mediamtx/internal/protocols/tls"
pwebrtc "github.com/bluenviron/mediamtx/internal/protocols/webrtc" pwebrtc "github.com/bluenviron/mediamtx/internal/protocols/webrtc"
"github.com/bluenviron/mediamtx/internal/protocols/whip" "github.com/bluenviron/mediamtx/internal/protocols/whip"
"github.com/bluenviron/mediamtx/internal/stream" "github.com/bluenviron/mediamtx/internal/stream"
@@ -21,8 +22,9 @@ import (
type Dest struct { type Dest struct {
Stream *stream.Stream Stream *stream.Stream
Dest string Dest string
DestFingerprint string
ReadTimeout conf.Duration ReadTimeout conf.Duration
WhipBearerToken string BearerToken string
Parent logger.Writer Parent logger.Writer
mutex sync.RWMutex mutex sync.RWMutex
@@ -56,8 +58,6 @@ func (d *Dest) Run(ctx context.Context) error {
u.Scheme = strings.Replace(u.Scheme, "whip", "http", 1) u.Scheme = strings.Replace(u.Scheme, "whip", "http", 1)
hc := &http.Client{Timeout: time.Duration(d.ReadTimeout)}
r := &stream.Reader{Parent: d} r := &stream.Reader{Parent: d}
pc := &pwebrtc.PeerConnection{} pc := &pwebrtc.PeerConnection{}
@@ -66,14 +66,22 @@ func (d *Dest) Run(ctx context.Context) error {
return err return err
} }
tr := &http.Transport{
TLSClientConfig: ptls.MakeConfig(d.DestFingerprint),
}
defer tr.CloseIdleConnections()
client := &whip.Client{ client := &whip.Client{
URL: u, URL: u,
Publish: true, Publish: true,
OutboundTracks: pc.OutboundTracks, OutboundTracks: pc.OutboundTracks,
OutboundDataChannels: pc.OutboundDataChannels, OutboundDataChannels: pc.OutboundDataChannels,
HTTPClient: hc, HTTPClient: &http.Client{
BearerToken: d.WhipBearerToken, Timeout: time.Duration(d.ReadTimeout),
Log: d, Transport: tr,
},
BearerToken: d.BearerToken,
Log: d,
} }
if err = client.Initialize(ctx); err != nil { if err = client.Initialize(ctx); err != nil {
return err return err
+5 -5
View File
@@ -150,11 +150,11 @@ func TestDest(t *testing.T) {
defer cancel() defer cancel()
dest := &forwardwebrtc.Dest{ dest := &forwardwebrtc.Dest{
Stream: strm, Stream: strm,
Dest: destURL, Dest: destURL,
ReadTimeout: conf.Duration(10 * time.Second), ReadTimeout: conf.Duration(10 * time.Second),
WhipBearerToken: bearerToken, BearerToken: bearerToken,
Parent: test.NilLogger, Parent: test.NilLogger,
} }
done := make(chan error, 1) done := make(chan error, 1)
+6
View File
@@ -550,6 +550,12 @@ pathDefaults:
# * $MTX_PATH: path name # * $MTX_PATH: path name
# * $G1, $G2, ...: regular expression groups, if path name is a regular expression. # * $G1, $G2, ...: regular expression groups, if path name is a regular expression.
# - dest: # - dest:
# # If the destination TLS certificate is self-signed
# # or invalid, you can provide the fingerprint of the certificate in order to
# # validate it anyway. It can be obtained by running:
# # openssl s_client -connect dest_ip:dest_port </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
# # openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
# destFingerprint:
# # Token to insert in the Authorization: Bearer header when using WHIP. # # Token to insert in the Authorization: Bearer header when using WHIP.
# whipBearerToken: "" # whipBearerToken: ""