2018-04-11 07:35:00 +00:00
|
|
|
package icecast_input
|
2018-04-10 14:34:41 +00:00
|
|
|
|
2018-04-10 15:08:40 +00:00
|
|
|
import (
|
2018-04-10 15:51:03 +00:00
|
|
|
"io"
|
2018-07-02 09:40:11 +00:00
|
|
|
"strconv"
|
2018-04-10 15:51:03 +00:00
|
|
|
|
|
|
|
"git.icedream.tech/icedream/uplink/app/authentication"
|
|
|
|
"git.icedream.tech/icedream/uplink/app/channels"
|
2018-04-10 15:08:40 +00:00
|
|
|
"git.icedream.tech/icedream/uplink/app/servers/http"
|
2018-07-02 09:39:53 +00:00
|
|
|
"git.icedream.tech/icedream/uplink/app/streams"
|
2018-04-10 15:08:40 +00:00
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
)
|
2018-04-10 14:34:41 +00:00
|
|
|
|
2018-07-02 09:40:11 +00:00
|
|
|
var allowedCopyHeaders = []string{
|
|
|
|
"icy-br",
|
|
|
|
"icy-name",
|
|
|
|
"icy-description",
|
|
|
|
"icy-pub",
|
|
|
|
"icy-url",
|
|
|
|
"icy-genre",
|
|
|
|
}
|
|
|
|
|
2018-04-10 14:34:41 +00:00
|
|
|
type pluginInstance struct {
|
2018-04-10 15:51:03 +00:00
|
|
|
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
|
2018-04-10 14:34:41 +00:00
|
|
|
}
|
|
|
|
|
2018-04-10 15:08:40 +00:00
|
|
|
func (instance *pluginInstance) SetServer(server *httpserver.Server) {
|
2018-04-10 14:34:41 +00:00
|
|
|
instance.server = server
|
2018-07-02 09:39:53 +00:00
|
|
|
}
|
2018-04-10 15:08:40 +00:00
|
|
|
|
2018-07-02 09:39:53 +00:00
|
|
|
func (instance *pluginInstance) Init() {
|
2018-04-10 15:08:40 +00:00
|
|
|
router := instance.server.Router
|
2018-04-10 15:51:03 +00:00
|
|
|
|
|
|
|
router.PUT("/:channel", func(ctx *gin.Context) {
|
|
|
|
channel := instance.channelManager.Channel(ctx.Param("channel"))
|
2018-04-10 15:08:40 +00:00
|
|
|
if channel == nil {
|
|
|
|
ctx.Status(404)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if user, password, ok := ctx.Request.BasicAuth(); ok {
|
2018-04-10 15:51:03 +00:00
|
|
|
if !instance.authenticator.VerifyUsernameAndPassword(channel, user, password) {
|
2018-04-10 15:08:40 +00:00
|
|
|
ctx.Status(401)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ctx.Status(401)
|
|
|
|
return
|
|
|
|
}
|
2018-07-02 09:39:53 +00:00
|
|
|
|
2018-07-02 09:40:11 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
2018-07-02 09:39:53 +00:00
|
|
|
input := channel.AddInputStream("icecast")
|
|
|
|
|
|
|
|
io.Copy(input, sr)
|
2018-04-10 15:08:40 +00:00
|
|
|
})
|
2018-04-10 14:34:41 +00:00
|
|
|
}
|