//setupPurgeReceiver set up the tcp socket where ban messages come //when a purge pattern is received it dispatches it to a Pub object func setupPurgeReceiver(incomingAddress *string, publisher *Publisher) { receiver, err := net.Listen("tcp", *incomingAddress) utils.CheckError(err, logger) go func() { ping := []byte("ping") for { time.Sleep(5 * time.Second) publisher.Pub(ping) } }() for { conn, err := receiver.Accept() utils.CheckError(err, logger) go func(c net.Conn) { defer conn.Close() b, err := ioutil.ReadAll(conn) if err != nil { logger.Info(fmt.Sprintln("Client connection error:", err)) } else { clean_purge := bytes.TrimSpace(b) logger.Info(fmt.Sprintln("<-", utils.ReverseName(conn), string(clean_purge))) publisher.Pub(clean_purge) conn.Write([]byte("OK\n")) } }(conn) } }
func control_server(port string, basic_auth string) { fmt.Println("icecast/shoutcast server running on port ", port) tcpAddr, err := net.ResolveTCPAddr("tcp4", port) utils.CheckError(err) listener, err := net.ListenTCP("tcp", tcpAddr) utils.CheckError(err) for { conn, err := listener.Accept() if err != nil { continue } go control_server_handle(conn, basic_auth) } }
//setupPurgeSenderAndListen start listening to the socket where varnish cli connects //when a client connects it calls handleClient func setupPurgeSenderAndListen(outgoingAddress *string, purgeOnStartup bool, publisher *Publisher, secret *string) { ln, err := net.Listen("tcp", *outgoingAddress) utils.CheckError(err, logger) for { conn, err := ln.Accept() if err != nil { // handle error continue } logger.Info(fmt.Sprintln("New client:", utils.ReverseName(conn))) // connect client to the pubsub purge go handleVarnishClient(conn, publisher, purgeOnStartup, secret) } }
func control_server_handle(conn net.Conn, basic_auth string) { povezava := new(Audiocast) if *_DEBUGME { log.Println("client", conn.RemoteAddr(), "connected") } for { req, err := http.ReadRequest(bufio.NewReader(conn)) if err != nil { conn.Write([]byte("HTTP/1.0 500 Error\r\n\r\n")) utils.CheckError(err) break } //chech for authorization auth := req.Header.Get("Authorization") if len(auth) != 0 && len(basic_auth) > 1 { if !strings.Contains(auth, "Basic "+basic_auth) { conn.Write([]byte("HTTP/1.0 402 Not Authorized\r\n\r\nDon't poke here!")) break } } else if len(basic_auth) > 1 { conn.Write([]byte("HTTP/1.0 401 Not Authorized\r\nWWW-Authenticate: Basic realm=\"Icecast Server\"r\n")) break } if req.Method == "SOURCE" { //check for streams limit if len(povezave) >= 16 { conn.Write([]byte("HTTP/1.0 405 Too many streams\r\n\r\nToo many streams")) break } (*povezava).Type = req.Header.Get("Content-Type") (*povezava).Name = req.Header.Get("Ice-Name") (*povezava).Description = req.Header.Get("Ice-Description") (*povezava).Audio = req.Header.Get("Ice-Audio-Info") povezave[req.URL.Path] = *povezava //icecast 1 update parseOGG(conn, povezava) //utils.Cleanup delete(povezave, req.URL.Path) break } else if req.Method == "GET" && req.URL.Path == "/admin/metadata" { parseMetadataUpdate(conn, req) break } else { conn.Write([]byte("HTTP/1.0 405 Method not allowed\r\n\r\nMethod not allowed")) break } } if *_DEBUGME { log.Println("client", conn.RemoteAddr(), "disconnected") } conn.Close() }