/* adminHandler is called whenever the /admin URL is requested. The two URLs special cased for metadata and listener listing respectively are not included and are handled by different handlers. */ func adminHandler(w http.ResponseWriter, r *http.Request, clientID *ClientID) { HandlerLock.Lock() if r.URL.Path == "/admin" { Body := "" for mount, clients := range HandlerMounts { MountBody := "" for i, c := range clients { name := c.ClientID.Name if i == 0 { name = fmt.Sprintf("<b>%s</b>", c.ClientID.Name) } ClientBody := fmt.Sprintf(ClientHTML, name, c.Metadata, c.ClientID.Agent, mount, i, "") MountBody = MountBody + ClientBody } Body = Body + fmt.Sprintf(MountHTML, mount, MountBody) } w.Write([]byte(fmt.Sprintf(AdminHTML, Body))) } else if r.URL.Path == "/admin/kick" { MountName := r.URL.Query().Get("mount") Id, err := strconv.Atoi(r.URL.Query().Get("num")) if err == nil { clients, ok := HandlerMounts[MountName] if ok { clients[Id].Conn.Close() } } w.Header().Set("Location", "/admin") w.WriteHeader(301) } HandlerLock.Unlock() }
func listclientsHandler(w http.ResponseWriter, r *http.Request, clientID *ClientID) { response := []byte("<?xml version=\"1.0\"?>\n<icestats><source mount=\"" + clientID.Mount + "\"><Listeners>0</Listeners></source></icestats>\n") w.Header().Set("Content-Length", strconv.Itoa(len(response))) w.Write(response) }
func AuthenticationError(w http.ResponseWriter, r *http.Request, err error) { /* Returns an authentication icecast error page when called. */ w.Header().Set("WWW-Authenticate", `Basic realm="`+realm+`"`) w.WriteHeader(401) response := "401 Unauthorized\n" if err != nil { response += err.Error() } w.Write([]byte(response)) }
func metadataHandler(w http.ResponseWriter, r *http.Request, clientID *ClientID) { /* Handles a metadata request from a source. This should make sure an user cannot set the metadata of another users stream and even save metadata of inactive users */ var meta string parsed := r.URL.Query() meta = parsed.Get("song") if meta == "" { // Someone is trying to not update the metadata? // Ignore the f****r return } var charset string if e := parsed.Get("charset"); e != "" { // TODO: Check if user specified encodings are not vulnerable to exploits charset = e } else { charset = "latin1" } // This isn't so much a parser as it is a encoding handler. meta = ParseMetadata(charset, meta) // Sending empty metadata is useless, so we don't if meta != "" { // And we are done here, send the data we have so far along ClientManager.MetaChan <- &MetaPack{Data: meta, ID: clientID, Seen: false} } response := []byte("<?xml version=\"1.0\"?>\n<iceresponse><message>Metadata update successful</message><return>1</return></iceresponse>\n") w.Header().Set("Content-Length", strconv.Itoa(len(response))) w.Write(response) }