* fix(s3): scope segment cleanup to path prefix, fix slice panic, batch deletes When a path prefix is configured for S3 storage, uploads correctly write to <prefix>/hls/... but cleanup lists objects from the bucket root without the prefix. This causes a panic when the resulting segment list is empty, due to unsafe slicing with a negative index. - Centralize prefix construction in remoteHLSPrefix() so Save(), retrieveAllVideoSegments(), and rewritePlaylistLocations() all share the same logic. remoteHLSListingPrefix() adds a trailing slash for directory-scoped S3 listing. - Use strings.Trim to normalize both leading and trailing slashes from the configured path prefix. - Replace ListObjects with ListObjectsPages to handle buckets with more than 1000 segments. - Batch DeleteObjects calls in chunks of 1000 to respect the S3 API limit, and log per-object errors from the response. - Guard getDeletableVideoSegmentsWithOffset against empty result sets to prevent the slice bounds panic. Fixes #4784 * fix(s3): handle empty hlsPrefix in rewritePlaylistLocations LocalStorage calls rewritePlaylistLocations with an empty prefix. The previous refactor removed the fallback to "/hls", causing double slashes and missing path segments in playlist URLs. Default hlsPrefix to "hls" when empty to preserve existing behavior for local storage setups with a custom video serving endpoint.
41 lines
950 B
Go
41 lines
950 B
Go
package storageproviders
|
|
|
|
import (
|
|
"bufio"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/grafov/m3u8"
|
|
"github.com/owncast/owncast/config"
|
|
"github.com/owncast/owncast/core/playlist"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// rewritePlaylistLocations will take a local playlist and rewrite it to have absolute URLs to a specified location.
|
|
func rewritePlaylistLocations(localFilePath, remoteServingEndpoint, hlsPrefix string) error {
|
|
f, err := os.Open(localFilePath) // nolint
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
p := m3u8.NewMasterPlaylist()
|
|
if err := p.DecodeFrom(bufio.NewReader(f), false); err != nil {
|
|
log.Warnln(err)
|
|
}
|
|
|
|
if hlsPrefix == "" {
|
|
hlsPrefix = "hls"
|
|
}
|
|
|
|
for _, item := range p.Variants {
|
|
item.URI = remoteServingEndpoint + "/" + hlsPrefix + "/" + item.URI
|
|
}
|
|
|
|
publicPath := filepath.Join(config.HLSStoragePath, filepath.Base(localFilePath))
|
|
|
|
newPlaylist := p.String()
|
|
|
|
return playlist.WritePlaylist(newPlaylist, publicPath)
|
|
}
|