package icecast_input import ( "io" "strconv" "git.icedream.tech/icedream/uplink/app/authentication" "git.icedream.tech/icedream/uplink/app/channels" "git.icedream.tech/icedream/uplink/app/servers/http" "git.icedream.tech/icedream/uplink/app/streams" "github.com/gin-gonic/gin" ) var allowedCopyHeaders = []string{ "icy-br", "icy-name", "icy-description", "icy-pub", "icy-url", "icy-genre", } type pluginInstance struct { server *httpserver.Server authenticator authentication.Authenticator channelManager *channels.ChannelManager } func (instance *pluginInstance) SetAuthenticator(authenticator authentication.Authenticator) { instance.authenticator = authenticator } func (instance *pluginInstance) SetChannelManager(channelManager *channels.ChannelManager) { instance.channelManager = channelManager } func (instance *pluginInstance) SetServer(server *httpserver.Server) { instance.server = server } func (instance *pluginInstance) Init() { router := instance.server.Router router.PUT("/:channel", func(ctx *gin.Context) { channel := instance.channelManager.Channel(ctx.Param("channel")) if channel == nil { ctx.Status(404) return } if user, password, ok := ctx.Request.BasicAuth(); ok { if !instance.authenticator.VerifyUsernameAndPassword(channel, user, password) { ctx.Status(401) return } } else { ctx.Status(401) return } var sr io.Reader = ctx.Request.Body defer ctx.Request.Body.Close() if ctx.GetHeader("icy-metadata") == "1" { metaInt64, err := strconv.ParseInt(ctx.GetHeader("icy-metaint"), 10, 32) if err != nil { ctx.Status(400) return } metaInt := int(metaInt64) // Client is sending metadata! mr := streams.NewMetadataExtractor(sr, metaInt) sr = mr metadataChan := channel.Metadata() defer func() { metadataChan <- nil }() go func() { for metadata := range metadataChan { metadataToWrite := streams.Metadata{} if value, ok := metadata["StreamTitle"]; ok { metadataToWrite["StreamTitle"] = value } channel.SetMetadata(metadataToWrite) } }() } input := channel.AddInputStream("icecast") io.Copy(input, sr) }) }