/* 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() }
/* sourceHandler is the handler for icecast source clients. It acknowledges the client before sending it over to the icecast manager. */ func sourceHandler(w http.ResponseWriter, r *http.Request, clientID *ClientID) { /* Handler for icecast source requests. This can only be called by authenticated requests */ // Icecast clients expect a 200 OK response before sending data. w.WriteHeader(http.StatusOK) // Make sure to send the extra newline to signify end of headers io.WriteString(w, "\r\n") // And flush the data because buffering is FUN! if flush, ok := w.(http.Flusher); ok { flush.Flush() } // We can now start hijacking the connection hj, ok := w.(http.Hijacker) if !ok { http.Error(w, "Webserver doesn't support hijacking.", http.StatusInternalServerError) return } conn, bufrw, err := hj.Hijack() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Create a client struct, this is defined in client.go client := NewClient(conn, bufrw, clientID) ClientManager.Receiver <- client // The manager will handle everything from this point on return }
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)) }