mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 23:26:54 +08:00
move most errors into pkg/liberrors (#408)
This commit is contained in:
12
client.go
12
client.go
@@ -713,7 +713,7 @@ func (c *Client) checkState(allowed map[clientState]struct{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) trySwitchingProtocol() error {
|
func (c *Client) trySwitchingProtocol() error {
|
||||||
c.OnTransportSwitch(fmt.Errorf("no UDP packets received, switching to TCP"))
|
c.OnTransportSwitch(liberrors.ErrClientSwitchToTCP{})
|
||||||
|
|
||||||
prevConnURL := c.connURL
|
prevConnURL := c.connURL
|
||||||
prevBaseURL := c.baseURL
|
prevBaseURL := c.baseURL
|
||||||
@@ -752,7 +752,7 @@ func (c *Client) trySwitchingProtocol() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) trySwitchingProtocol2(medi *description.Media, baseURL *url.URL) (*base.Response, error) {
|
func (c *Client) trySwitchingProtocol2(medi *description.Media, baseURL *url.URL) (*base.Response, error) {
|
||||||
c.OnTransportSwitch(fmt.Errorf("switching to TCP because server requested it"))
|
c.OnTransportSwitch(liberrors.ErrClientSwitchToTCP2{})
|
||||||
|
|
||||||
prevConnURL := c.connURL
|
prevConnURL := c.connURL
|
||||||
|
|
||||||
@@ -939,7 +939,7 @@ func (c *Client) do(req *base.Request, skipResponse bool) (*base.Response, error
|
|||||||
|
|
||||||
sender, err := auth.NewSender(res.Header["WWW-Authenticate"], user, pass)
|
sender, err := auth.NewSender(res.Header["WWW-Authenticate"], user, pass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to setup authentication: %s", err)
|
return nil, liberrors.ErrClientAuthSetup{Err: err}
|
||||||
}
|
}
|
||||||
c.sender = sender
|
c.sender = sender
|
||||||
|
|
||||||
@@ -1142,13 +1142,13 @@ func (c *Client) doDescribe(u *url.URL) (*description.Session, *base.Response, e
|
|||||||
var ssd sdp.SessionDescription
|
var ssd sdp.SessionDescription
|
||||||
err = ssd.Unmarshal(res.Body)
|
err = ssd.Unmarshal(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, liberrors.ErrClientSDPInvalid{Err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
var desc description.Session
|
var desc description.Session
|
||||||
err = desc.Unmarshal(&ssd)
|
err = desc.Unmarshal(&ssd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, liberrors.ErrClientSDPInvalid{Err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
baseURL, err := findBaseURL(&ssd, res, u)
|
baseURL, err := findBaseURL(&ssd, res, u)
|
||||||
@@ -1348,7 +1348,7 @@ func (c *Client) doSetup(
|
|||||||
// switch transport automatically
|
// switch transport automatically
|
||||||
if res.StatusCode == base.StatusUnsupportedTransport &&
|
if res.StatusCode == base.StatusUnsupportedTransport &&
|
||||||
c.effectiveTransport == nil {
|
c.effectiveTransport == nil {
|
||||||
c.OnTransportSwitch(fmt.Errorf("switching to TCP because server requested it"))
|
c.OnTransportSwitch(liberrors.ErrClientSwitchToTCP2{})
|
||||||
v := TransportTCP
|
v := TransportTCP
|
||||||
c.effectiveTransport = &v
|
c.effectiveTransport = &v
|
||||||
return c.doSetup(baseURL, medi, 0, 0)
|
return c.doSetup(baseURL, medi, 0, 0)
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
package gortsplib
|
package gortsplib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pion/rtcp"
|
"github.com/pion/rtcp"
|
||||||
@@ -95,14 +94,7 @@ func (ct *clientFormat) writePacketRTP(byts []byte, pkt *rtp.Packet, ntp time.Ti
|
|||||||
func (ct *clientFormat) readRTPUDP(pkt *rtp.Packet) {
|
func (ct *clientFormat) readRTPUDP(pkt *rtp.Packet) {
|
||||||
packets, lost := ct.udpReorderer.Process(pkt)
|
packets, lost := ct.udpReorderer.Process(pkt)
|
||||||
if lost != 0 {
|
if lost != 0 {
|
||||||
ct.cm.c.OnPacketLost(fmt.Errorf("%d RTP %s lost",
|
ct.cm.c.OnPacketLost(liberrors.ErrClientRTPPacketsLost{Lost: lost})
|
||||||
lost,
|
|
||||||
func() string {
|
|
||||||
if lost == 1 {
|
|
||||||
return "packet"
|
|
||||||
}
|
|
||||||
return "packets"
|
|
||||||
}()))
|
|
||||||
// do not return
|
// do not return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,14 +114,7 @@ func (ct *clientFormat) readRTPUDP(pkt *rtp.Packet) {
|
|||||||
func (ct *clientFormat) readRTPTCP(pkt *rtp.Packet) {
|
func (ct *clientFormat) readRTPTCP(pkt *rtp.Packet) {
|
||||||
lost := ct.tcpLossDetector.Process(pkt)
|
lost := ct.tcpLossDetector.Process(pkt)
|
||||||
if lost != 0 {
|
if lost != 0 {
|
||||||
ct.cm.c.OnPacketLost(fmt.Errorf("%d RTP %s lost",
|
ct.cm.c.OnPacketLost(liberrors.ErrClientRTPPacketsLost{Lost: lost})
|
||||||
lost,
|
|
||||||
func() string {
|
|
||||||
if lost == 1 {
|
|
||||||
return "packet"
|
|
||||||
}
|
|
||||||
return "packets"
|
|
||||||
}()))
|
|
||||||
// do not return
|
// do not return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
package gortsplib
|
package gortsplib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -193,7 +192,7 @@ func (cm *clientMedia) readRTPTCPPlay(payload []byte) {
|
|||||||
|
|
||||||
forma, ok := cm.formats[pkt.PayloadType]
|
forma, ok := cm.formats[pkt.PayloadType]
|
||||||
if !ok {
|
if !ok {
|
||||||
cm.c.OnDecodeError(fmt.Errorf("received RTP packet with unknown format: %d", pkt.PayloadType))
|
cm.c.OnDecodeError(liberrors.ErrClientRTPPacketUnknownPayloadType{PayloadType: pkt.PayloadType})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,8 +204,7 @@ func (cm *clientMedia) readRTCPTCPPlay(payload []byte) {
|
|||||||
atomic.StoreInt64(cm.c.tcpLastFrameTime, now.Unix())
|
atomic.StoreInt64(cm.c.tcpLastFrameTime, now.Unix())
|
||||||
|
|
||||||
if len(payload) > udpMaxPayloadSize {
|
if len(payload) > udpMaxPayloadSize {
|
||||||
cm.c.OnDecodeError(fmt.Errorf("RTCP packet size (%d) is greater than maximum allowed (%d)",
|
cm.c.OnDecodeError(liberrors.ErrClientRTCPPacketTooBig{L: len(payload), Max: udpMaxPayloadSize})
|
||||||
len(payload), udpMaxPayloadSize))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,8 +231,7 @@ func (cm *clientMedia) readRTPTCPRecord(_ []byte) {
|
|||||||
|
|
||||||
func (cm *clientMedia) readRTCPTCPRecord(payload []byte) {
|
func (cm *clientMedia) readRTCPTCPRecord(payload []byte) {
|
||||||
if len(payload) > udpMaxPayloadSize {
|
if len(payload) > udpMaxPayloadSize {
|
||||||
cm.c.OnDecodeError(fmt.Errorf("RTCP packet size (%d) is greater than maximum allowed (%d)",
|
cm.c.OnDecodeError(liberrors.ErrClientRTCPPacketTooBig{L: len(payload), Max: udpMaxPayloadSize})
|
||||||
len(payload), udpMaxPayloadSize))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +252,7 @@ func (cm *clientMedia) readRTPUDPPlay(payload []byte) {
|
|||||||
atomic.AddUint64(cm.c.BytesReceived, uint64(plen))
|
atomic.AddUint64(cm.c.BytesReceived, uint64(plen))
|
||||||
|
|
||||||
if plen == (udpMaxPayloadSize + 1) {
|
if plen == (udpMaxPayloadSize + 1) {
|
||||||
cm.c.OnDecodeError(fmt.Errorf("RTP packet is too big to be read with UDP"))
|
cm.c.OnDecodeError(liberrors.ErrClientRTPPacketTooBigUDP{})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +265,7 @@ func (cm *clientMedia) readRTPUDPPlay(payload []byte) {
|
|||||||
|
|
||||||
forma, ok := cm.formats[pkt.PayloadType]
|
forma, ok := cm.formats[pkt.PayloadType]
|
||||||
if !ok {
|
if !ok {
|
||||||
cm.c.OnDecodeError(fmt.Errorf("received RTP packet with unknown format: %d", pkt.PayloadType))
|
cm.c.OnDecodeError(liberrors.ErrClientRTPPacketUnknownPayloadType{PayloadType: pkt.PayloadType})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +279,7 @@ func (cm *clientMedia) readRTCPUDPPlay(payload []byte) {
|
|||||||
atomic.AddUint64(cm.c.BytesReceived, uint64(plen))
|
atomic.AddUint64(cm.c.BytesReceived, uint64(plen))
|
||||||
|
|
||||||
if plen == (udpMaxPayloadSize + 1) {
|
if plen == (udpMaxPayloadSize + 1) {
|
||||||
cm.c.OnDecodeError(fmt.Errorf("RTCP packet is too big to be read with UDP"))
|
cm.c.OnDecodeError(liberrors.ErrClientRTCPPacketTooBigUDP{})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,7 +310,7 @@ func (cm *clientMedia) readRTCPUDPRecord(payload []byte) {
|
|||||||
atomic.AddUint64(cm.c.BytesReceived, uint64(plen))
|
atomic.AddUint64(cm.c.BytesReceived, uint64(plen))
|
||||||
|
|
||||||
if plen == (udpMaxPayloadSize + 1) {
|
if plen == (udpMaxPayloadSize + 1) {
|
||||||
cm.c.OnDecodeError(fmt.Errorf("RTCP packet is too big to be read with UDP"))
|
cm.c.OnDecodeError(liberrors.ErrClientRTCPPacketTooBigUDP{})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2896,13 +2896,13 @@ func TestClientPlayDecodeErrors(t *testing.T) {
|
|||||||
{"udp", "rtp invalid"},
|
{"udp", "rtp invalid"},
|
||||||
{"udp", "rtcp invalid"},
|
{"udp", "rtcp invalid"},
|
||||||
{"udp", "rtp packets lost"},
|
{"udp", "rtp packets lost"},
|
||||||
{"udp", "rtp unknown format"},
|
{"udp", "rtp unknown payload type"},
|
||||||
{"udp", "wrong ssrc"},
|
{"udp", "wrong ssrc"},
|
||||||
{"udp", "rtcp too big"},
|
{"udp", "rtcp too big"},
|
||||||
{"udp", "rtp too big"},
|
{"udp", "rtp too big"},
|
||||||
{"tcp", "rtp invalid"},
|
{"tcp", "rtp invalid"},
|
||||||
{"tcp", "rtcp invalid"},
|
{"tcp", "rtcp invalid"},
|
||||||
{"tcp", "rtp unknown format"},
|
{"tcp", "rtp unknown payload type"},
|
||||||
{"tcp", "wrong ssrc"},
|
{"tcp", "wrong ssrc"},
|
||||||
{"tcp", "rtcp too big"},
|
{"tcp", "rtcp too big"},
|
||||||
} {
|
} {
|
||||||
@@ -3077,7 +3077,7 @@ func TestClientPlayDecodeErrors(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
case ca.name == "rtp unknown format":
|
case ca.name == "rtp unknown payload type":
|
||||||
writeRTP(mustMarshalPacketRTP(&rtp.Packet{
|
writeRTP(mustMarshalPacketRTP(&rtp.Packet{
|
||||||
Header: rtp.Header{
|
Header: rtp.Header{
|
||||||
PayloadType: 111,
|
PayloadType: 111,
|
||||||
@@ -3140,8 +3140,8 @@ func TestClientPlayDecodeErrors(t *testing.T) {
|
|||||||
case ca.name == "rtcp invalid":
|
case ca.name == "rtcp invalid":
|
||||||
require.EqualError(t, err, "rtcp: packet too short")
|
require.EqualError(t, err, "rtcp: packet too short")
|
||||||
|
|
||||||
case ca.name == "rtp unknown format":
|
case ca.name == "rtp unknown payload type":
|
||||||
require.EqualError(t, err, "received RTP packet with unknown format: 111")
|
require.EqualError(t, err, "received RTP packet with unknown payload type: 111")
|
||||||
|
|
||||||
case ca.name == "wrong ssrc":
|
case ca.name == "wrong ssrc":
|
||||||
require.EqualError(t, err, "received packet with wrong SSRC 456, expected 123")
|
require.EqualError(t, err, "received packet with wrong SSRC 456, expected 123")
|
||||||
|
@@ -256,3 +256,94 @@ type ErrClientWriteQueueFull struct{}
|
|||||||
func (e ErrClientWriteQueueFull) Error() string {
|
func (e ErrClientWriteQueueFull) Error() string {
|
||||||
return "write queue is full"
|
return "write queue is full"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrClientRTPPacketsLost is an error that can be returned by a client.
|
||||||
|
type ErrClientRTPPacketsLost struct {
|
||||||
|
Lost int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (e ErrClientRTPPacketsLost) Error() string {
|
||||||
|
return fmt.Sprintf("%d RTP %s lost",
|
||||||
|
e.Lost,
|
||||||
|
func() string {
|
||||||
|
if e.Lost == 1 {
|
||||||
|
return "packet"
|
||||||
|
}
|
||||||
|
return "packets"
|
||||||
|
}())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrClientRTPPacketUnknownPayloadType is an error that can be returned by a client.
|
||||||
|
type ErrClientRTPPacketUnknownPayloadType struct {
|
||||||
|
PayloadType uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (e ErrClientRTPPacketUnknownPayloadType) Error() string {
|
||||||
|
return fmt.Sprintf("received RTP packet with unknown payload type: %d", e.PayloadType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrClientRTCPPacketTooBig is an error that can be returned by a client.
|
||||||
|
type ErrClientRTCPPacketTooBig struct {
|
||||||
|
L int
|
||||||
|
Max int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (e ErrClientRTCPPacketTooBig) Error() string {
|
||||||
|
return fmt.Sprintf("RTCP packet size (%d) is greater than maximum allowed (%d)",
|
||||||
|
e.L, e.Max)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrClientRTPPacketTooBigUDP is an error that can be returned by a client.
|
||||||
|
type ErrClientRTPPacketTooBigUDP struct{}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (e ErrClientRTPPacketTooBigUDP) Error() string {
|
||||||
|
return "RTP packet is too big to be read with UDP"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrClientRTCPPacketTooBigUDP is an error that can be returned by a client.
|
||||||
|
type ErrClientRTCPPacketTooBigUDP struct{}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (e ErrClientRTCPPacketTooBigUDP) Error() string {
|
||||||
|
return "RTCP packet is too big to be read with UDP"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrClientSwitchToTCP is an error that can be returned by a client.
|
||||||
|
type ErrClientSwitchToTCP struct{}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (e ErrClientSwitchToTCP) Error() string {
|
||||||
|
return "no UDP packets received, switching to TCP"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrClientSwitchToTCP2 is an error that can be returned by a client.
|
||||||
|
type ErrClientSwitchToTCP2 struct{}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (e ErrClientSwitchToTCP2) Error() string {
|
||||||
|
return "switching to TCP because server requested it"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrClientAuthSetup is an error that can be returned by a client.
|
||||||
|
type ErrClientAuthSetup struct {
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (e ErrClientAuthSetup) Error() string {
|
||||||
|
return fmt.Sprintf("unable to setup authentication: %s", e.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrClientSDPInvalid is an error that can be returned by a client.
|
||||||
|
type ErrClientSDPInvalid struct {
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (e ErrClientSDPInvalid) Error() string {
|
||||||
|
return fmt.Sprintf("invalid SDP: %v", e.Err)
|
||||||
|
}
|
||||||
|
@@ -4,17 +4,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/bluenviron/gortsplib/v4/pkg/base"
|
|
||||||
"github.com/bluenviron/gortsplib/v4/pkg/headers"
|
"github.com/bluenviron/gortsplib/v4/pkg/headers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrServerTerminated is an error that can be returned by a server.
|
// ErrServerTerminated is an error that can be returned by a server.
|
||||||
type ErrServerTerminated struct{}
|
type ErrServerTerminated = ErrClientTerminated
|
||||||
|
|
||||||
// Error implements the error interface.
|
|
||||||
func (e ErrServerTerminated) Error() string {
|
|
||||||
return "terminated"
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrServerSessionNotFound is an error that can be returned by a server.
|
// ErrServerSessionNotFound is an error that can be returned by a server.
|
||||||
type ErrServerSessionNotFound struct{}
|
type ErrServerSessionNotFound struct{}
|
||||||
@@ -61,42 +55,16 @@ func (e ErrServerInvalidPath) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ErrServerContentTypeMissing is an error that can be returned by a server.
|
// ErrServerContentTypeMissing is an error that can be returned by a server.
|
||||||
type ErrServerContentTypeMissing struct{}
|
type ErrServerContentTypeMissing = ErrClientContentTypeMissing
|
||||||
|
|
||||||
// Error implements the error interface.
|
|
||||||
func (e ErrServerContentTypeMissing) Error() string {
|
|
||||||
return "Content-Type header is missing"
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrServerContentTypeUnsupported is an error that can be returned by a server.
|
// ErrServerContentTypeUnsupported is an error that can be returned by a server.
|
||||||
type ErrServerContentTypeUnsupported struct {
|
type ErrServerContentTypeUnsupported = ErrClientContentTypeUnsupported
|
||||||
CT base.HeaderValue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error implements the error interface.
|
|
||||||
func (e ErrServerContentTypeUnsupported) Error() string {
|
|
||||||
return fmt.Sprintf("unsupported Content-Type header '%v'", e.CT)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrServerSDPInvalid is an error that can be returned by a server.
|
// ErrServerSDPInvalid is an error that can be returned by a server.
|
||||||
type ErrServerSDPInvalid struct {
|
type ErrServerSDPInvalid = ErrClientSDPInvalid
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error implements the error interface.
|
|
||||||
func (e ErrServerSDPInvalid) Error() string {
|
|
||||||
return fmt.Sprintf("invalid SDP: %v", e.Err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrServerTransportHeaderInvalid is an error that can be returned by a server.
|
// ErrServerTransportHeaderInvalid is an error that can be returned by a server.
|
||||||
type ErrServerTransportHeaderInvalid struct {
|
type ErrServerTransportHeaderInvalid = ErrClientTransportHeaderInvalid
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error implements the error interface.
|
|
||||||
func (e ErrServerTransportHeaderInvalid) Error() string {
|
|
||||||
return fmt.Sprintf("invalid transport header: %v", e.Err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrServerMediaAlreadySetup is an error that can be returned by a server.
|
// ErrServerMediaAlreadySetup is an error that can be returned by a server.
|
||||||
type ErrServerMediaAlreadySetup struct{}
|
type ErrServerMediaAlreadySetup struct{}
|
||||||
@@ -106,6 +74,14 @@ func (e ErrServerMediaAlreadySetup) Error() string {
|
|||||||
return "media has already been setup"
|
return "media has already been setup"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrServerMediaNotFound is an error that can be returned by a server.
|
||||||
|
type ErrServerMediaNotFound struct{}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (e ErrServerMediaNotFound) Error() string {
|
||||||
|
return "media not found"
|
||||||
|
}
|
||||||
|
|
||||||
// ErrServerTransportHeaderInvalidMode is an error that can be returned by a server.
|
// ErrServerTransportHeaderInvalidMode is an error that can be returned by a server.
|
||||||
type ErrServerTransportHeaderInvalidMode struct {
|
type ErrServerTransportHeaderInvalidMode struct {
|
||||||
Mode headers.TransportMode
|
Mode headers.TransportMode
|
||||||
@@ -245,25 +221,43 @@ func (e ErrServerSessionNotInUse) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ErrServerUnexpectedFrame is an error that can be returned by a server.
|
// ErrServerUnexpectedFrame is an error that can be returned by a server.
|
||||||
type ErrServerUnexpectedFrame struct{}
|
type ErrServerUnexpectedFrame = ErrClientUnexpectedFrame
|
||||||
|
|
||||||
// Error implements the error interface.
|
|
||||||
func (e ErrServerUnexpectedFrame) Error() string {
|
|
||||||
return "received unexpected interleaved frame"
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrServerUnexpectedResponse is an error that can be returned by a server.
|
// ErrServerUnexpectedResponse is an error that can be returned by a server.
|
||||||
type ErrServerUnexpectedResponse struct{}
|
type ErrServerUnexpectedResponse = ErrClientUnexpectedResponse
|
||||||
|
|
||||||
// Error implements the error interface.
|
|
||||||
func (e ErrServerUnexpectedResponse) Error() string {
|
|
||||||
return "received unexpected response"
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrServerWriteQueueFull is an error that can be returned by a server.
|
// ErrServerWriteQueueFull is an error that can be returned by a server.
|
||||||
type ErrServerWriteQueueFull struct{}
|
type ErrServerWriteQueueFull = ErrClientWriteQueueFull
|
||||||
|
|
||||||
|
// ErrServerRTPPacketsLost is an error that can be returned by a server.
|
||||||
|
type ErrServerRTPPacketsLost = ErrClientRTPPacketsLost
|
||||||
|
|
||||||
|
// ErrServerRTPPacketUnknownPayloadType is an error that can be returned by a server.
|
||||||
|
type ErrServerRTPPacketUnknownPayloadType = ErrClientRTPPacketUnknownPayloadType
|
||||||
|
|
||||||
|
// ErrServerRTCPPacketTooBig is an error that can be returned by a server.
|
||||||
|
type ErrServerRTCPPacketTooBig = ErrClientRTCPPacketTooBig
|
||||||
|
|
||||||
|
// ErrServerRTPPacketTooBigUDP is an error that can be returned by a server.
|
||||||
|
type ErrServerRTPPacketTooBigUDP = ErrClientRTPPacketTooBigUDP
|
||||||
|
|
||||||
|
// ErrServerRTCPPacketTooBigUDP is an error that can be returned by a server.
|
||||||
|
type ErrServerRTCPPacketTooBigUDP = ErrClientRTCPPacketTooBigUDP
|
||||||
|
|
||||||
|
// ErrServerStreamClosed is an error that can be returned by a server.
|
||||||
|
type ErrServerStreamClosed struct{}
|
||||||
|
|
||||||
// Error implements the error interface.
|
// Error implements the error interface.
|
||||||
func (e ErrServerWriteQueueFull) Error() string {
|
func (e ErrServerStreamClosed) Error() string {
|
||||||
return "write queue is full"
|
return "stream is closed"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrServerPathNoSlash is an error that can be returned by a server.
|
||||||
|
type ErrServerPathNoSlash struct{}
|
||||||
|
|
||||||
|
// Error implements the error interface.
|
||||||
|
func (ErrServerPathNoSlash) Error() string {
|
||||||
|
return "path of a SETUP request must end with a slash. " +
|
||||||
|
"This typically happens when VLC fails a request, and then switches to an " +
|
||||||
|
"unsupported RTSP dialect"
|
||||||
}
|
}
|
||||||
|
@@ -459,7 +459,7 @@ func (s *Server) getMulticastIP() (net.IP, error) {
|
|||||||
return <-res, nil
|
return <-res, nil
|
||||||
|
|
||||||
case <-s.ctx.Done():
|
case <-s.ctx.Done():
|
||||||
return nil, fmt.Errorf("terminated")
|
return nil, liberrors.ErrServerTerminated{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1188,13 +1188,13 @@ func TestServerRecordDecodeErrors(t *testing.T) {
|
|||||||
{"udp", "rtp invalid"},
|
{"udp", "rtp invalid"},
|
||||||
{"udp", "rtcp invalid"},
|
{"udp", "rtcp invalid"},
|
||||||
{"udp", "rtp packets lost"},
|
{"udp", "rtp packets lost"},
|
||||||
{"udp", "rtp unknown format"},
|
{"udp", "rtp unknown payload type"},
|
||||||
{"udp", "wrong ssrc"},
|
{"udp", "wrong ssrc"},
|
||||||
{"udp", "rtcp too big"},
|
{"udp", "rtcp too big"},
|
||||||
{"udp", "rtp too big"},
|
{"udp", "rtp too big"},
|
||||||
{"tcp", "rtcp invalid"},
|
{"tcp", "rtcp invalid"},
|
||||||
{"tcp", "rtp packets lost"},
|
{"tcp", "rtp packets lost"},
|
||||||
{"tcp", "rtp unknown format"},
|
{"tcp", "rtp unknown payload type"},
|
||||||
{"tcp", "wrong ssrc"},
|
{"tcp", "wrong ssrc"},
|
||||||
{"tcp", "rtcp too big"},
|
{"tcp", "rtcp too big"},
|
||||||
} {
|
} {
|
||||||
@@ -1230,8 +1230,8 @@ func TestServerRecordDecodeErrors(t *testing.T) {
|
|||||||
case ca.name == "rtcp invalid":
|
case ca.name == "rtcp invalid":
|
||||||
require.EqualError(t, ctx.Error, "rtcp: packet too short")
|
require.EqualError(t, ctx.Error, "rtcp: packet too short")
|
||||||
|
|
||||||
case ca.name == "rtp unknown format":
|
case ca.name == "rtp unknown payload type":
|
||||||
require.EqualError(t, ctx.Error, "received RTP packet with unknown format: 111")
|
require.EqualError(t, ctx.Error, "received RTP packet with unknown payload type: 111")
|
||||||
|
|
||||||
case ca.name == "wrong ssrc":
|
case ca.name == "wrong ssrc":
|
||||||
require.EqualError(t, ctx.Error, "received packet with wrong SSRC 456, expected 123")
|
require.EqualError(t, ctx.Error, "received packet with wrong SSRC 456, expected 123")
|
||||||
@@ -1375,7 +1375,7 @@ func TestServerRecordDecodeErrors(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
case ca.name == "rtp unknown format":
|
case ca.name == "rtp unknown payload type":
|
||||||
writeRTP(mustMarshalPacketRTP(&rtp.Packet{
|
writeRTP(mustMarshalPacketRTP(&rtp.Packet{
|
||||||
Header: rtp.Header{
|
Header: rtp.Header{
|
||||||
PayloadType: 111,
|
PayloadType: 111,
|
||||||
|
@@ -44,9 +44,7 @@ func serverParseURLForPlay(u *url.URL) (string, string, string, error) {
|
|||||||
i := stringsReverseIndex(pathAndQuery, "/trackID=")
|
i := stringsReverseIndex(pathAndQuery, "/trackID=")
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
if !strings.HasSuffix(pathAndQuery, "/") {
|
if !strings.HasSuffix(pathAndQuery, "/") {
|
||||||
return "", "", "", fmt.Errorf("path of a SETUP request must end with a slash. " +
|
return "", "", "", liberrors.ErrServerPathNoSlash{}
|
||||||
"This typically happens when VLC fails a request, and then switches to an " +
|
|
||||||
"unsupported RTSP dialect")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
path, query := url.PathSplitQuery(pathAndQuery[:len(pathAndQuery)-1])
|
path, query := url.PathSplitQuery(pathAndQuery[:len(pathAndQuery)-1])
|
||||||
@@ -775,7 +773,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) (
|
|||||||
if medi == nil {
|
if medi == nil {
|
||||||
return &base.Response{
|
return &base.Response{
|
||||||
StatusCode: base.StatusBadRequest,
|
StatusCode: base.StatusBadRequest,
|
||||||
}, fmt.Errorf("media not found")
|
}, liberrors.ErrServerMediaNotFound{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := ss.setuppedMedias[medi]; ok {
|
if _, ok := ss.setuppedMedias[medi]; ok {
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
package gortsplib
|
package gortsplib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pion/rtcp"
|
"github.com/pion/rtcp"
|
||||||
"github.com/pion/rtp"
|
"github.com/pion/rtp"
|
||||||
|
|
||||||
"github.com/bluenviron/gortsplib/v4/pkg/format"
|
"github.com/bluenviron/gortsplib/v4/pkg/format"
|
||||||
|
"github.com/bluenviron/gortsplib/v4/pkg/liberrors"
|
||||||
"github.com/bluenviron/gortsplib/v4/pkg/rtcpreceiver"
|
"github.com/bluenviron/gortsplib/v4/pkg/rtcpreceiver"
|
||||||
"github.com/bluenviron/gortsplib/v4/pkg/rtplossdetector"
|
"github.com/bluenviron/gortsplib/v4/pkg/rtplossdetector"
|
||||||
"github.com/bluenviron/gortsplib/v4/pkg/rtpreorderer"
|
"github.com/bluenviron/gortsplib/v4/pkg/rtpreorderer"
|
||||||
@@ -65,14 +65,7 @@ func (sf *serverSessionFormat) stop() {
|
|||||||
func (sf *serverSessionFormat) readRTPUDP(pkt *rtp.Packet, now time.Time) {
|
func (sf *serverSessionFormat) readRTPUDP(pkt *rtp.Packet, now time.Time) {
|
||||||
packets, lost := sf.udpReorderer.Process(pkt)
|
packets, lost := sf.udpReorderer.Process(pkt)
|
||||||
if lost != 0 {
|
if lost != 0 {
|
||||||
sf.sm.ss.onPacketLost(fmt.Errorf("%d RTP %s lost",
|
sf.sm.ss.onPacketLost(liberrors.ErrServerRTPPacketsLost{Lost: lost})
|
||||||
lost,
|
|
||||||
func() string {
|
|
||||||
if lost == 1 {
|
|
||||||
return "packet"
|
|
||||||
}
|
|
||||||
return "packets"
|
|
||||||
}()))
|
|
||||||
// do not return
|
// do not return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,14 +83,7 @@ func (sf *serverSessionFormat) readRTPUDP(pkt *rtp.Packet, now time.Time) {
|
|||||||
func (sf *serverSessionFormat) readRTPTCP(pkt *rtp.Packet) {
|
func (sf *serverSessionFormat) readRTPTCP(pkt *rtp.Packet) {
|
||||||
lost := sf.tcpLossDetector.Process(pkt)
|
lost := sf.tcpLossDetector.Process(pkt)
|
||||||
if lost != 0 {
|
if lost != 0 {
|
||||||
sf.sm.ss.onPacketLost(fmt.Errorf("%d RTP %s lost",
|
sf.sm.ss.onPacketLost(liberrors.ErrServerRTPPacketsLost{Lost: lost})
|
||||||
lost,
|
|
||||||
func() string {
|
|
||||||
if lost == 1 {
|
|
||||||
return "packet"
|
|
||||||
}
|
|
||||||
return "packets"
|
|
||||||
}()))
|
|
||||||
// do not return
|
// do not return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
package gortsplib
|
package gortsplib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@@ -171,7 +170,7 @@ func (sm *serverSessionMedia) readRTCPUDPPlay(payload []byte) {
|
|||||||
atomic.AddUint64(sm.ss.bytesReceived, uint64(plen))
|
atomic.AddUint64(sm.ss.bytesReceived, uint64(plen))
|
||||||
|
|
||||||
if plen == (udpMaxPayloadSize + 1) {
|
if plen == (udpMaxPayloadSize + 1) {
|
||||||
sm.ss.onDecodeError(fmt.Errorf("RTCP packet is too big to be read with UDP"))
|
sm.ss.onDecodeError(liberrors.ErrServerRTCPPacketTooBigUDP{})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +194,7 @@ func (sm *serverSessionMedia) readRTPUDPRecord(payload []byte) {
|
|||||||
atomic.AddUint64(sm.ss.bytesReceived, uint64(plen))
|
atomic.AddUint64(sm.ss.bytesReceived, uint64(plen))
|
||||||
|
|
||||||
if plen == (udpMaxPayloadSize + 1) {
|
if plen == (udpMaxPayloadSize + 1) {
|
||||||
sm.ss.onDecodeError(fmt.Errorf("RTP packet is too big to be read with UDP"))
|
sm.ss.onDecodeError(liberrors.ErrServerRTPPacketTooBigUDP{})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +207,7 @@ func (sm *serverSessionMedia) readRTPUDPRecord(payload []byte) {
|
|||||||
|
|
||||||
forma, ok := sm.formats[pkt.PayloadType]
|
forma, ok := sm.formats[pkt.PayloadType]
|
||||||
if !ok {
|
if !ok {
|
||||||
sm.ss.onDecodeError(fmt.Errorf("received RTP packet with unknown format: %d", pkt.PayloadType))
|
sm.ss.onDecodeError(liberrors.ErrServerRTPPacketUnknownPayloadType{PayloadType: pkt.PayloadType})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +223,7 @@ func (sm *serverSessionMedia) readRTCPUDPRecord(payload []byte) {
|
|||||||
atomic.AddUint64(sm.ss.bytesReceived, uint64(plen))
|
atomic.AddUint64(sm.ss.bytesReceived, uint64(plen))
|
||||||
|
|
||||||
if plen == (udpMaxPayloadSize + 1) {
|
if plen == (udpMaxPayloadSize + 1) {
|
||||||
sm.ss.onDecodeError(fmt.Errorf("RTCP packet is too big to be read with UDP"))
|
sm.ss.onDecodeError(liberrors.ErrServerRTCPPacketTooBigUDP{})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,8 +253,7 @@ func (sm *serverSessionMedia) readRTPTCPPlay(_ []byte) {
|
|||||||
|
|
||||||
func (sm *serverSessionMedia) readRTCPTCPPlay(payload []byte) {
|
func (sm *serverSessionMedia) readRTCPTCPPlay(payload []byte) {
|
||||||
if len(payload) > udpMaxPayloadSize {
|
if len(payload) > udpMaxPayloadSize {
|
||||||
sm.ss.onDecodeError(fmt.Errorf("RTCP packet size (%d) is greater than maximum allowed (%d)",
|
sm.ss.onDecodeError(liberrors.ErrServerRTCPPacketTooBig{L: len(payload), Max: udpMaxPayloadSize})
|
||||||
len(payload), udpMaxPayloadSize))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +278,7 @@ func (sm *serverSessionMedia) readRTPTCPRecord(payload []byte) {
|
|||||||
|
|
||||||
forma, ok := sm.formats[pkt.PayloadType]
|
forma, ok := sm.formats[pkt.PayloadType]
|
||||||
if !ok {
|
if !ok {
|
||||||
sm.ss.onDecodeError(fmt.Errorf("received RTP packet with unknown format: %d", pkt.PayloadType))
|
sm.ss.onDecodeError(liberrors.ErrServerRTPPacketUnknownPayloadType{PayloadType: pkt.PayloadType})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,8 +287,7 @@ func (sm *serverSessionMedia) readRTPTCPRecord(payload []byte) {
|
|||||||
|
|
||||||
func (sm *serverSessionMedia) readRTCPTCPRecord(payload []byte) {
|
func (sm *serverSessionMedia) readRTCPTCPRecord(payload []byte) {
|
||||||
if len(payload) > udpMaxPayloadSize {
|
if len(payload) > udpMaxPayloadSize {
|
||||||
sm.ss.onDecodeError(fmt.Errorf("RTCP packet size (%d) is greater than maximum allowed (%d)",
|
sm.ss.onDecodeError(liberrors.ErrServerRTCPPacketTooBig{L: len(payload), Max: udpMaxPayloadSize})
|
||||||
len(payload), udpMaxPayloadSize))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
package gortsplib
|
package gortsplib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -142,7 +141,7 @@ func (st *ServerStream) readerAdd(
|
|||||||
defer st.mutex.Unlock()
|
defer st.mutex.Unlock()
|
||||||
|
|
||||||
if st.closed {
|
if st.closed {
|
||||||
return fmt.Errorf("stream is closed")
|
return liberrors.ErrServerStreamClosed{}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch transport {
|
switch transport {
|
||||||
@@ -251,7 +250,7 @@ func (st *ServerStream) WritePacketRTPWithNTP(medi *description.Media, pkt *rtp.
|
|||||||
defer st.mutex.RUnlock()
|
defer st.mutex.RUnlock()
|
||||||
|
|
||||||
if st.closed {
|
if st.closed {
|
||||||
return fmt.Errorf("stream is closed")
|
return liberrors.ErrServerStreamClosed{}
|
||||||
}
|
}
|
||||||
|
|
||||||
sm := st.streamMedias[medi]
|
sm := st.streamMedias[medi]
|
||||||
@@ -270,7 +269,7 @@ func (st *ServerStream) WritePacketRTCP(medi *description.Media, pkt rtcp.Packet
|
|||||||
defer st.mutex.RUnlock()
|
defer st.mutex.RUnlock()
|
||||||
|
|
||||||
if st.closed {
|
if st.closed {
|
||||||
return fmt.Errorf("stream is closed")
|
return liberrors.ErrServerStreamClosed{}
|
||||||
}
|
}
|
||||||
|
|
||||||
sm := st.streamMedias[medi]
|
sm := st.streamMedias[medi]
|
||||||
|
Reference in New Issue
Block a user