mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 07:06:58 +08:00
move errors into subpackage
This commit is contained in:
226
serverconn.go
226
serverconn.go
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/aler9/gortsplib/pkg/base"
|
||||
"github.com/aler9/gortsplib/pkg/headers"
|
||||
"github.com/aler9/gortsplib/pkg/liberrors"
|
||||
"github.com/aler9/gortsplib/pkg/multibuffer"
|
||||
"github.com/aler9/gortsplib/pkg/ringbuffer"
|
||||
"github.com/aler9/gortsplib/pkg/rtcpreceiver"
|
||||
@@ -24,167 +25,6 @@ const (
|
||||
serverConnReceiverReportInterval = 10 * time.Second
|
||||
)
|
||||
|
||||
// ErrServerTeardown is returned in case of a teardown request.
|
||||
type ErrServerTeardown struct{}
|
||||
|
||||
// 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 '%v'", 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 {
|
||||
for i := len(s) - 1 - len(substr); i >= 0; i-- {
|
||||
if s[i:i+len(substr)] == substr {
|
||||
@@ -201,7 +41,7 @@ func setupGetTrackIDPathQuery(url *base.URL,
|
||||
|
||||
pathAndQuery, ok := url.RTSPPathAndQuery()
|
||||
if !ok {
|
||||
return 0, "", "", ErrServerNoPath{}
|
||||
return 0, "", "", liberrors.ErrServerNoPath{}
|
||||
}
|
||||
|
||||
if thMode == nil || *thMode == headers.TransportModePlay {
|
||||
@@ -519,13 +359,13 @@ func (sc *ServerConn) checkState(allowed map[ServerConnState]struct{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
allowedList := make([]ServerConnState, len(allowed))
|
||||
allowedList := make([]fmt.Stringer, len(allowed))
|
||||
i := 0
|
||||
for a := range allowed {
|
||||
allowedList[i] = a
|
||||
i++
|
||||
}
|
||||
return ErrServerWrongState{allowedList, sc.state}
|
||||
return liberrors.ErrServerWrongState{AllowedList: allowedList, State: sc.state}
|
||||
}
|
||||
|
||||
// NetConn returns the underlying net.Conn.
|
||||
@@ -617,7 +457,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
Header: base.Header{},
|
||||
}, ErrServerCSeqMissing{}
|
||||
}, liberrors.ErrServerCSeqMissing{}
|
||||
}
|
||||
|
||||
if sc.readHandlers.OnRequest != nil {
|
||||
@@ -631,7 +471,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if !ok {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerNoPath{}
|
||||
}, liberrors.ErrServerNoPath{}
|
||||
}
|
||||
|
||||
path, query := base.PathSplitQuery(pathAndQuery)
|
||||
@@ -690,7 +530,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if !ok {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerNoPath{}
|
||||
}, liberrors.ErrServerNoPath{}
|
||||
}
|
||||
|
||||
path, query := base.PathSplitQuery(pathAndQuery)
|
||||
@@ -729,33 +569,33 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if !ok || len(ct) != 1 {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerContentTypeMissing{}
|
||||
}, liberrors.ErrServerContentTypeMissing{}
|
||||
}
|
||||
|
||||
if ct[0] != "application/sdp" {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerContentTypeUnsupported{ct}
|
||||
}, liberrors.ErrServerContentTypeUnsupported{CT: ct}
|
||||
}
|
||||
|
||||
tracks, err := ReadTracks(req.Body, req.URL)
|
||||
if err != nil {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerSDPInvalid{err}
|
||||
}, liberrors.ErrServerSDPInvalid{Err: err}
|
||||
}
|
||||
|
||||
if len(tracks) == 0 {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerSDPNoTracksDefined{}
|
||||
}, liberrors.ErrServerSDPNoTracksDefined{}
|
||||
}
|
||||
|
||||
pathAndQuery, ok := req.URL.RTSPPath()
|
||||
if !ok {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerNoPath{}
|
||||
}, liberrors.ErrServerNoPath{}
|
||||
}
|
||||
|
||||
path, query := base.PathSplitQuery(pathAndQuery)
|
||||
@@ -829,7 +669,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if err != nil {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerTransportHeaderInvalid{err}
|
||||
}, liberrors.ErrServerTransportHeaderInvalid{Err: err}
|
||||
}
|
||||
|
||||
if th.Delivery != nil && *th.Delivery == base.StreamDeliveryMulticast {
|
||||
@@ -849,7 +689,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if _, ok := sc.setuppedTracks[trackID]; ok {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerTrackAlreadySetup{trackID}
|
||||
}, liberrors.ErrServerTrackAlreadySetup{TrackID: trackID}
|
||||
}
|
||||
|
||||
switch sc.state {
|
||||
@@ -857,14 +697,14 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if th.Mode != nil && *th.Mode != headers.TransportModePlay {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerTransportHeaderWrongMode{th.Mode}
|
||||
}, liberrors.ErrServerTransportHeaderWrongMode{Mode: th.Mode}
|
||||
}
|
||||
|
||||
default: // record
|
||||
if th.Mode == nil || *th.Mode != headers.TransportModeRecord {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerTransportHeaderWrongMode{th.Mode}
|
||||
}, liberrors.ErrServerTransportHeaderWrongMode{Mode: th.Mode}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -878,29 +718,29 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if th.ClientPorts == nil {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerTransportHeaderNoClientPorts{}
|
||||
}, liberrors.ErrServerTransportHeaderNoClientPorts{}
|
||||
}
|
||||
|
||||
} else {
|
||||
if th.InterleavedIDs == nil {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerTransportHeaderNoInterleavedIDs{}
|
||||
}, liberrors.ErrServerTransportHeaderNoInterleavedIDs{}
|
||||
}
|
||||
|
||||
if th.InterleavedIDs[0] != (trackID*2) ||
|
||||
th.InterleavedIDs[1] != (1+trackID*2) {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerTransportHeaderWrongInterleavedIDs{
|
||||
[2]int{(trackID * 2), (1 + trackID*2)}, *th.InterleavedIDs}
|
||||
}, liberrors.ErrServerTransportHeaderWrongInterleavedIDs{
|
||||
Expected: [2]int{(trackID * 2), (1 + trackID*2)}, Value: *th.InterleavedIDs}
|
||||
}
|
||||
}
|
||||
|
||||
if sc.setupProtocol != nil && *sc.setupProtocol != th.Protocol {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerTracksDifferentProtocols{}
|
||||
}, liberrors.ErrServerTracksDifferentProtocols{}
|
||||
}
|
||||
|
||||
res, err := sc.readHandlers.OnSetup(&ServerConnSetupCtx{
|
||||
@@ -987,14 +827,14 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if len(sc.setuppedTracks) == 0 {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerNoTracksSetup{}
|
||||
}, liberrors.ErrServerNoTracksSetup{}
|
||||
}
|
||||
|
||||
pathAndQuery, ok := req.URL.RTSPPath()
|
||||
if !ok {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerNoPath{}
|
||||
}, liberrors.ErrServerNoPath{}
|
||||
}
|
||||
|
||||
// path can end with a slash due to Content-Base, remove it
|
||||
@@ -1030,20 +870,20 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if len(sc.setuppedTracks) == 0 {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerNoTracksSetup{}
|
||||
}, liberrors.ErrServerNoTracksSetup{}
|
||||
}
|
||||
|
||||
if len(sc.setuppedTracks) != len(sc.announcedTracks) {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerNotAllAnnouncedTracksSetup{}
|
||||
}, liberrors.ErrServerNotAllAnnouncedTracksSetup{}
|
||||
}
|
||||
|
||||
pathAndQuery, ok := req.URL.RTSPPath()
|
||||
if !ok {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerNoPath{}
|
||||
}, liberrors.ErrServerNoPath{}
|
||||
}
|
||||
|
||||
// path can end with a slash due to Content-Base, remove it
|
||||
@@ -1083,7 +923,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if !ok {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerNoPath{}
|
||||
}, liberrors.ErrServerNoPath{}
|
||||
}
|
||||
|
||||
// path can end with a slash due to Content-Base, remove it
|
||||
@@ -1118,7 +958,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if !ok {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerNoPath{}
|
||||
}, liberrors.ErrServerNoPath{}
|
||||
}
|
||||
|
||||
path, query := base.PathSplitQuery(pathAndQuery)
|
||||
@@ -1145,7 +985,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if !ok {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerNoPath{}
|
||||
}, liberrors.ErrServerNoPath{}
|
||||
}
|
||||
|
||||
path, query := base.PathSplitQuery(pathAndQuery)
|
||||
@@ -1163,7 +1003,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
if !ok {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusBadRequest,
|
||||
}, ErrServerNoPath{}
|
||||
}, liberrors.ErrServerNoPath{}
|
||||
}
|
||||
|
||||
path, query := base.PathSplitQuery(pathAndQuery)
|
||||
@@ -1177,7 +1017,7 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
||||
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusOK,
|
||||
}, ErrServerTeardown{}
|
||||
}, liberrors.ErrServerTeardown{}
|
||||
}
|
||||
|
||||
return &base.Response{
|
||||
@@ -1196,7 +1036,7 @@ func (sc *ServerConn) backgroundRead() error {
|
||||
}
|
||||
|
||||
// add cseq
|
||||
if _, ok := err.(ErrServerCSeqMissing); !ok {
|
||||
if _, ok := err.(liberrors.ErrServerCSeqMissing); !ok {
|
||||
res.Header["CSeq"] = req.Header["CSeq"]
|
||||
}
|
||||
|
||||
@@ -1286,7 +1126,7 @@ outer:
|
||||
err := req.Read(sc.br)
|
||||
if err != nil {
|
||||
if atomic.LoadInt32(&sc.udpTimeout) == 1 {
|
||||
errRet = ErrServerNoUDPPacketsRecently{}
|
||||
errRet = liberrors.ErrServerNoUDPPacketsRecently{}
|
||||
} else {
|
||||
errRet = err
|
||||
}
|
||||
|
Reference in New Issue
Block a user