diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 438443f1..d284b19d 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -47,5 +47,5 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: - version: v1.31 + version: v1.45.2 args: $GOLANGCI_LINT_EXRA_ARGS diff --git a/.golangci.yml b/.golangci.yml index d6162c97..d7a88eca 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -15,14 +15,22 @@ linters-settings: linters: enable: - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers + - bidichk # Checks for dangerous unicode character sequences - bodyclose # checks whether HTTP response body is closed successfully + - contextcheck # check the function whether use a non-inherited context - deadcode # Finds unused code + - decorder # check declaration order and count of types, constants, variables and functions - depguard # Go linter that checks if package imports are in a list of acceptable packages - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - dupl # Tool for code clone detection + - durationcheck # check for two durations multiplied together - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases + - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. + - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. + - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - exhaustive # check exhaustiveness of enum switch statements - exportloopref # checks for pointers to enclosing loop variables + - forcetypeassert # finds forced type assertions - gci # Gci control golang package import order and make it always deterministic. - gochecknoglobals # Checks that no globals are present in Go code - gochecknoinits # Checks that no init functions are present in Go code @@ -35,40 +43,62 @@ linters: - gofumpt # Gofumpt checks whether code was gofumpt-ed. - goheader # Checks is file header matches to pattern - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - - golint # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes + - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - goprintffuncname # Checks that printf-like functions are named with `f` at the end - gosec # Inspects source code for security problems - gosimple # Linter for Go source code that specializes in simplifying a code - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string + - grouper # An analyzer to analyze expression groups. + - importas # Enforces consistent import aliases - ineffassign # Detects when assignments to existing variables are not used - misspell # Finds commonly misspelled English words in comments - nakedret # Finds naked returns in functions greater than a specified function length + - nilerr # Finds the code that returns nil even if it checks that the error is not nil. + - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - noctx # noctx finds sending http request without context.Context - - scopelint # Scopelint checks for unpinned variables in go programs + - predeclared # find code that shadows one of Go's predeclared identifiers + - revive # golint replacement, finds style mistakes - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - structcheck # Finds unused struct fields - stylecheck # Stylecheck is a replacement for golint + - tagliatelle # Checks the struct tags. + - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 + - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - unconvert # Remove unnecessary type conversions - unparam # Reports unused function parameters - unused # Checks Go code for unused constants, variables, functions and types - varcheck # Finds unused global variables and constants + - wastedassign # wastedassign finds wasted assignment statements - whitespace # Tool for detection of leading and trailing whitespace disable: + - containedctx # containedctx is a linter that detects struct contained context.Context field + - cyclop # checks function and package cyclomatic complexity + - exhaustivestruct # Checks if all struct's fields are initialized + - forbidigo # Forbids identifiers - funlen # Tool for detection of long functions - gocyclo # Computes and checks the cyclomatic complexity of functions - godot # Check if comments end in a period - gomnd # An analyzer to detect magic numbers. + - ifshort # Checks that your code uses short syntax for if-statements whenever possible + - ireturn # Accept Interfaces, Return Concrete Types - lll # Reports long lines + - maintidx # maintidx measures the maintainability index of each function. + - makezero # Finds slice declarations with non-zero initial length - maligned # Tool to detect Go structs that would take less memory if their fields were sorted - nestif # Reports deeply nested if statements - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - nolintlint # Reports ill-formed or insufficient nolint directives + - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - prealloc # Finds slice declarations that could potentially be preallocated + - promlinter # Check Prometheus metrics naming via promlint - rowserrcheck # checks whether Err of rows is checked successfully - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - testpackage # linter that makes you use a separate _test package + - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers + - varnamelen # checks that the length of a variable's name matches its scope + - wrapcheck # Checks that errors returned from external packages are wrapped - wsl # Whitespace Linter - Forces you to use empty lines! issues: diff --git a/atomicbool.go b/atomicbool.go index 1d4bf55a..bb6c26d2 100644 --- a/atomicbool.go +++ b/atomicbool.go @@ -20,7 +20,7 @@ func (b *atomicBool) get() bool { } func (b *atomicBool) swap(value bool) bool { - var i int32 = 0 + var i int32 if value { i = 1 } diff --git a/datachannel.go b/datachannel.go index 4af5ac94..94e4ddf5 100644 --- a/datachannel.go +++ b/datachannel.go @@ -321,12 +321,12 @@ var rlBufPool = sync.Pool{New: func() interface{} { func (d *DataChannel) readLoop() { for { - buffer := rlBufPool.Get().([]byte) + buffer := rlBufPool.Get().([]byte) //nolint:forcetypeassert n, isString, err := d.dataChannel.ReadDataChannel(buffer) if err != nil { rlBufPool.Put(buffer) // nolint:staticcheck d.setReadyState(DataChannelStateClosed) - if err != io.EOF { + if !errors.Is(err, io.EOF) { d.onError(err) } d.onClose() @@ -488,8 +488,8 @@ func (d *DataChannel) ID() *uint16 { // ReadyState represents the state of the DataChannel object. func (d *DataChannel) ReadyState() DataChannelState { - if v := d.readyState.Load(); v != nil { - return v.(DataChannelState) + if v, ok := d.readyState.Load().(DataChannelState); ok { + return v } return DataChannelState(0) } diff --git a/dtlstransport.go b/dtlstransport.go index 560eb4b8..22a327b7 100644 --- a/dtlstransport.go +++ b/dtlstransport.go @@ -134,7 +134,7 @@ func (t *DTLSTransport) WriteRTCP(pkts []rtcp.Packet) (int, error) { srtcpSession, err := t.getSRTCPSession() if err != nil { - return 0, nil + return 0, err } writeStream, err := srtcpSession.OpenWriteStream() @@ -232,16 +232,16 @@ func (t *DTLSTransport) startSRTP() error { } func (t *DTLSTransport) getSRTPSession() (*srtp.SessionSRTP, error) { - if value := t.srtpSession.Load(); value != nil { - return value.(*srtp.SessionSRTP), nil + if value, ok := t.srtpSession.Load().(*srtp.SessionSRTP); ok { + return value, nil } return nil, errDtlsTransportNotStarted } func (t *DTLSTransport) getSRTCPSession() (*srtp.SessionSRTCP, error) { - if value := t.srtcpSession.Load(); value != nil { - return value.(*srtp.SessionSRTCP), nil + if value, ok := t.srtcpSession.Load().(*srtp.SessionSRTCP); ok { + return value, nil } return nil, errDtlsTransportNotStarted @@ -407,12 +407,12 @@ func (t *DTLSTransport) Stop() error { // Try closing everything and collect the errors var closeErrs []error - if srtpSessionValue := t.srtpSession.Load(); srtpSessionValue != nil { - closeErrs = append(closeErrs, srtpSessionValue.(*srtp.SessionSRTP).Close()) + if srtpSession, err := t.getSRTPSession(); err == nil && srtpSession != nil { + closeErrs = append(closeErrs, srtpSession.Close()) } - if srtcpSessionValue := t.srtcpSession.Load(); srtcpSessionValue != nil { - closeErrs = append(closeErrs, srtcpSessionValue.(*srtp.SessionSRTCP).Close()) + if srtcpSession, err := t.getSRTCPSession(); err == nil && srtcpSession != nil { + closeErrs = append(closeErrs, srtcpSession.Close()) } for i := range t.simulcastStreams { diff --git a/examples/bandwidth-estimation-from-disk/main.go b/examples/bandwidth-estimation-from-disk/main.go index b0c13f84..9f6d4436 100644 --- a/examples/bandwidth-estimation-from-disk/main.go +++ b/examples/bandwidth-estimation-from-disk/main.go @@ -1,8 +1,10 @@ +//go:build !js // +build !js package main import ( + "errors" "fmt" "io" "os" @@ -217,16 +219,17 @@ func main() { frame, _, err = ivf.ParseNextFrame() } - switch err { + switch { + // If we have reached the end of the file start again + case errors.Is(err, io.EOF): + ivf.ResetReader(setReaderFile(qualityLevels[currentQuality].fileName)) + // No error write the video frame - case nil: + case err == nil: currentTimestamp = frameHeader.Timestamp if err = videoTrack.WriteSample(media.Sample{Data: frame, Duration: time.Second}); err != nil { panic(err) } - // If we have reached the end of the file start again - case io.EOF: - ivf.ResetReader(setReaderFile(qualityLevels[currentQuality].fileName)) // Error besides io.EOF that we dont know how to handle default: panic(err) diff --git a/examples/insertable-streams/main.go b/examples/insertable-streams/main.go index 1dd0fe0b..e49fbe4a 100644 --- a/examples/insertable-streams/main.go +++ b/examples/insertable-streams/main.go @@ -5,6 +5,7 @@ package main import ( "context" + "errors" "fmt" "io" "os" @@ -78,7 +79,7 @@ func main() { sleepTime := time.Millisecond * time.Duration((float32(header.TimebaseNumerator)/float32(header.TimebaseDenominator))*1000) for { frame, _, ivfErr := ivf.ParseNextFrame() - if ivfErr == io.EOF { + if errors.Is(ivfErr, io.EOF) { fmt.Printf("All frames parsed and sent") os.Exit(0) } diff --git a/examples/play-from-disk/main.go b/examples/play-from-disk/main.go index 386ab88e..5b6b7c51 100644 --- a/examples/play-from-disk/main.go +++ b/examples/play-from-disk/main.go @@ -5,6 +5,7 @@ package main import ( "context" + "errors" "fmt" "io" "os" @@ -102,7 +103,7 @@ func main() { ticker := time.NewTicker(time.Millisecond * time.Duration((float32(header.TimebaseNumerator)/float32(header.TimebaseDenominator))*1000)) for ; true; <-ticker.C { frame, _, ivfErr := ivf.ParseNextFrame() - if ivfErr == io.EOF { + if errors.Is(ivfErr, io.EOF) { fmt.Printf("All video frames parsed and sent") os.Exit(0) } @@ -167,7 +168,7 @@ func main() { ticker := time.NewTicker(oggPageDuration) for ; true; <-ticker.C { pageData, pageHeader, oggErr := ogg.ParseNextPage() - if oggErr == io.EOF { + if errors.Is(oggErr, io.EOF) { fmt.Printf("All audio pages parsed and sent") os.Exit(0) } diff --git a/examples/rtp-forwarder/main.go b/examples/rtp-forwarder/main.go index 41ce6036..3a0d73fc 100644 --- a/examples/rtp-forwarder/main.go +++ b/examples/rtp-forwarder/main.go @@ -4,6 +4,7 @@ package main import ( + "errors" "fmt" "net" "os" @@ -161,7 +162,8 @@ func main() { // That's why, for this particular example, the user first needs to provide the answer // to the browser then open the third party application. Therefore we must not kill // the forward on "connection refused" errors - if opError, ok := err.(*net.OpError); ok && opError.Err.Error() == "write: connection refused" { + var opError *net.OpError + if errors.As(err, &opError); ok && opError.Err.Error() == "write: connection refused" { continue } panic(err) diff --git a/icetransport.go b/icetransport.go index 5b1a1c3b..33968f83 100644 --- a/icetransport.go +++ b/icetransport.go @@ -45,7 +45,7 @@ type ICETransport struct { func (t *ICETransport) GetSelectedCandidatePair() (*ICECandidatePair, error) { agent := t.gatherer.getAgent() if agent == nil { - return nil, nil + return nil, nil //nolint:nilnil } icePair, err := agent.GetSelectedCandidatePair() @@ -208,9 +208,8 @@ func (t *ICETransport) OnSelectedCandidatePairChange(f func(*ICECandidatePair)) } func (t *ICETransport) onSelectedCandidatePairChange(pair *ICECandidatePair) { - handler := t.onSelectedCandidatePairChangeHandler.Load() - if handler != nil { - handler.(func(*ICECandidatePair))(pair) + if handler, ok := t.onSelectedCandidatePairChangeHandler.Load().(func(*ICECandidatePair)); ok { + handler(pair) } } @@ -221,11 +220,11 @@ func (t *ICETransport) OnConnectionStateChange(f func(ICETransportState)) { } func (t *ICETransport) onConnectionStateChange(state ICETransportState) { - if handler := t.onConnectionStateChangeHandler.Load(); handler != nil { - handler.(func(ICETransportState))(state) + if handler, ok := t.onConnectionStateChangeHandler.Load().(func(ICETransportState)); ok { + handler(state) } - if handler := t.internalOnConnectionStateChangeHandler.Load(); handler != nil { - handler.(func(ICETransportState))(state) + if handler, ok := t.internalOnConnectionStateChangeHandler.Load().(func(ICETransportState)); ok { + handler(state) } } @@ -295,8 +294,8 @@ func (t *ICETransport) AddRemoteCandidate(remoteCandidate *ICECandidate) error { // State returns the current ice transport state. func (t *ICETransport) State() ICETransportState { - if v := t.state.Load(); v != nil { - return v.(ICETransportState) + if v, ok := t.state.Load().(ICETransportState); ok { + return v } return ICETransportState(0) } diff --git a/internal/util/util.go b/internal/util/util.go index 6e12b641..0e245f22 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -39,7 +39,7 @@ func FlattenErrs(errs []error) error { return multiError(errs2) } -type multiError []error +type multiError []error //nolint:errname func (me multiError) Error() string { var errstrings []string @@ -62,7 +62,7 @@ func (me multiError) Is(err error) bool { if errors.Is(e, err) { return true } - if me2, ok := e.(multiError); ok { + if me2, ok := e.(multiError); ok { //nolint:errorlint if me2.Is(err) { return true } diff --git a/internal/util/util_test.go b/internal/util/util_test.go index 54ae7189..560e39e9 100644 --- a/internal/util/util_test.go +++ b/internal/util/util_test.go @@ -38,7 +38,7 @@ func TestMultiError(t *testing.T) { t.Errorf("String representation doesn't match, expected: %s, got: %s", errs.Error(), str) } - errIs, ok := errs.(multiError) + errIs, ok := errs.(multiError) //nolint:errorlint if !ok { t.Fatal("FlattenErrs returns non-multiError") } diff --git a/operations.go b/operations.go index 1eb85345..06490eef 100644 --- a/operations.go +++ b/operations.go @@ -66,7 +66,10 @@ func (o *operations) pop() func() { e := o.ops.Front() o.ops.Remove(e) - return e.Value.(operation) + if op, ok := e.Value.(operation); ok { + return op + } + return nil } func (o *operations) start() { diff --git a/peerconnection.go b/peerconnection.go index 64b75a28..1bb34777 100644 --- a/peerconnection.go +++ b/peerconnection.go @@ -1651,7 +1651,10 @@ func (pc *PeerConnection) AddICECandidate(candidate ICECandidateInit) error { // ICEConnectionState returns the ICE connection state of the // PeerConnection instance. func (pc *PeerConnection) ICEConnectionState() ICEConnectionState { - return pc.iceConnectionState.Load().(ICEConnectionState) + if state, ok := pc.iceConnectionState.Load().(ICEConnectionState); ok { + return state + } + return ICEConnectionState(0) } // GetSenders returns the RTPSender that are currently attached to this PeerConnection @@ -2071,7 +2074,10 @@ func (pc *PeerConnection) ICEGatheringState() ICEGatheringState { // ConnectionState attribute returns the connection state of the // PeerConnection instance. func (pc *PeerConnection) ConnectionState() PeerConnectionState { - return pc.connectionState.Load().(PeerConnectionState) + if state, ok := pc.connectionState.Load().(PeerConnectionState); ok { + return state + } + return PeerConnectionState(0) } // GetStats return data providing statistics about the overall connection diff --git a/peerconnection_go_test.go b/peerconnection_go_test.go index f5832a3e..d5a0b27b 100644 --- a/peerconnection_go_test.go +++ b/peerconnection_go_test.go @@ -1580,7 +1580,7 @@ a=ssrc:1455629982 cname:{61fd3093-0326-4b12-8258-86bdc1fe677a} assert.NoError(t, err) assert.NoError(t, peerConnection.SetRemoteDescription(SessionDescription{Type: SDPTypeOffer, SDP: remoteSDP})) - assert.Equal(t, RTPTransceiverDirectionInactive, peerConnection.rtpTransceivers[0].direction.Load().(RTPTransceiverDirection)) + assert.Equal(t, RTPTransceiverDirectionInactive, peerConnection.rtpTransceivers[0].direction.Load().(RTPTransceiverDirection)) //nolint:forcetypeassert assert.NoError(t, peerConnection.Close()) } diff --git a/peerconnection_renegotiation_test.go b/peerconnection_renegotiation_test.go index e081c1c9..cc30fe1d 100644 --- a/peerconnection_renegotiation_test.go +++ b/peerconnection_renegotiation_test.go @@ -6,6 +6,7 @@ package webrtc import ( "bufio" "context" + "errors" "io" "strconv" "strings" @@ -438,7 +439,7 @@ func TestPeerConnection_Renegotiation_CodecChange(t *testing.T) { pcAnswer.OnTrack(func(track *TrackRemote, r *RTPReceiver) { tracksCh <- track for { - if _, _, readErr := track.ReadRTP(); readErr == io.EOF { + if _, _, readErr := track.ReadRTP(); errors.Is(readErr, io.EOF) { tracksClosed <- struct{}{} return } @@ -527,7 +528,7 @@ func TestPeerConnection_Renegotiation_RemoveTrack(t *testing.T) { onTrackFiredFunc() for { - if _, _, err := track.ReadRTP(); err == io.EOF { + if _, _, err := track.ReadRTP(); errors.Is(err, io.EOF) { trackClosedFunc() return } diff --git a/pkg/media/h264writer/h264writer.go b/pkg/media/h264writer/h264writer.go index 8eea3fe6..78045131 100644 --- a/pkg/media/h264writer/h264writer.go +++ b/pkg/media/h264writer/h264writer.go @@ -26,7 +26,7 @@ type ( // New builds a new H264 writer func New(filename string) (*H264Writer, error) { - f, err := os.Create(filename) + f, err := os.Create(filename) //nolint:gosec if err != nil { return nil, err } diff --git a/pkg/media/h264writer/h264writer_test.go b/pkg/media/h264writer/h264writer_test.go index b40d3917..eacbbecf 100644 --- a/pkg/media/h264writer/h264writer_test.go +++ b/pkg/media/h264writer/h264writer_test.go @@ -13,10 +13,10 @@ type writerCloser struct { bytes.Buffer } -var errCloseErr = errors.New("close error") +var errClose = errors.New("close error") func (w *writerCloser) Close() error { - return errCloseErr + return errClose } func TestNewWith(t *testing.T) { diff --git a/pkg/media/ivfwriter/ivfwriter.go b/pkg/media/ivfwriter/ivfwriter.go index a47c8584..d6bf7d47 100644 --- a/pkg/media/ivfwriter/ivfwriter.go +++ b/pkg/media/ivfwriter/ivfwriter.go @@ -43,7 +43,7 @@ type IVFWriter struct { // New builds a new IVF writer func New(fileName string, opts ...Option) (*IVFWriter, error) { - f, err := os.Create(fileName) + f, err := os.Create(fileName) //nolint:gosec if err != nil { return nil, err } diff --git a/pkg/media/oggwriter/oggwriter.go b/pkg/media/oggwriter/oggwriter.go index 54c1ce46..7c179e35 100644 --- a/pkg/media/oggwriter/oggwriter.go +++ b/pkg/media/oggwriter/oggwriter.go @@ -43,7 +43,7 @@ type OggWriter struct { // New builds a new OGG Opus writer func New(fileName string, sampleRate uint32, channelCount uint16) (*OggWriter, error) { - f, err := os.Create(fileName) + f, err := os.Create(fileName) //nolint:gosec if err != nil { return nil, err } diff --git a/pkg/media/rtpdump/reader.go b/pkg/media/rtpdump/reader.go index e903a06c..82cfa5fc 100644 --- a/pkg/media/rtpdump/reader.go +++ b/pkg/media/rtpdump/reader.go @@ -23,7 +23,7 @@ func NewReader(r io.Reader) (*Reader, Header, error) { // Look ahead to see if there's a valid preamble peek, err := bio.Peek(preambleLen) - if err == io.EOF { + if errors.Is(err, io.EOF) { return nil, hdr, errMalformed } if err != nil { @@ -38,7 +38,7 @@ func NewReader(r io.Reader) (*Reader, Header, error) { // consume the preamble _, _, err = bio.ReadLine() - if err == io.EOF { + if errors.Is(err, io.EOF) { return nil, hdr, errMalformed } if err != nil { diff --git a/pkg/media/rtpdump/reader_test.go b/pkg/media/rtpdump/reader_test.go index f71fa697..c5e01c41 100644 --- a/pkg/media/rtpdump/reader_test.go +++ b/pkg/media/rtpdump/reader_test.go @@ -262,7 +262,7 @@ func TestReader(t *testing.T) { var packets []Packet for { pkt, err := r.Next() - if err == io.EOF { + if errors.Is(err, io.EOF) { break } if err != nil { diff --git a/pkg/media/rtpdump/rtpdump.go b/pkg/media/rtpdump/rtpdump.go index c2ff0e13..795fc006 100644 --- a/pkg/media/rtpdump/rtpdump.go +++ b/pkg/media/rtpdump/rtpdump.go @@ -100,9 +100,7 @@ func (p Packet) Marshal() ([]byte, error) { return nil, err } - data := append(hdrData, p.Payload...) - - return data, nil + return append(hdrData, p.Payload...), nil } // Unmarshal decodes the Packet from binary. diff --git a/pkg/media/rtpdump/writer_test.go b/pkg/media/rtpdump/writer_test.go index 5dbdec5c..4937a48d 100644 --- a/pkg/media/rtpdump/writer_test.go +++ b/pkg/media/rtpdump/writer_test.go @@ -2,6 +2,7 @@ package rtpdump import ( "bytes" + "errors" "io" "net" "reflect" @@ -91,7 +92,7 @@ func TestRoundTrip(t *testing.T) { var packets2 []Packet for { pkt, err := reader.Next() - if err == io.EOF { + if errors.Is(err, io.EOF) { break } if err != nil { diff --git a/rtptransceiver.go b/rtptransceiver.go index 4ff4ead7..776e0108 100644 --- a/rtptransceiver.go +++ b/rtptransceiver.go @@ -82,8 +82,8 @@ func (t *RTPTransceiver) getCodecs() []RTPCodecParameters { // Sender returns the RTPTransceiver's RTPSender if it has one func (t *RTPTransceiver) Sender() *RTPSender { - if v := t.sender.Load(); v != nil { - return v.(*RTPSender) + if v, ok := t.sender.Load().(*RTPSender); ok { + return v } return nil @@ -109,8 +109,8 @@ func (t *RTPTransceiver) setSender(s *RTPSender) { // Receiver returns the RTPTransceiver's RTPReceiver if it has one func (t *RTPTransceiver) Receiver() *RTPReceiver { - if v := t.receiver.Load(); v != nil { - return v.(*RTPReceiver) + if v, ok := t.receiver.Load().(*RTPReceiver); ok { + return v } return nil @@ -127,8 +127,8 @@ func (t *RTPTransceiver) SetMid(mid string) error { // Mid gets the Transceiver's mid value. When not already set, this value will be set in CreateOffer or CreateAnswer. func (t *RTPTransceiver) Mid() string { - if v := t.mid.Load(); v != nil { - return v.(string) + if v, ok := t.mid.Load().(string); ok { + return v } return "" } @@ -140,7 +140,10 @@ func (t *RTPTransceiver) Kind() RTPCodecType { // Direction returns the RTPTransceiver's current direction func (t *RTPTransceiver) Direction() RTPTransceiverDirection { - return t.direction.Load().(RTPTransceiverDirection) + if direction, ok := t.direction.Load().(RTPTransceiverDirection); ok { + return direction + } + return RTPTransceiverDirection(0) } // Stop irreversibly stops the RTPTransceiver diff --git a/sctptransport.go b/sctptransport.go index a379a96b..e0e9873a 100644 --- a/sctptransport.go +++ b/sctptransport.go @@ -4,6 +4,7 @@ package webrtc import ( + "errors" "io" "math" "sync" @@ -175,7 +176,7 @@ ACCEPT: LoggerFactory: r.api.settingEngine.LoggerFactory, }, dataChannels...) if err != nil { - if err != io.EOF { + if errors.Is(err, io.EOF) { r.log.Errorf("Failed to accept data channel: %v", err) r.onError(err) } diff --git a/srtp_writer_future.go b/srtp_writer_future.go index 834d4613..45a50507 100644 --- a/srtp_writer_future.go +++ b/srtp_writer_future.go @@ -82,16 +82,16 @@ func (s *srtpWriterFuture) Close() error { } s.closed = true - if value := s.rtcpReadStream.Load(); value != nil { - return value.(*srtp.ReadStreamSRTCP).Close() + if value, ok := s.rtcpReadStream.Load().(*srtp.ReadStreamSRTCP); ok { + return value.Close() } return nil } func (s *srtpWriterFuture) Read(b []byte) (n int, err error) { - if value := s.rtcpReadStream.Load(); value != nil { - return value.(*srtp.ReadStreamSRTCP).Read(b) + if value, ok := s.rtcpReadStream.Load().(*srtp.ReadStreamSRTCP); ok { + return value.Read(b) } if err := s.init(false); err != nil || s.rtcpReadStream.Load() == nil { @@ -102,8 +102,8 @@ func (s *srtpWriterFuture) Read(b []byte) (n int, err error) { } func (s *srtpWriterFuture) SetReadDeadline(t time.Time) error { - if value := s.rtcpReadStream.Load(); value != nil { - return value.(*srtp.ReadStreamSRTCP).SetReadDeadline(t) + if value, ok := s.rtcpReadStream.Load().(*srtp.ReadStreamSRTCP); ok { + return value.SetReadDeadline(t) } if err := s.init(false); err != nil || s.rtcpReadStream.Load() == nil { @@ -114,8 +114,8 @@ func (s *srtpWriterFuture) SetReadDeadline(t time.Time) error { } func (s *srtpWriterFuture) WriteRTP(header *rtp.Header, payload []byte) (int, error) { - if value := s.rtpWriteStream.Load(); value != nil { - return value.(*srtp.WriteStreamSRTP).WriteRTP(header, payload) + if value, ok := s.rtpWriteStream.Load().(*srtp.WriteStreamSRTP); ok { + return value.WriteRTP(header, payload) } if err := s.init(true); err != nil || s.rtpWriteStream.Load() == nil { @@ -126,8 +126,8 @@ func (s *srtpWriterFuture) WriteRTP(header *rtp.Header, payload []byte) (int, er } func (s *srtpWriterFuture) Write(b []byte) (int, error) { - if value := s.rtpWriteStream.Load(); value != nil { - return value.(*srtp.WriteStreamSRTP).Write(b) + if value, ok := s.rtpWriteStream.Load().(*srtp.WriteStreamSRTP); ok { + return value.Write(b) } if err := s.init(true); err != nil || s.rtpWriteStream.Load() == nil { diff --git a/track_local_static.go b/track_local_static.go index 914bd374..51e963d0 100644 --- a/track_local_static.go +++ b/track_local_static.go @@ -134,7 +134,7 @@ var rtpPacketPool = sync.Pool{ // PeerConnections so you can remove them func (s *TrackLocalStaticRTP) WriteRTP(p *rtp.Packet) error { ipacket := rtpPacketPool.Get() - packet := ipacket.(*rtp.Packet) + packet := ipacket.(*rtp.Packet) //nolint:forcetypeassert defer func() { *packet = rtp.Packet{} rtpPacketPool.Put(ipacket) @@ -167,7 +167,7 @@ func (s *TrackLocalStaticRTP) writeRTP(p *rtp.Packet) error { // PeerConnections so you can remove them func (s *TrackLocalStaticRTP) Write(b []byte) (n int, err error) { ipacket := rtpPacketPool.Get() - packet := ipacket.(*rtp.Packet) + packet := ipacket.(*rtp.Packet) //nolint:forcetypeassert defer func() { *packet = rtp.Packet{} rtpPacketPool.Put(ipacket)