export most server errors

This commit is contained in:
aler9
2021-03-21 09:59:43 +01:00
parent aa094b21e5
commit da82a2dcc3
9 changed files with 232 additions and 79 deletions

View File

@@ -524,7 +524,7 @@ func (c *ClientConn) Setup(mode headers.TransportMode, track *Track,
th.ClientPorts = &[2]int{rtpPort, rtcpPort} th.ClientPorts = &[2]int{rtpPort, rtcpPort}
} else { } else {
th.InterleavedIds = &[2]int{(track.ID * 2), (track.ID * 2) + 1} th.InterleavedIDs = &[2]int{(track.ID * 2), (track.ID * 2) + 1}
} }
trackURL, err := track.URL() trackURL, err := track.URL()
@@ -605,11 +605,11 @@ func (c *ClientConn) Setup(mode headers.TransportMode, track *Track,
} }
} }
} else if thRes.InterleavedIds == nil || } else if thRes.InterleavedIDs == nil ||
thRes.InterleavedIds[0] != th.InterleavedIds[0] || thRes.InterleavedIDs[0] != th.InterleavedIDs[0] ||
thRes.InterleavedIds[1] != th.InterleavedIds[1] { thRes.InterleavedIDs[1] != th.InterleavedIDs[1] {
return nil, fmt.Errorf("transport header does not have interleaved ids %v (%s)", return nil, fmt.Errorf("transport header does not have interleaved ids %v (%s)",
*th.InterleavedIds, res.Header["Transport"]) *th.InterleavedIDs, res.Header["Transport"])
} }
clockRate, _ := track.ClockRate() clockRate, _ := track.ClockRate()

View File

@@ -80,7 +80,7 @@ func TestClientConnPublishSerial(t *testing.T) {
} else { } else {
th.Protocol = StreamProtocolTCP th.Protocol = StreamProtocolTCP
th.InterleavedIds = inTH.InterleavedIds th.InterleavedIDs = inTH.InterleavedIDs
} }
err = base.Response{ err = base.Response{
@@ -211,7 +211,7 @@ func TestClientConnPublishParallel(t *testing.T) {
} else { } else {
th.Protocol = StreamProtocolTCP th.Protocol = StreamProtocolTCP
th.InterleavedIds = inTH.InterleavedIds th.InterleavedIDs = inTH.InterleavedIDs
} }
err = base.Response{ err = base.Response{
@@ -354,7 +354,7 @@ func TestClientConnPublishPauseSerial(t *testing.T) {
} else { } else {
th.Protocol = StreamProtocolTCP th.Protocol = StreamProtocolTCP
th.InterleavedIds = inTH.InterleavedIds th.InterleavedIDs = inTH.InterleavedIDs
} }
err = base.Response{ err = base.Response{
@@ -514,7 +514,7 @@ func TestClientConnPublishPauseParallel(t *testing.T) {
} else { } else {
th.Protocol = StreamProtocolTCP th.Protocol = StreamProtocolTCP
th.InterleavedIds = inTH.InterleavedIds th.InterleavedIDs = inTH.InterleavedIDs
} }
err = base.Response{ err = base.Response{

View File

@@ -134,7 +134,7 @@ func TestClientConnRead(t *testing.T) {
return &v return &v
}(), }(),
ClientPorts: th.ClientPorts, ClientPorts: th.ClientPorts,
InterleavedIds: &[2]int{0, 1}, InterleavedIDs: &[2]int{0, 1},
}.Write(), }.Write(),
}, },
}.Write(bconn.Writer) }.Write(bconn.Writer)
@@ -395,7 +395,7 @@ func TestClientConnReadAutomaticProtocol(t *testing.T) {
v := base.StreamDeliveryUnicast v := base.StreamDeliveryUnicast
return &v return &v
}(), }(),
InterleavedIds: &[2]int{0, 1}, InterleavedIDs: &[2]int{0, 1},
}.Write(), }.Write(),
}, },
}.Write(bconn.Writer) }.Write(bconn.Writer)
@@ -690,7 +690,7 @@ func TestClientConnReadPause(t *testing.T) {
} else { } else {
th.Protocol = StreamProtocolTCP th.Protocol = StreamProtocolTCP
th.InterleavedIds = inTH.InterleavedIds th.InterleavedIDs = inTH.InterleavedIDs
} }
err = base.Response{ err = base.Response{

View File

@@ -55,7 +55,7 @@ type Transport struct {
ServerPorts *[2]int ServerPorts *[2]int
// (optional) interleaved frame ids // (optional) interleaved frame ids
InterleavedIds *[2]int InterleavedIDs *[2]int
// (optional) mode // (optional) mode
Mode *TransportMode Mode *TransportMode
@@ -170,7 +170,7 @@ func (h *Transport) Read(v base.HeaderValue) error {
if err != nil { if err != nil {
return err return err
} }
h.InterleavedIds = ports h.InterleavedIDs = ports
case strings.HasPrefix(t, "mode="): case strings.HasPrefix(t, "mode="):
str := strings.ToLower(t[len("mode="):]) str := strings.ToLower(t[len("mode="):])
@@ -227,8 +227,8 @@ func (h Transport) Write() base.HeaderValue {
rets = append(rets, "server_port="+strconv.FormatInt(int64(ports[0]), 10)+"-"+strconv.FormatInt(int64(ports[1]), 10)) rets = append(rets, "server_port="+strconv.FormatInt(int64(ports[0]), 10)+"-"+strconv.FormatInt(int64(ports[1]), 10))
} }
if h.InterleavedIds != nil { if h.InterleavedIDs != nil {
ports := *h.InterleavedIds ports := *h.InterleavedIDs
rets = append(rets, "interleaved="+strconv.FormatInt(int64(ports[0]), 10)+"-"+strconv.FormatInt(int64(ports[1]), 10)) rets = append(rets, "interleaved="+strconv.FormatInt(int64(ports[0]), 10)+"-"+strconv.FormatInt(int64(ports[1]), 10))
} }

View File

@@ -72,7 +72,7 @@ var casesTransport = []struct {
base.HeaderValue{`RTP/AVP/TCP;interleaved=0-1`}, base.HeaderValue{`RTP/AVP/TCP;interleaved=0-1`},
Transport{ Transport{
Protocol: base.StreamProtocolTCP, Protocol: base.StreamProtocolTCP,
InterleavedIds: &[2]int{0, 1}, InterleavedIDs: &[2]int{0, 1},
}, },
}, },
{ {

View File

@@ -3,7 +3,6 @@ package gortsplib
import ( import (
"bufio" "bufio"
"crypto/tls" "crypto/tls"
"errors"
"fmt" "fmt"
"net" "net"
"strconv" "strconv"
@@ -25,11 +24,166 @@ const (
serverConnReceiverReportInterval = 10 * time.Second serverConnReceiverReportInterval = 10 * time.Second
) )
// server errors. // ErrServerTeardown is returned in case of a teardown request.
var ( type ErrServerTeardown struct{}
ErrServerTeardown = errors.New("teardown")
errServerCSeqMissing = errors.New("CSeq is missing") // Error implements the error interface.
) func (e ErrServerTeardown) Error() string {
return "teardown"
}
// ErrServerCSeqMissing is returned in case the CSeq is missing.
type ErrServerCSeqMissing struct{}
// Error implements the error interface.
func (e ErrServerCSeqMissing) Error() string {
return "CSeq is missing"
}
// ErrServerWrongState is returned in case of a wrong client state.
type ErrServerWrongState struct {
allowedList []ServerConnState
state ServerConnState
}
// Error implements the error interface.
func (e ErrServerWrongState) Error() string {
return fmt.Sprintf("must be in state %v, while is in state %v",
e.allowedList, e.state)
}
// ErrServerNoPath is returned in case the path can't be retrieved.
type ErrServerNoPath struct{}
// Error implements the error interface.
func (e ErrServerNoPath) Error() string {
return "RTSP path can't be retrieved"
}
// ErrServerContentTypeMissing is returned in case the Content-Type header is missing.
type ErrServerContentTypeMissing struct{}
// Error implements the error interface.
func (e ErrServerContentTypeMissing) Error() string {
return "Content-Type header is missing"
}
// ErrServerContentTypeUnsupported is returned in case the Content-Type header is unsupported.
type ErrServerContentTypeUnsupported struct {
ct base.HeaderValue
}
// Error implements the error interface.
func (e ErrServerContentTypeUnsupported) Error() string {
return fmt.Sprintf("unsupported Content-Type header '%s'", e.ct)
}
// ErrServerSDPInvalid is returned in case the SDP is invalid.
type ErrServerSDPInvalid struct {
err error
}
// Error implements the error interface.
func (e ErrServerSDPInvalid) Error() string {
return fmt.Sprintf("invalid SDP: %v", e.err)
}
// ErrServerSDPNoTracksDefined is returned in case the SDP has no tracks defined.
type ErrServerSDPNoTracksDefined struct{}
// Error implements the error interface.
func (e ErrServerSDPNoTracksDefined) Error() string {
return "no tracks defined in the SDP"
}
// ErrServerTransportHeaderInvalid is returned in case the transport header is invalid.
type ErrServerTransportHeaderInvalid struct {
err error
}
// Error implements the error interface.
func (e ErrServerTransportHeaderInvalid) Error() string {
return fmt.Sprintf("invalid transport header: %v", e.err)
}
// ErrServerTrackAlreadySetup is returned in case a track has already been setup.
type ErrServerTrackAlreadySetup struct {
trackID int
}
// Error implements the error interface.
func (e ErrServerTrackAlreadySetup) Error() string {
return fmt.Sprintf("track %d has already been setup", e.trackID)
}
// ErrServerTransportHeaderWrongMode is returned in case the transport header contains a wrong mode.
type ErrServerTransportHeaderWrongMode struct {
mode *headers.TransportMode
}
// Error implements the error interface.
func (e ErrServerTransportHeaderWrongMode) Error() string {
return fmt.Sprintf("transport header contains a wrong mode (%v)", e.mode)
}
// ErrServerTransportHeaderNoClientPorts is returned in case the transport header doesn't contain client ports.
type ErrServerTransportHeaderNoClientPorts struct{}
// Error implements the error interface.
func (e ErrServerTransportHeaderNoClientPorts) Error() string {
return "transport header does not contain client ports"
}
// ErrServerTransportHeaderNoInterleavedIDs is returned in case the transport header doesn't contain interleaved IDs.
type ErrServerTransportHeaderNoInterleavedIDs struct{}
// Error implements the error interface.
func (e ErrServerTransportHeaderNoInterleavedIDs) Error() string {
return "transport header does not contain interleaved ids"
}
// ErrServerTransportHeaderWrongInterleavedIDs is returned in case the transport header contains wrong interleaved IDs.
type ErrServerTransportHeaderWrongInterleavedIDs struct {
expected [2]int
value [2]int
}
// Error implements the error interface.
func (e ErrServerTransportHeaderWrongInterleavedIDs) Error() string {
return fmt.Sprintf("wrong interleaved ids, expected %v, got %v", e.expected, e.value)
}
// ErrServerTracksDifferentProtocols is returned in case the client is trying to setup tracks with different protocols.
type ErrServerTracksDifferentProtocols struct{}
// Error implements the error interface.
func (e ErrServerTracksDifferentProtocols) Error() string {
return "can't setup tracks with different protocols"
}
// ErrServerNoTracksSetup is returned in case no tracks have been setup.
type ErrServerNoTracksSetup struct{}
// Error implements the error interface.
func (e ErrServerNoTracksSetup) Error() string {
return "no tracks have been setup"
}
// ErrServerNotAllAnnouncedTracksSetup is returned in case not all announced tracks have been setup.
type ErrServerNotAllAnnouncedTracksSetup struct{}
// Error implements the error interface.
func (e ErrServerNotAllAnnouncedTracksSetup) Error() string {
return "not all announced tracks have been setup"
}
// ErrServerNoUDPPacketsRecently is returned when no UDP packets have been received recently.
type ErrServerNoUDPPacketsRecently struct{}
// Error implements the error interface.
func (e ErrServerNoUDPPacketsRecently) Error() string {
return "no UDP packets received recently (maybe there's a firewall/NAT in between)"
}
func stringsReverseIndex(s, substr string) int { func stringsReverseIndex(s, substr string) int {
for i := len(s) - 1 - len(substr); i >= 0; i-- { for i := len(s) - 1 - len(substr); i >= 0; i-- {
@@ -47,7 +201,7 @@ func setupGetTrackIDPathQuery(url *base.URL,
pathAndQuery, ok := url.RTSPPathAndQuery() pathAndQuery, ok := url.RTSPPathAndQuery()
if !ok { if !ok {
return 0, "", "", fmt.Errorf("invalid URL (%s)", url) return 0, "", "", ErrServerNoPath{}
} }
if thMode == nil || *thMode == headers.TransportModePlay { if thMode == nil || *thMode == headers.TransportModePlay {
@@ -356,9 +510,6 @@ func (sc *ServerConn) backgroundWrite() {
case *base.Response: case *base.Response:
sc.nconn.SetWriteDeadline(time.Now().Add(sc.conf.WriteTimeout)) sc.nconn.SetWriteDeadline(time.Now().Add(sc.conf.WriteTimeout))
w.Write(sc.bw) w.Write(sc.bw)
default:
panic(fmt.Errorf("unsupported type: %T", what))
} }
} }
} }
@@ -374,8 +525,7 @@ func (sc *ServerConn) checkState(allowed map[ServerConnState]struct{}) error {
allowedList[i] = a allowedList[i] = a
i++ i++
} }
return fmt.Errorf("must be in state %v, while is in state %v", return ErrServerWrongState{allowedList, sc.state}
allowedList, sc.state)
} }
// NetConn returns the underlying net.Conn. // NetConn returns the underlying net.Conn.
@@ -467,7 +617,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
Header: base.Header{}, Header: base.Header{},
}, errServerCSeqMissing }, ErrServerCSeqMissing{}
} }
if sc.readHandlers.OnRequest != nil { if sc.readHandlers.OnRequest != nil {
@@ -481,7 +631,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if !ok { if !ok {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("invalid URL (%s)", req.URL) }, ErrServerNoPath{}
} }
path, query := base.PathSplitQuery(pathAndQuery) path, query := base.PathSplitQuery(pathAndQuery)
@@ -540,7 +690,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if !ok { if !ok {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("invalid URL (%s)", req.URL) }, ErrServerNoPath{}
} }
path, query := base.PathSplitQuery(pathAndQuery) path, query := base.PathSplitQuery(pathAndQuery)
@@ -579,33 +729,33 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if !ok || len(ct) != 1 { if !ok || len(ct) != 1 {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, errors.New("Content-Type header is missing") }, ErrServerContentTypeMissing{}
} }
if ct[0] != "application/sdp" { if ct[0] != "application/sdp" {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("unsupported Content-Type '%s'", ct) }, ErrServerContentTypeUnsupported{ct}
} }
tracks, err := ReadTracks(req.Body, req.URL) tracks, err := ReadTracks(req.Body, req.URL)
if err != nil { if err != nil {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("invalid SDP: %s", err) }, ErrServerSDPInvalid{err}
} }
if len(tracks) == 0 { if len(tracks) == 0 {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, errors.New("no tracks defined") }, ErrServerSDPNoTracksDefined{}
} }
pathAndQuery, ok := req.URL.RTSPPath() pathAndQuery, ok := req.URL.RTSPPath()
if !ok { if !ok {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("invalid URL (%s)", req.URL) }, ErrServerNoPath{}
} }
path, query := base.PathSplitQuery(pathAndQuery) path, query := base.PathSplitQuery(pathAndQuery)
@@ -679,7 +829,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if err != nil { if err != nil {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("transport header: %s", err) }, ErrServerTransportHeaderInvalid{err}
} }
if th.Delivery != nil && *th.Delivery == base.StreamDeliveryMulticast { if th.Delivery != nil && *th.Delivery == base.StreamDeliveryMulticast {
@@ -699,7 +849,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if _, ok := sc.setuppedTracks[trackID]; ok { if _, ok := sc.setuppedTracks[trackID]; ok {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("track %d has already been setup", trackID) }, ErrServerTrackAlreadySetup{trackID}
} }
switch sc.state { switch sc.state {
@@ -707,14 +857,14 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if th.Mode != nil && *th.Mode != headers.TransportModePlay { if th.Mode != nil && *th.Mode != headers.TransportModePlay {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("transport header must contain mode=play or not contain a mode") }, ErrServerTransportHeaderWrongMode{th.Mode}
} }
default: // record default: // record
if th.Mode == nil || *th.Mode != headers.TransportModeRecord { if th.Mode == nil || *th.Mode != headers.TransportModeRecord {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("transport header does not contain mode=record") }, ErrServerTransportHeaderWrongMode{th.Mode}
} }
} }
@@ -728,29 +878,29 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if th.ClientPorts == nil { if th.ClientPorts == nil {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("transport header does not have valid client ports (%v)", req.Header["Transport"]) }, ErrServerTransportHeaderNoClientPorts{}
} }
} else { } else {
if th.InterleavedIds == nil { if th.InterleavedIDs == nil {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("transport header does not contain the interleaved field") }, ErrServerTransportHeaderNoInterleavedIDs{}
} }
if th.InterleavedIds[0] != (trackID*2) || if th.InterleavedIDs[0] != (trackID*2) ||
th.InterleavedIds[1] != (1+trackID*2) { th.InterleavedIDs[1] != (1+trackID*2) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("wrong interleaved ids, expected [%v %v], got %v", }, ErrServerTransportHeaderWrongInterleavedIDs{
(trackID * 2), (1 + trackID*2), *th.InterleavedIds) [2]int{(trackID * 2), (1 + trackID*2)}, *th.InterleavedIDs}
} }
} }
if sc.setupProtocol != nil && *sc.setupProtocol != th.Protocol { if sc.setupProtocol != nil && *sc.setupProtocol != th.Protocol {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("can't setup tracks with different protocols") }, ErrServerTracksDifferentProtocols{}
} }
res, err := sc.readHandlers.OnSetup(&ServerConnSetupCtx{ res, err := sc.readHandlers.OnSetup(&ServerConnSetupCtx{
@@ -795,7 +945,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
} }
res.Header["Transport"] = headers.Transport{ res.Header["Transport"] = headers.Transport{
Protocol: StreamProtocolTCP, Protocol: StreamProtocolTCP,
InterleavedIds: th.InterleavedIds, InterleavedIDs: th.InterleavedIDs,
}.Write() }.Write()
} }
} }
@@ -837,14 +987,14 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if len(sc.setuppedTracks) == 0 { if len(sc.setuppedTracks) == 0 {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("no tracks have been setup") }, ErrServerNoTracksSetup{}
} }
pathAndQuery, ok := req.URL.RTSPPath() pathAndQuery, ok := req.URL.RTSPPath()
if !ok { if !ok {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("invalid URL (%s)", req.URL) }, ErrServerNoPath{}
} }
// path can end with a slash due to Content-Base, remove it // path can end with a slash due to Content-Base, remove it
@@ -880,20 +1030,20 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if len(sc.setuppedTracks) == 0 { if len(sc.setuppedTracks) == 0 {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("no tracks have been setup") }, ErrServerNoTracksSetup{}
} }
if len(sc.setuppedTracks) != len(sc.announcedTracks) { if len(sc.setuppedTracks) != len(sc.announcedTracks) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("not all announced tracks have been setup") }, ErrServerNotAllAnnouncedTracksSetup{}
} }
pathAndQuery, ok := req.URL.RTSPPath() pathAndQuery, ok := req.URL.RTSPPath()
if !ok { if !ok {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("invalid URL (%s)", req.URL) }, ErrServerNoPath{}
} }
// path can end with a slash due to Content-Base, remove it // path can end with a slash due to Content-Base, remove it
@@ -933,7 +1083,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if !ok { if !ok {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("invalid URL (%s)", req.URL) }, ErrServerNoPath{}
} }
// path can end with a slash due to Content-Base, remove it // path can end with a slash due to Content-Base, remove it
@@ -968,7 +1118,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if !ok { if !ok {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("invalid URL (%s)", req.URL) }, ErrServerNoPath{}
} }
path, query := base.PathSplitQuery(pathAndQuery) path, query := base.PathSplitQuery(pathAndQuery)
@@ -995,7 +1145,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if !ok { if !ok {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("invalid URL (%s)", req.URL) }, ErrServerNoPath{}
} }
path, query := base.PathSplitQuery(pathAndQuery) path, query := base.PathSplitQuery(pathAndQuery)
@@ -1013,7 +1163,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
if !ok { if !ok {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("invalid URL (%s)", req.URL) }, ErrServerNoPath{}
} }
path, query := base.PathSplitQuery(pathAndQuery) path, query := base.PathSplitQuery(pathAndQuery)
@@ -1027,7 +1177,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
return &base.Response{ return &base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}, ErrServerTeardown }, ErrServerTeardown{}
} }
return &base.Response{ return &base.Response{
@@ -1046,7 +1196,7 @@ func (sc *ServerConn) backgroundRead() error {
} }
// add cseq // add cseq
if err != errServerCSeqMissing { if _, ok := err.(ErrServerCSeqMissing); !ok {
res.Header["CSeq"] = req.Header["CSeq"] res.Header["CSeq"] = req.Header["CSeq"]
} }
@@ -1136,7 +1286,7 @@ outer:
err := req.Read(sc.br) err := req.Read(sc.br)
if err != nil { if err != nil {
if atomic.LoadInt32(&sc.udpTimeout) == 1 { if atomic.LoadInt32(&sc.udpTimeout) == 1 {
errRet = fmt.Errorf("no UDP packets received recently (maybe there's a firewall/NAT in between)") errRet = ErrServerNoUDPPacketsRecently{}
} else { } else {
errRet = err errRet = err
} }

View File

@@ -202,8 +202,10 @@ func (ts *testServ) handleConn(conn *ServerConn) {
OnRecord: onRecord, OnRecord: onRecord,
OnFrame: onFrame, OnFrame: onFrame,
}) })
if err != io.EOF && err != ErrServerTeardown { if err != io.EOF {
fmt.Println("ERR", err) if _, ok := err.(ErrServerTeardown); !ok {
fmt.Println("ERR", err)
}
} }
ts.mutex.Lock() ts.mutex.Lock()
@@ -464,7 +466,8 @@ func TestServerConnTeardownResponse(t *testing.T) {
defer conn.Close() defer conn.Close()
err = <-conn.Read(ServerConnReadHandlers{}) err = <-conn.Read(ServerConnReadHandlers{})
require.Equal(t, ErrServerTeardown, err) _, ok := err.(ErrServerTeardown)
require.Equal(t, true, ok)
}() }()
conn, err := net.Dial("tcp", "localhost:8554") conn, err := net.Dial("tcp", "localhost:8554")

View File

@@ -161,7 +161,7 @@ func TestServerConnPublishSetupPath(t *testing.T) {
v := headers.TransportModeRecord v := headers.TransportModeRecord
return &v return &v
}(), }(),
InterleavedIds: &[2]int{0, 1}, InterleavedIDs: &[2]int{0, 1},
} }
err = base.Request{ err = base.Request{
@@ -262,7 +262,7 @@ func TestServerConnPublishSetupDifferentPaths(t *testing.T) {
v := headers.TransportModeRecord v := headers.TransportModeRecord
return &v return &v
}(), }(),
InterleavedIds: &[2]int{0, 1}, InterleavedIDs: &[2]int{0, 1},
} }
err = base.Request{ err = base.Request{
@@ -360,7 +360,7 @@ func TestServerConnPublishSetupDouble(t *testing.T) {
v := headers.TransportModeRecord v := headers.TransportModeRecord
return &v return &v
}(), }(),
InterleavedIds: &[2]int{0, 1}, InterleavedIDs: &[2]int{0, 1},
} }
err = base.Request{ err = base.Request{
@@ -482,7 +482,7 @@ func TestServerConnPublishRecordPartialTracks(t *testing.T) {
v := headers.TransportModeRecord v := headers.TransportModeRecord
return &v return &v
}(), }(),
InterleavedIds: &[2]int{0, 1}, InterleavedIDs: &[2]int{0, 1},
} }
err = base.Request{ err = base.Request{
@@ -632,7 +632,7 @@ func TestServerConnPublishReceivePackets(t *testing.T) {
inTH.ClientPorts = &[2]int{35466, 35467} inTH.ClientPorts = &[2]int{35466, 35467}
} else { } else {
inTH.Protocol = StreamProtocolTCP inTH.Protocol = StreamProtocolTCP
inTH.InterleavedIds = &[2]int{0, 1} inTH.InterleavedIDs = &[2]int{0, 1}
} }
err = base.Request{ err = base.Request{

View File

@@ -104,7 +104,7 @@ func TestServerConnReadSetupPath(t *testing.T) {
v := headers.TransportModePlay v := headers.TransportModePlay
return &v return &v
}(), }(),
InterleavedIds: &[2]int{ca.trackID * 2, (ca.trackID * 2) + 1}, InterleavedIDs: &[2]int{ca.trackID * 2, (ca.trackID * 2) + 1},
} }
err = base.Request{ err = base.Request{
@@ -172,7 +172,7 @@ func TestServerConnReadSetupDifferentPaths(t *testing.T) {
v := headers.TransportModePlay v := headers.TransportModePlay
return &v return &v
}(), }(),
InterleavedIds: &[2]int{0, 1}, InterleavedIDs: &[2]int{0, 1},
} }
err = base.Request{ err = base.Request{
@@ -190,7 +190,7 @@ func TestServerConnReadSetupDifferentPaths(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode) require.Equal(t, base.StatusOK, res.StatusCode)
th.InterleavedIds = &[2]int{2, 3} th.InterleavedIDs = &[2]int{2, 3}
err = base.Request{ err = base.Request{
Method: base.Setup, Method: base.Setup,
@@ -253,7 +253,7 @@ func TestServerConnReadSetupDouble(t *testing.T) {
v := headers.TransportModePlay v := headers.TransportModePlay
return &v return &v
}(), }(),
InterleavedIds: &[2]int{0, 1}, InterleavedIDs: &[2]int{0, 1},
} }
err = base.Request{ err = base.Request{
@@ -271,7 +271,7 @@ func TestServerConnReadSetupDouble(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode) require.Equal(t, base.StatusOK, res.StatusCode)
th.InterleavedIds = &[2]int{2, 3} th.InterleavedIDs = &[2]int{2, 3}
err = base.Request{ err = base.Request{
Method: base.Setup, Method: base.Setup,
@@ -364,7 +364,7 @@ func TestServerConnReadReceivePackets(t *testing.T) {
inTH.ClientPorts = &[2]int{35466, 35467} inTH.ClientPorts = &[2]int{35466, 35467}
} else { } else {
inTH.Protocol = StreamProtocolTCP inTH.Protocol = StreamProtocolTCP
inTH.InterleavedIds = &[2]int{0, 1} inTH.InterleavedIDs = &[2]int{0, 1}
} }
err = base.Request{ err = base.Request{
@@ -501,7 +501,7 @@ func TestServerConnReadTCPResponseBeforeFrames(t *testing.T) {
v := headers.TransportModePlay v := headers.TransportModePlay
return &v return &v
}(), }(),
InterleavedIds: &[2]int{0, 1}, InterleavedIDs: &[2]int{0, 1},
}.Write(), }.Write(),
}, },
}.Write(bconn.Writer) }.Write(bconn.Writer)
@@ -606,7 +606,7 @@ func TestServerConnReadPlayMultiple(t *testing.T) {
v := headers.TransportModePlay v := headers.TransportModePlay
return &v return &v
}(), }(),
InterleavedIds: &[2]int{0, 1}, InterleavedIDs: &[2]int{0, 1},
}.Write(), }.Write(),
}, },
}.Write(bconn.Writer) }.Write(bconn.Writer)
@@ -725,7 +725,7 @@ func TestServerConnReadPauseMultiple(t *testing.T) {
v := headers.TransportModePlay v := headers.TransportModePlay
return &v return &v
}(), }(),
InterleavedIds: &[2]int{0, 1}, InterleavedIDs: &[2]int{0, 1},
}.Write(), }.Write(),
}, },
}.Write(bconn.Writer) }.Write(bconn.Writer)