diff --git a/controllers/admin/hardware.go b/controllers/admin/hardware.go index 4eb40cf4f..3bdbde6e0 100644 --- a/controllers/admin/hardware.go +++ b/controllers/admin/hardware.go @@ -5,6 +5,7 @@ import ( "net/http" "github.com/owncast/owncast/metrics" + log "github.com/sirupsen/logrus" ) // GetHardwareStats will return hardware utilization over time. @@ -12,5 +13,8 @@ func GetHardwareStats(w http.ResponseWriter, r *http.Request) { m := metrics.Metrics w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(m) + err := json.NewEncoder(w).Encode(m) + if err != nil { + log.Errorln(err) + } } diff --git a/controllers/admin/index.go b/controllers/admin/index.go index d1ba623d5..15b1c74a1 100644 --- a/controllers/admin/index.go +++ b/controllers/admin/index.go @@ -27,7 +27,7 @@ func ServeAdmin(w http.ResponseWriter, r *http.Request) { f, err := pkger.Open(path) if err != nil { log.Warnln(err, path) - errorHandler(w, r, http.StatusNotFound) + errorHandler(w, http.StatusNotFound) return } @@ -39,9 +39,11 @@ func ServeAdmin(w http.ResponseWriter, r *http.Request) { mimeType := mime.TypeByExtension(filepath.Ext(path)) w.Header().Set("Content-Type", mimeType) - w.Write(b) + if _, err = w.Write(b); err != nil { + log.Errorln(err) + } } -func errorHandler(w http.ResponseWriter, r *http.Request, status int) { +func errorHandler(w http.ResponseWriter, status int) { w.WriteHeader(status) } diff --git a/controllers/admin/logs.go b/controllers/admin/logs.go index 5211c3af1..b7657111b 100644 --- a/controllers/admin/logs.go +++ b/controllers/admin/logs.go @@ -7,6 +7,7 @@ import ( "github.com/owncast/owncast/logging" "github.com/sirupsen/logrus" + log "github.com/sirupsen/logrus" ) // GetLogs will return all logs. @@ -19,7 +20,10 @@ func GetLogs(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(response) + err := json.NewEncoder(w).Encode(response) + if err != nil { + log.Errorln(err) + } } // GetWarnings will return only warning and error logs. @@ -32,7 +36,10 @@ func GetWarnings(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(response) + err := json.NewEncoder(w).Encode(response) + if err != nil { + log.Errorln(err) + } } type logsResponse struct { diff --git a/controllers/admin/serverConfig.go b/controllers/admin/serverConfig.go index fa660f584..fd8251fee 100644 --- a/controllers/admin/serverConfig.go +++ b/controllers/admin/serverConfig.go @@ -5,6 +5,7 @@ import ( "net/http" "github.com/owncast/owncast/config" + log "github.com/sirupsen/logrus" ) // GetServerConfig gets the config details of the server. @@ -35,7 +36,10 @@ func GetServerConfig(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(response) + err := json.NewEncoder(w).Encode(response) + if err != nil { + log.Errorln(err) + } } type serverConfigAdminResponse struct { diff --git a/controllers/admin/status.go b/controllers/admin/status.go index 8f2c3b648..2755276e3 100644 --- a/controllers/admin/status.go +++ b/controllers/admin/status.go @@ -7,6 +7,7 @@ import ( "github.com/owncast/owncast/config" "github.com/owncast/owncast/core" "github.com/owncast/owncast/models" + log "github.com/sirupsen/logrus" ) // Status gets the details of the inbound broadcaster. @@ -25,7 +26,10 @@ func Status(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(response) + err := json.NewEncoder(w).Encode(response) + if err != nil { + log.Errorln(err) + } } type adminStatusResponse struct { diff --git a/controllers/admin/viewers.go b/controllers/admin/viewers.go index 8d0d1abb2..8aa93aaf8 100644 --- a/controllers/admin/viewers.go +++ b/controllers/admin/viewers.go @@ -5,11 +5,15 @@ import ( "net/http" "github.com/owncast/owncast/metrics" + log "github.com/sirupsen/logrus" ) // GetViewersOverTime will return the number of viewers at points in time. func GetViewersOverTime(w http.ResponseWriter, r *http.Request) { viewersOverTime := metrics.Metrics.Viewers w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(viewersOverTime) + err := json.NewEncoder(w).Encode(viewersOverTime) + if err != nil { + log.Errorln(err) + } } diff --git a/controllers/chat.go b/controllers/chat.go index 01cb0f87f..175ad296d 100644 --- a/controllers/chat.go +++ b/controllers/chat.go @@ -7,6 +7,7 @@ import ( "github.com/owncast/owncast/core" "github.com/owncast/owncast/models" "github.com/owncast/owncast/router/middleware" + log "github.com/sirupsen/logrus" ) // GetChatMessages gets all of the chat messages. @@ -17,7 +18,10 @@ func GetChatMessages(w http.ResponseWriter, r *http.Request) { case http.MethodGet: messages := core.GetAllChatMessages() - json.NewEncoder(w).Encode(messages) + err := json.NewEncoder(w).Encode(messages) + if err != nil { + log.Errorln(err) + } case http.MethodPost: var message models.ChatMessage if err := json.NewDecoder(r.Body).Decode(&message); err != nil { @@ -30,9 +34,14 @@ func GetChatMessages(w http.ResponseWriter, r *http.Request) { return } - json.NewEncoder(w).Encode(j{"success": true}) + if err := json.NewEncoder(w).Encode(j{"success": true}); err != nil { + internalErrorHandler(w, err) + return + } default: w.WriteHeader(http.StatusNotImplemented) - json.NewEncoder(w).Encode(j{"error": "method not implemented (PRs are accepted)"}) + if err := json.NewEncoder(w).Encode(j{"error": "method not implemented (PRs are accepted)"}); err != nil { + internalErrorHandler(w, err) + } } } diff --git a/controllers/config.go b/controllers/config.go index 84bf90d4d..f30416e7f 100644 --- a/controllers/config.go +++ b/controllers/config.go @@ -14,5 +14,7 @@ func GetWebConfig(w http.ResponseWriter, r *http.Request) { configuration := config.Config.InstanceDetails configuration.Version = config.Config.VersionInfo - json.NewEncoder(w).Encode(configuration) + if err := json.NewEncoder(w).Encode(configuration); err != nil { + badRequestHandler(w, err) + } } diff --git a/controllers/connectedClients.go b/controllers/connectedClients.go index 13c159150..5d9a7c6f2 100644 --- a/controllers/connectedClients.go +++ b/controllers/connectedClients.go @@ -12,5 +12,7 @@ func GetConnectedClients(w http.ResponseWriter, r *http.Request) { clients := core.GetClients() w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(clients) + if err := json.NewEncoder(w).Encode(clients); err != nil { + internalErrorHandler(w, err) + } } diff --git a/controllers/controllers.go b/controllers/controllers.go index 747793b2f..a92c6fad8 100644 --- a/controllers/controllers.go +++ b/controllers/controllers.go @@ -15,7 +15,9 @@ func internalErrorHandler(w http.ResponseWriter, err error) { } w.WriteHeader(http.StatusInternalServerError) - json.NewEncoder(w).Encode(j{"error": err.Error()}) + if err := json.NewEncoder(w).Encode(j{"error": err.Error()}); err != nil { + internalErrorHandler(w, err) + } } func badRequestHandler(w http.ResponseWriter, err error) { @@ -24,7 +26,9 @@ func badRequestHandler(w http.ResponseWriter, err error) { } w.WriteHeader(http.StatusBadRequest) - json.NewEncoder(w).Encode(j{"error": err.Error()}) + if err := json.NewEncoder(w).Encode(j{"error": err.Error()}); err != nil { + internalErrorHandler(w, err) + } } func WriteSimpleResponse(w http.ResponseWriter, success bool, message string) { @@ -33,5 +37,7 @@ func WriteSimpleResponse(w http.ResponseWriter, success bool, message string) { Message: message, } w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(response) + if err := json.NewEncoder(w).Encode(response); err != nil { + internalErrorHandler(w, err) + } } diff --git a/controllers/emoji.go b/controllers/emoji.go index dd7c8f2b4..9eb8e95fc 100644 --- a/controllers/emoji.go +++ b/controllers/emoji.go @@ -35,9 +35,11 @@ func GetCustomEmoji(w http.ResponseWriter, r *http.Request) { for _, f := range files { name := strings.TrimSuffix(f.Name(), path.Ext(f.Name())) emojiPath := filepath.Join(emojiDir, f.Name()) - singleEmoji := models.CustomEmoji{name, emojiPath} + singleEmoji := models.CustomEmoji{Name: name, Emoji: emojiPath} emojiList = append(emojiList, singleEmoji) } - json.NewEncoder(w).Encode(emojiList) + if err := json.NewEncoder(w).Encode(emojiList); err != nil { + internalErrorHandler(w, err) + } } diff --git a/controllers/status.go b/controllers/status.go index 5e8841aeb..5f89f5145 100644 --- a/controllers/status.go +++ b/controllers/status.go @@ -15,5 +15,7 @@ func GetStatus(w http.ResponseWriter, r *http.Request) { status := core.GetStatus() w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(status) + if err := json.NewEncoder(w).Encode(status); err != nil { + internalErrorHandler(w, err) + } } diff --git a/core/chat/chat.go b/core/chat/chat.go index 88879606a..fc10dbc60 100644 --- a/core/chat/chat.go +++ b/core/chat/chat.go @@ -40,11 +40,8 @@ func Start() error { ticker := time.NewTicker(30 * time.Second) go func() { - for { - select { - case <-ticker.C: - _server.ping() - } + for range ticker.C { + _server.ping() } }() diff --git a/core/chat/client.go b/core/chat/client.go index 773753253..1ce80b04d 100644 --- a/core/chat/client.go +++ b/core/chat/client.go @@ -94,13 +94,21 @@ func (c *Client) listenWrite() { select { // Send a PING keepalive case msg := <-c.pingch: - websocket.JSON.Send(c.ws, msg) + err := websocket.JSON.Send(c.ws, msg) + if err != nil { + log.Errorln(err) + } // send message to the client case msg := <-c.ch: - // log.Println("Send:", msg) - websocket.JSON.Send(c.ws, msg) + err := websocket.JSON.Send(c.ws, msg) + if err != nil { + log.Errorln(err) + } case msg := <-c.usernameChangeChannel: - websocket.JSON.Send(c.ws, msg) + err := websocket.JSON.Send(c.ws, msg) + if err != nil { + log.Errorln(err) + } // receive done request case <-c.doneCh: _server.remove(c) @@ -114,7 +122,6 @@ func (c *Client) listenWrite() { func (c *Client) listenRead() { for { select { - // receive done request case <-c.doneCh: _server.remove(c) diff --git a/core/chat/persistence.go b/core/chat/persistence.go index b5a5929a3..13b60f16e 100644 --- a/core/chat/persistence.go +++ b/core/chat/persistence.go @@ -32,7 +32,10 @@ func createTable() { log.Fatal(err) } defer stmt.Close() - stmt.Exec() + _, err = stmt.Exec() + if err != nil { + log.Warnln(err) + } } func addMessage(message models.ChatMessage) { @@ -41,16 +44,20 @@ func addMessage(message models.ChatMessage) { log.Fatal(err) } stmt, err := tx.Prepare("INSERT INTO messages(id, author, body, messageType, visible, timestamp) values(?, ?, ?, ?, ?, ?)") + if err != nil { log.Fatal(err) } + defer stmt.Close() + _, err = stmt.Exec(message.ID, message.Author, message.Body, message.MessageType, 1, message.Timestamp) if err != nil { log.Fatal(err) } - tx.Commit() - - defer stmt.Close() + err = tx.Commit() + if err != nil { + log.Fatal(err) + } } func getChatHistory() []models.ChatMessage { @@ -89,5 +96,9 @@ func getChatHistory() []models.ChatMessage { history = append(history, message) } + if err := rows.Err(); err != nil { + log.Fatal(err) + } + return history } diff --git a/core/chat/server.go b/core/chat/server.go index 144708942..943987a4f 100644 --- a/core/chat/server.go +++ b/core/chat/server.go @@ -46,11 +46,6 @@ func (s *server) SendToAll(msg models.ChatMessage) { s.sendAllCh <- msg } -// Done marks the server as done. -func (s *server) done() { - s.doneCh <- true -} - // Err handles an error. func (s *server) err(err error) { s.errCh <- err @@ -140,18 +135,7 @@ func (s *server) sendWelcomeMessageToClient(c *Client) { time.Sleep(7 * time.Second) initialChatMessageText := fmt.Sprintf("Welcome to %s! %s", config.Config.InstanceDetails.Title, config.Config.InstanceDetails.Summary) - initialMessage := models.ChatMessage{"owncast-server", config.Config.InstanceDetails.Name, initialChatMessageText, "initial-message-1", "SYSTEM", true, time.Now()} + initialMessage := models.ChatMessage{ClientID: "owncast-server", Author: config.Config.InstanceDetails.Name, Body: initialChatMessageText, ID: "initial-message-1", MessageType: "SYSTEM", Visible: true, Timestamp: time.Now()} c.Write(initialMessage) }() - -} - -func (s *server) getClientForClientID(clientID string) *Client { - for _, client := range s.Clients { - if client.ClientID == clientID { - return client - } - } - - return nil } diff --git a/core/core.go b/core/core.go index 5bdbafd14..9be362999 100644 --- a/core/core.go +++ b/core/core.go @@ -99,7 +99,10 @@ func transitionToOfflineVideoStreamContent() { _transcoder.Start() // Copy the logo to be the thumbnail - utils.Copy(filepath.Join("webroot", config.Config.InstanceDetails.Logo.Large), "webroot/thumbnail.jpg") + err := utils.Copy(filepath.Join("webroot", config.Config.InstanceDetails.Logo.Large), "webroot/thumbnail.jpg") + if err != nil { + log.Warnln(err) + } // Delete the preview Gif os.Remove(path.Join(config.WebRoot, "preview.gif")) @@ -111,8 +114,15 @@ func resetDirectories() { // Wipe the public, web-accessible hls data directory os.RemoveAll(config.PublicHLSStoragePath) os.RemoveAll(config.PrivateHLSStoragePath) - os.MkdirAll(config.PublicHLSStoragePath, 0777) - os.MkdirAll(config.PrivateHLSStoragePath, 0777) + err := os.MkdirAll(config.PublicHLSStoragePath, 0777) + if err != nil { + log.Fatalln(err) + } + + err = os.MkdirAll(config.PrivateHLSStoragePath, 0777) + if err != nil { + log.Fatalln(err) + } // Remove the previous thumbnail os.Remove(filepath.Join(config.WebRoot, "thumbnail.jpg")) @@ -120,14 +130,31 @@ func resetDirectories() { // Create private hls data dirs if len(config.Config.VideoSettings.StreamQualities) != 0 { for index := range config.Config.VideoSettings.StreamQualities { - os.MkdirAll(path.Join(config.PrivateHLSStoragePath, strconv.Itoa(index)), 0777) - os.MkdirAll(path.Join(config.PublicHLSStoragePath, strconv.Itoa(index)), 0777) + err = os.MkdirAll(path.Join(config.PrivateHLSStoragePath, strconv.Itoa(index)), 0777) + if err != nil { + log.Fatalln(err) + } + + err = os.MkdirAll(path.Join(config.PublicHLSStoragePath, strconv.Itoa(index)), 0777) + if err != nil { + log.Fatalln(err) + } } } else { - os.MkdirAll(path.Join(config.PrivateHLSStoragePath, strconv.Itoa(0)), 0777) - os.MkdirAll(path.Join(config.PublicHLSStoragePath, strconv.Itoa(0)), 0777) + err = os.MkdirAll(path.Join(config.PrivateHLSStoragePath, strconv.Itoa(0)), 0777) + if err != nil { + log.Fatalln(err) + } + + err = os.MkdirAll(path.Join(config.PublicHLSStoragePath, strconv.Itoa(0)), 0777) + if err != nil { + log.Fatalln(err) + } } // Remove the previous thumbnail - utils.Copy(config.Config.InstanceDetails.Logo.Large, "webroot/thumbnail.jpg") + err = utils.Copy(path.Join(config.WebRoot, config.Config.InstanceDetails.Logo.Large), "webroot/thumbnail.jpg") + if err != nil { + log.Warnln(err) + } } diff --git a/core/ffmpeg/fileWriterReceiverService.go b/core/ffmpeg/fileWriterReceiverService.go index 7dd189648..febfd261f 100644 --- a/core/ffmpeg/fileWriterReceiverService.go +++ b/core/ffmpeg/fileWriterReceiverService.go @@ -60,14 +60,14 @@ func (s *FileWriterReceiverService) uploadHandler(w http.ResponseWriter, r *http f, err := os.Create(writePath) if err != nil { - returnError(err, w, r) + returnError(err, w) return } defer f.Close() _, err = f.Write(data) if err != nil { - returnError(err, w, r) + returnError(err, w) return } @@ -82,7 +82,6 @@ func (s *FileWriterReceiverService) fileWritten(path string) { if utils.GetRelativePathFromAbsolutePath(path) == "hls/stream.m3u8" { s.callbacks.MasterPlaylistWritten(path) - } else if strings.HasSuffix(path, ".ts") { performanceMonitorKey := "segmentWritten-" + index averagePerformance := utils.GetAveragePerformance(performanceMonitorKey) @@ -98,13 +97,12 @@ func (s *FileWriterReceiverService) fileWritten(path string) { } else { _inWarningState = false } - } else if strings.HasSuffix(path, ".m3u8") { s.callbacks.VariantPlaylistWritten(path) } } -func returnError(err error, w http.ResponseWriter, r *http.Request) { +func returnError(err error, w http.ResponseWriter) { log.Errorln(err) http.Error(w, http.StatusText(http.StatusInternalServerError)+": "+err.Error(), http.StatusInternalServerError) } diff --git a/core/rtmp/rtmp.go b/core/rtmp/rtmp.go index 22843190e..3830a71ac 100644 --- a/core/rtmp/rtmp.go +++ b/core/rtmp/rtmp.go @@ -90,7 +90,12 @@ func HandleConn(c *rtmp.Conn, nc net.Conn) { log.Infoln("Incoming RTMP connected.") pipePath := utils.GetTemporaryPipePath() - syscall.Mkfifo(pipePath, 0666) + if !utils.DoesFileExists(pipePath) { + err := syscall.Mkfifo(pipePath, 0666) + if err != nil { + log.Fatalln(err) + } + } _hasInboundRTMPConnection = true _setStreamAsConnected() @@ -119,7 +124,6 @@ func HandleConn(c *rtmp.Conn, nc net.Conn) { panic(err) } } - } func handleDisconnect(conn net.Conn) { diff --git a/core/rtmp/utils.go b/core/rtmp/utils.go index a3344bc3c..c4abcaf95 100644 --- a/core/rtmp/utils.go +++ b/core/rtmp/utils.go @@ -6,8 +6,8 @@ import ( "fmt" "regexp" - "github.com/owncast/owncast/models" "github.com/nareix/joy5/format/flv/flvio" + "github.com/owncast/owncast/models" ) func getInboundDetailsFromMetadata(metadata []interface{}) (models.RTMPStreamMetadata, error) { @@ -21,8 +21,8 @@ func getInboundDetailsFromMetadata(metadata []interface{}) (models.RTMPStreamMet metadataJSONString := submatchall[0] var details models.RTMPStreamMetadata - json.Unmarshal([]byte(metadataJSONString), &details) - return details, nil + err := json.Unmarshal([]byte(metadataJSONString), &details) + return details, err } func getAudioCodec(codec interface{}) string { diff --git a/core/stats.go b/core/stats.go index 6125a530f..d7392ae7a 100644 --- a/core/stats.go +++ b/core/stats.go @@ -29,12 +29,9 @@ func setupStats() error { statsSaveTimer := time.NewTicker(1 * time.Minute) go func() { - for { - select { - case <-statsSaveTimer.C: - if err := saveStatsToFile(); err != nil { - panic(err) - } + for range statsSaveTimer.C { + if err := saveStatsToFile(); err != nil { + panic(err) } } }() @@ -137,12 +134,12 @@ func getSavedStats() (models.Stats, error) { jsonFile, err := ioutil.ReadFile(config.StatsFile) if err != nil { - return result, nil + return result, err } if err := json.Unmarshal(jsonFile, &result); err != nil { - return result, nil + return result, err } - return result, nil + return result, err } diff --git a/core/storage.go b/core/storage.go index f4155ecac..b0dedc9d9 100644 --- a/core/storage.go +++ b/core/storage.go @@ -5,10 +5,6 @@ import ( "github.com/owncast/owncast/core/storageproviders" ) -var ( - usingExternalStorage = false -) - func setupStorage() error { handler.Storage = _storage diff --git a/core/storageproviders/local.go b/core/storageproviders/local.go index 8753d7f75..67e9d56c2 100644 --- a/core/storageproviders/local.go +++ b/core/storageproviders/local.go @@ -23,11 +23,8 @@ func (s *LocalStorage) Setup() error { // as all HLS segments have to be publicly available on disk to keep a recording of them. _onlineCleanupTicker = time.NewTicker(1 * time.Minute) go func() { - for { - select { - case <-_onlineCleanupTicker.C: - ffmpeg.CleanupOldContent(config.PublicHLSStoragePath) - } + for range _onlineCleanupTicker.C { + ffmpeg.CleanupOldContent(config.PublicHLSStoragePath) } }() return nil @@ -35,7 +32,10 @@ func (s *LocalStorage) Setup() error { // SegmentWritten is called when a single segment of video is written. func (s *LocalStorage) SegmentWritten(localFilePath string) { - s.Save(localFilePath, 0) + _, err := s.Save(localFilePath, 0) + if err != nil { + log.Warnln(err) + } } // VariantPlaylistWritten is called when a variant hls playlist is written. @@ -49,7 +49,10 @@ func (s *LocalStorage) VariantPlaylistWritten(localFilePath string) { // MasterPlaylistWritten is called when the master hls playlist is written. func (s *LocalStorage) MasterPlaylistWritten(localFilePath string) { - s.Save(localFilePath, 0) + _, err := s.Save(localFilePath, 0) + if err != nil { + log.Warnln(err) + } } // Save will save a local filepath using the storage provider. @@ -63,7 +66,6 @@ func (s *LocalStorage) Save(filePath string, retryCount int) (string, error) { newPath = filepath.Join(config.WebRoot, filePath) } - utils.Copy(filePath, newPath) - - return newPath, nil + err := utils.Copy(filePath, newPath) + return newPath, err } diff --git a/core/storageproviders/s3Storage.go b/core/storageproviders/s3Storage.go index 0a5c78560..8d7757b88 100644 --- a/core/storageproviders/s3Storage.go +++ b/core/storageproviders/s3Storage.go @@ -22,7 +22,7 @@ import ( // If we try to upload a playlist but it is not yet on disk // then keep a reference to it here. -var _queuedPlaylistUpdates = make(map[string]string, 0) +var _queuedPlaylistUpdates = make(map[string]string) // S3Storage is the s3 implementation of the ChunkStorageProvider. type S3Storage struct { @@ -118,7 +118,10 @@ func (s *S3Storage) VariantPlaylistWritten(localFilePath string) { // MasterPlaylistWritten is called when the master hls playlist is written. func (s *S3Storage) MasterPlaylistWritten(localFilePath string) { // Rewrite the playlist to use absolute remote S3 URLs - s.rewriteRemotePlaylist(localFilePath) + err := s.rewriteRemotePlaylist(localFilePath) + if err != nil { + log.Warnln(err) + } } // Save saves the file to the s3 bucket. @@ -192,6 +195,9 @@ func (s *S3Storage) rewriteRemotePlaylist(filePath string) error { p := m3u8.NewMasterPlaylist() err = p.DecodeFrom(bufio.NewReader(f), false) + if err != nil { + log.Warnln(err) + } for _, item := range p.Variants { item.URI = s.host + filepath.Join("/hls", item.URI) diff --git a/core/streamState.go b/core/streamState.go index 5df5dd812..b23aa25f5 100644 --- a/core/streamState.go +++ b/core/streamState.go @@ -26,8 +26,8 @@ var _onlineCleanupTicker *time.Ticker // setStreamAsConnected sets the stream as connected. func setStreamAsConnected() { _stats.StreamConnected = true - _stats.LastConnectTime = utils.NullTime{time.Now(), true} - _stats.LastDisconnectTime = utils.NullTime{time.Now(), false} + _stats.LastConnectTime = utils.NullTime{Time: time.Now(), Valid: true} + _stats.LastDisconnectTime = utils.NullTime{Time: time.Now(), Valid: false} StopOfflineCleanupTimer() startOnlineCleanupTimer() @@ -44,7 +44,6 @@ func setStreamAsConnected() { go func() { _transcoder = ffmpeg.NewTranscoder() _transcoder.TranscoderCompleted = func(error) { - SetStreamAsDisconnected() } _transcoder.Start() @@ -56,7 +55,7 @@ func setStreamAsConnected() { // SetStreamAsDisconnected sets the stream as disconnected. func SetStreamAsDisconnected() { _stats.StreamConnected = false - _stats.LastDisconnectTime = utils.NullTime{time.Now(), true} + _stats.LastDisconnectTime = utils.NullTime{Time: time.Now(), Valid: true} _broadcaster = nil offlineFilename := "offline.ts" @@ -73,9 +72,14 @@ func SetStreamAsDisconnected() { playlistFilePath := fmt.Sprintf(filepath.Join(config.PrivateHLSStoragePath, "%d/stream.m3u8"), index) segmentFilePath := fmt.Sprintf(filepath.Join(config.PrivateHLSStoragePath, "%d/%s"), index, offlineFilename) - utils.Copy(offlineFilePath, segmentFilePath) - _storage.Save(segmentFilePath, 0) - + err := utils.Copy(offlineFilePath, segmentFilePath) + if err != nil { + log.Warnln(err) + } + _, err = _storage.Save(segmentFilePath, 0) + if err != nil { + log.Warnln(err) + } if utils.DoesFileExists(playlistFilePath) { f, err := os.OpenFile(playlistFilePath, os.O_CREATE|os.O_RDWR, os.ModePerm) if err != nil { @@ -84,13 +88,23 @@ func SetStreamAsDisconnected() { defer f.Close() playlist, _, err := m3u8.DecodeFrom(bufio.NewReader(f), true) + if err != nil { + log.Fatalln(err) + } + variantPlaylist := playlist.(*m3u8.MediaPlaylist) if len(variantPlaylist.Segments) > config.Config.GetMaxNumberOfReferencedSegmentsInPlaylist() { variantPlaylist.Segments = variantPlaylist.Segments[:len(variantPlaylist.Segments)] } err = variantPlaylist.Append(offlineFilename, 8.0, "") - variantPlaylist.SetDiscontinuity() + if err != nil { + log.Fatalln(err) + } + err = variantPlaylist.SetDiscontinuity() + if err != nil { + log.Fatalln(err) + } _, err = f.WriteAt(variantPlaylist.Encode().Bytes(), 0) if err != nil { log.Errorln(err) @@ -118,7 +132,10 @@ func SetStreamAsDisconnected() { log.Errorln(err) } } - _storage.Save(playlistFilePath, 0) + _, err = _storage.Save(playlistFilePath, 0) + if err != nil { + log.Warnln(err) + } } StartOfflineCleanupTimer() @@ -129,14 +146,11 @@ func SetStreamAsDisconnected() { func StartOfflineCleanupTimer() { _offlineCleanupTimer = time.NewTimer(5 * time.Minute) go func() { - for { - select { - case <-_offlineCleanupTimer.C: - // Reset the session count since the session is over - _stats.SessionMaxViewerCount = 0 - resetDirectories() - transitionToOfflineVideoStreamContent() - } + for range _offlineCleanupTimer.C { + // Reset the session count since the session is over + _stats.SessionMaxViewerCount = 0 + resetDirectories() + transitionToOfflineVideoStreamContent() } }() } @@ -151,11 +165,8 @@ func StopOfflineCleanupTimer() { func startOnlineCleanupTimer() { _onlineCleanupTicker = time.NewTicker(1 * time.Minute) go func() { - for { - select { - case <-_onlineCleanupTicker.C: - ffmpeg.CleanupOldContent(config.PrivateHLSStoragePath) - } + for range _onlineCleanupTicker.C { + ffmpeg.CleanupOldContent(config.PrivateHLSStoragePath) } }() } diff --git a/geoip/geoip.go b/geoip/geoip.go index 212120225..4898396a3 100644 --- a/geoip/geoip.go +++ b/geoip/geoip.go @@ -80,5 +80,4 @@ func FetchGeoForIP(ip string) { _geoIPCache[ip] = response }() - } diff --git a/main.go b/main.go index bcd90faf1..d6d197046 100644 --- a/main.go +++ b/main.go @@ -31,7 +31,7 @@ func main() { log.Infoln(getReleaseString()) // Enable bundling of admin assets - pkger.Include("/admin") + _ = pkger.Include("/admin") configFile := flag.String("configFile", "config.yaml", "Config File full path. Defaults to current folder") dbFile := flag.String("database", "", "Path to the database file.") @@ -67,13 +67,11 @@ func main() { // starts the core if err := core.Start(); err != nil { - log.Error("failed to start the core package") - panic(err) + log.Fatalln("failed to start the core package", err) } if err := router.Start(); err != nil { - log.Error("failed to start/run the router") - panic(err) + log.Fatalln("failed to start/run the router", err) } } diff --git a/metrics/alerting.go b/metrics/alerting.go index 08994cbeb..674dd5d18 100644 --- a/metrics/alerting.go +++ b/metrics/alerting.go @@ -51,5 +51,5 @@ func handleDiskAlerting() { } func recentAverage(values []timestampedValue) int { - return int((values[len(values)-1].Value + values[len(values)-2].Value) / 2) + return (values[len(values)-1].Value + values[len(values)-2].Value) / 2 } diff --git a/router/router.go b/router/router.go index a5c148f94..bb9f7bc8d 100644 --- a/router/router.go +++ b/router/router.go @@ -29,7 +29,12 @@ func Start() error { http.HandleFunc("/api/emoji", controllers.GetCustomEmoji) // websocket chat server - go chat.Start() + go func() { + err := chat.Start() + if err != nil { + log.Fatalln(err) + } + }() // chat rest api http.HandleFunc("/api/chat", controllers.GetChatMessages) diff --git a/utils/clientId.go b/utils/clientId.go index 41947536a..2256d4743 100644 --- a/utils/clientId.go +++ b/utils/clientId.go @@ -1,7 +1,7 @@ package utils import ( - "crypto/md5" + "crypto/md5" //nolint "encoding/hex" "net" "net/http" @@ -18,9 +18,8 @@ func GenerateClientIDFromRequest(req *http.Request) string { clientID := strings.Join(ipAddressComponents, ":") + req.UserAgent() // Create a MD5 hash of this ip + useragent - hasher := md5.New() - hasher.Write([]byte(clientID)) - return hex.EncodeToString(hasher.Sum(nil)) + b := md5.Sum([]byte(clientID)) // nolint + return hex.EncodeToString(b[:]) } // GetIPAddressFromRequest returns the IP address from a http request. diff --git a/utils/nulltime.go b/utils/nulltime.go index e5ec931fc..71df254a4 100644 --- a/utils/nulltime.go +++ b/utils/nulltime.go @@ -17,7 +17,7 @@ func (nt *NullTime) Scan(value interface{}) error { return nil } -// Value implements the driver Valuer interface. +// Value implements the driver Value interface. func (nt NullTime) Value() (driver.Value, error) { if !nt.Valid { return nil, nil @@ -32,3 +32,19 @@ func (nt NullTime) MarshalJSON() ([]byte, error) { val := fmt.Sprintf("\"%s\"", nt.Time.Format(time.RFC3339)) return []byte(val), nil } + +func (nt NullTime) UnmarshalJSON(data []byte) error { + dateString := string(data) + if dateString == "null" { + return nil + } + + dateStringWithoutQuotes := dateString[1 : len(dateString)-1] + parsedDateTime, err := time.Parse(time.RFC3339, dateStringWithoutQuotes) + if err != nil { + return err + } + + nt.Time = parsedDateTime + return nil +} diff --git a/utils/utils.go b/utils/utils.go index 54ba79621..4a9693a8f 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -54,7 +54,7 @@ func Copy(source, destination string) error { return err } - return ioutil.WriteFile(destination, input, 0644) + return ioutil.WriteFile(destination, input, 0600) } // Move moves the file to destination. diff --git a/yp/api.go b/yp/api.go index 12a0d160e..1262d7546 100644 --- a/yp/api.go +++ b/yp/api.go @@ -6,6 +6,7 @@ import ( "github.com/owncast/owncast/config" "github.com/owncast/owncast/utils" + log "github.com/sirupsen/logrus" ) type ypDetailsResponse struct { @@ -41,6 +42,8 @@ func GetYPResponse(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(response) - + err := json.NewEncoder(w).Encode(response) + if err != nil { + log.Errorln(err) + } } diff --git a/yp/yp.go b/yp/yp.go index 59c201371..5d2f20016 100644 --- a/yp/yp.go +++ b/yp/yp.go @@ -47,15 +47,9 @@ func NewYP(getStatusFunc func() models.Status) *YP { // Start is run when a live stream begins to start pinging YP. func (yp *YP) Start() { yp.timer = time.NewTicker(pingInterval) - - go func() { - for { - select { - case <-yp.timer.C: - yp.ping() - } - } - }() + for range yp.timer.C { + yp.ping() + } yp.ping() } @@ -92,7 +86,7 @@ func (yp *YP) ping() { } pingURL := config.Config.GetYPServiceHost() + "/ping" - resp, err := http.Post(pingURL, "application/json", bytes.NewBuffer(req)) + resp, err := http.Post(pingURL, "application/json", bytes.NewBuffer(req)) //nolint if err != nil { log.Errorln(err) return @@ -105,7 +99,10 @@ func (yp *YP) ping() { } pingResponse := ypPingResponse{} - json.Unmarshal(body, &pingResponse) + err = json.Unmarshal(body, &pingResponse) + if err != nil { + log.Errorln(err) + } if !pingResponse.Success { if !_inErrorState {