//websocket main handler func wsMain(ws *websocket.Conn) { defer ws.Close() wsCtx := newWSContext(ws) var msg string for { //read message err := websocket.Message.Receive(ws, &msg) if err != nil { break } log.Debug("[wsMain]endpoint's msg = " + msg) //parse message wsMsg, err := NewEndptMsgFromStr(msg) if err != nil { log.Error("[wsMain]failed to unmarshal json :" + err.Error()) continue } wsCtx.UserID = wsMsg.UserID if wsMsg.Domain == "irc" && wsCtx.LoggedIn { ClientDoIRCCmd(wsMsg, ws) } else { dispatchBoksHandler(wsCtx, wsMsg) } } if wsCtx.LoggedIn { UserLogout(wsCtx.UserID, ws) } log.Debug("[wsMain]endpoint exited") }
func NewMapHandler(paths map[string]string) (handler http.Handler, err error) { h := mapHandler{ templatePaths: make(map[string]*template.Template), staticPaths: make(map[string][]byte)} for path, data := range paths { log.Debug("Parsing in web asset %s", path) dataBytes, err := hex.DecodeString(data) if err != nil { return nil, err } switch { case strings.HasPrefix(path, "templates/"): log.Debug("Parsing in templated web asset glob %s", path) t, err := template.New(path).Parse(string(dataBytes)) if err != nil { return nil, fmt.Errorf("Error parsing %s: %s", path, err) } log.Debug("Adding templated asset %s to lookup", path) h.templatePaths[path] = t default: log.Debug("Adding static asset %s to lookup", path) h.staticPaths[path] = dataBytes } } return h, nil }
//MsgHistChannel get message history of a channel //It will fetch message history from the latest to oldest func MsgHistChannel(em *EndptMsg, ws *websocket.Conn) { channel, ok := em.GetDataString("channel") if !ok { log.Error("MsgHistChannel() null channel") return } log.Debug("[MsgHistChannel] userId=" + em.UserID + ".channel = " + channel) i := 0 for { var res []MessageHist query := bson.M{"userId": em.UserID, "target": channel} err := DBQueryArr("ircboks", "msghist", query, "-timestamp", 50, 50*i, &res) if err != nil { log.Error("[MsgHistChannel]fetching channel history:" + err.Error()) return } m := map[string]interface{}{ "logs": res, "channel": channel, } //send the result websocket.Message.Send(ws, jsonMarshal("msghistChannel", m)) if len(res) == 0 || res[len(res)-1].ReadFlag == true { break } i = i + 1 } }
func ReceiveChanges(changes chan gitsync.GitChange, webPort uint16, repo gitsync.Repo) { log.Info("webport %d", webPort) var webEvents = make(chan *gitsync.GitChange, 128) if webPort != 0 { go serveWeb(webPort, webEvents) } for { select { case change, ok := <-changes: if !ok { log.Debug("Exiting Loop") break } log.Info("saw %+v", change) if change.FromRepo(repo) { if err := fetchChange(change, repo.Path()); err != nil { log.Info("Error fetching change") } else { log.Info("fetched change") } } if webPort != 0 { select { case webEvents <- &change: default: log.Info("Dropped event %+v from websocket") } } } } }
// serveWeb starts a webserver that can serve a page and websocket events as // they are seen. // It is expected to be run only once and uses the http package global request // router. It does NOT return. func serveWeb(port uint16, events chan *gitsync.GitChange) { // the container for websocket clients, passed into every websocket handler // below var cs = clientSet{ clients: make(map[*websocket.Conn]chan gitsync.GitChange)} // Handle any static files (JS/CSS files) if handler, err := webcontent.NewMapHandler(webcontent.Paths); err != nil { log.Error("Error building templates for web content: %s", err) } else { log.Debug("Registering / handler") http.Handle("/", handler) } // Events endpoint // Note: we wrap the handler in a closure to pass in the clientSet http.Handle("/events", websocket.Handler(func(ws *websocket.Conn) { handleGitChangeWebClient(&cs, ws) })) log.Info("Attempting to spawn webserver on %d", port) go cs.distribute(events) if err := http.ListenAndServe(fmt.Sprintf(":%v", port), nil); err != nil { log.Error("Error listening on %d: %s", port, err) } }
//process JOIN event func (c *IRCClient) processJoined(e *ogric.Event) { if len(e.Arguments) == 0 { log.Error("processJoined() invalid event args len = 0") } else { log.Debug("process join nick=" + e.Nick) channelName := e.Arguments[0] c.chanJoinedSet[channelName] = true } c.forwardEvent(e) }
//UserRegister handle user registration func UserRegister(e *EndptMsg, ws *websocket.Conn) { userID := e.UserID password, ok := e.GetDataString("password") if !ok { websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"failed", "reason":null password"}}`) return } //check if user already exist if isUserExist(userID) { log.Info("[registerUser]User '" + userID + "' already registered") websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"failed", "reason":"email address already registered"}}`) return } log.Info("[registerUser] registering " + userID) hashedPass, err := authHassPassword(password) if err != nil { log.Error("[RegisterUser]:failed to hass password : "******"event":"registrationResult", "data" : {"result":"failed", "reason":"internal error"}}`) return } if len(hashedPass) == 0 { log.Error("[RegisterUser]:failed to hass password : password len = 0") websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"failed", "reason":"invalid password"}}`) return } log.Debug("generated password = "******"mongodb_uri") sess, err := mgo.Dial(uri) if err != nil { log.Error("Can't connect to mongo, go error :" + err.Error()) websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"failed", "reason":"internal DB error"}}`) return } defer sess.Close() sess.SetSafe(&mgo.Safe{}) collection := sess.DB("ircboks").C("user") doc := AuthInfo{bson.NewObjectId(), userID, hashedPass} err = collection.Insert(doc) if err != nil { log.Error("Can't insert new user:"******"event":"registrationResult", "data" : {"result":"failed", "reason":"internal DB error"}}`) return } websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"ok"}}`) }
func (m mapHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { var ( upath = r.URL.Path ctype = mime.TypeByExtension(filepath.Ext(upath)) ) w.Header().Set("Content-Type", ctype) log.Debug("Handling %s", upath) if t, found := m.templatePaths[upath]; found { log.Debug("Found data for %s of type %s", upath, ctype) if err := t.Execute(w, nil); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } else if t, found := m.staticPaths[upath]; found { log.Debug("Found data for %s of type %s", upath, ctype) io.Copy(w, bytes.NewBuffer(t)) } else { log.Debug("Found no data for %s", upath) w.WriteHeader(404) } }
func main() { log.LoadConfiguration("timber.xml") r := mux.NewRouter() r.Handle("/irc/", websocket.Handler(wsMain)) r.PathPrefix("/").Handler(http.FileServer(http.Dir("../ui/build/"))) ContextMapInit() go EndpointPublisher() log.Debug("Starting ircboks server ..") if err := http.ListenAndServe(Config.GetString("host_port"), r); err != nil { log.Error("ListenAndServer error :", err.Error()) } log.Close() }
//DelWs remove a websocket connection from client object func (c *ClientContext) DelWs(ws *websocket.Conn) { //search index idx := -1 for i, v := range c.wsArr { if v == ws { idx = i break } } //del if ws found if idx != -1 { log.Debug("deleting ws for = " + c.UserID) if len(c.wsArr) == 1 { c.wsArr = []*websocket.Conn{} } else { c.wsArr[idx] = c.wsArr[len(c.wsArr)-1] c.wsArr = c.wsArr[:len(c.wsArr)-1] } } }
func clientStart(userID, nick, password, username, server string, ws *websocket.Conn) error { log.Debug("clientStart(). userId=" + userID + ". Nick = " + nick + ". Username = "******". Server = " + server) //create IRC client inChan := make(chan *EndptMsg) client, err := NewIRCClient(userID, nick, password, username, server, inChan) if err != nil { return err } //start IRC client if err = client.Start(); err != nil { return err } //add client context ctx := ContextMap.Add(userID, nick, server, username, inChan, ws) //start client loop go client.Loop(ctx) return nil }
func (log TimberLog) Debug(v ...interface{}) { tl.Debug("", v) }