github.com/jlevesy/mattermost-server@v5.3.2-0.20181003190404-7468f35cb0c8+incompatible/app/websocket_router.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "fmt" 8 "net/http" 9 10 "github.com/mattermost/mattermost-server/mlog" 11 "github.com/mattermost/mattermost-server/model" 12 "github.com/mattermost/mattermost-server/utils" 13 ) 14 15 type webSocketHandler interface { 16 ServeWebSocket(*WebConn, *model.WebSocketRequest) 17 } 18 19 type WebSocketRouter struct { 20 app *App 21 handlers map[string]webSocketHandler 22 } 23 24 func (wr *WebSocketRouter) Handle(action string, handler webSocketHandler) { 25 wr.handlers[action] = handler 26 } 27 28 func (wr *WebSocketRouter) ServeWebSocket(conn *WebConn, r *model.WebSocketRequest) { 29 if r.Action == "" { 30 err := model.NewAppError("ServeWebSocket", "api.web_socket_router.no_action.app_error", nil, "", http.StatusBadRequest) 31 ReturnWebSocketError(conn, r, err) 32 return 33 } 34 35 if r.Seq <= 0 { 36 err := model.NewAppError("ServeWebSocket", "api.web_socket_router.bad_seq.app_error", nil, "", http.StatusBadRequest) 37 ReturnWebSocketError(conn, r, err) 38 return 39 } 40 41 if r.Action == model.WEBSOCKET_AUTHENTICATION_CHALLENGE { 42 if conn.GetSessionToken() != "" { 43 return 44 } 45 46 token, ok := r.Data["token"].(string) 47 if !ok { 48 conn.WebSocket.Close() 49 return 50 } 51 52 session, err := wr.app.GetSession(token) 53 54 if err != nil { 55 conn.WebSocket.Close() 56 } else { 57 wr.app.Go(func() { 58 wr.app.SetStatusOnline(session.UserId, false) 59 wr.app.UpdateLastActivityAtIfNeeded(*session) 60 }) 61 62 conn.SetSession(session) 63 conn.SetSessionToken(session.Token) 64 conn.UserId = session.UserId 65 66 wr.app.HubRegister(conn) 67 68 resp := model.NewWebSocketResponse(model.STATUS_OK, r.Seq, nil) 69 conn.Send <- resp 70 } 71 72 return 73 } 74 75 if !conn.IsAuthenticated() { 76 err := model.NewAppError("ServeWebSocket", "api.web_socket_router.not_authenticated.app_error", nil, "", http.StatusUnauthorized) 77 ReturnWebSocketError(conn, r, err) 78 return 79 } 80 81 var handler webSocketHandler 82 if h, ok := wr.handlers[r.Action]; !ok { 83 err := model.NewAppError("ServeWebSocket", "api.web_socket_router.bad_action.app_error", nil, "", http.StatusInternalServerError) 84 ReturnWebSocketError(conn, r, err) 85 return 86 } else { 87 handler = h 88 } 89 90 handler.ServeWebSocket(conn, r) 91 } 92 93 func ReturnWebSocketError(conn *WebConn, r *model.WebSocketRequest, err *model.AppError) { 94 mlog.Error(fmt.Sprintf("websocket routing error: seq=%v uid=%v %v [details: %v]", r.Seq, conn.UserId, err.SystemMessage(utils.T), err.DetailedError)) 95 96 err.DetailedError = "" 97 errorResp := model.NewWebSocketError(r.Seq, err) 98 99 conn.Send <- errorResp 100 }