From 00e4d3791cbf620a4d5b8b4392ccd0e729e8f965 Mon Sep 17 00:00:00 2001 From: James Hillyerd Date: Sun, 22 Jan 2017 13:51:55 -0800 Subject: [PATCH] Allow monitoring of a particular mailbox for #44 - No UI to access, just append /mailbox to /monitor URL - Changed API URLs: - /api/v1/monitor/messages - all - /api/v1/monitor/messages/{name} - specific --- rest/routes.go | 4 +- rest/socketv1_controller.go | 51 +++++++++++++++++--- themes/bootstrap/public/monitor.js | 7 ++- themes/bootstrap/templates/root/monitor.html | 9 +++- webui/root_controller.go | 29 +++++++++++ webui/routes.go | 2 + 6 files changed, 89 insertions(+), 13 deletions(-) diff --git a/rest/routes.go b/rest/routes.go index 146e53d..1bc73d1 100644 --- a/rest/routes.go +++ b/rest/routes.go @@ -16,6 +16,8 @@ func SetupRoutes(r *mux.Router) { httpd.Handler(MailboxDeleteV1)).Name("MailboxDeleteV1").Methods("DELETE") r.Path("/api/v1/mailbox/{name}/{id}/source").Handler( httpd.Handler(MailboxSourceV1)).Name("MailboxSourceV1").Methods("GET") - r.Path("/api/v1/monitor/all/messages").Handler( + r.Path("/api/v1/monitor/messages").Handler( httpd.Handler(MonitorAllMessagesV1)).Name("MonitorAllMessagesV1").Methods("GET") + r.Path("/api/v1/monitor/messages/{name}").Handler( + httpd.Handler(MonitorMailboxMessagesV1)).Name("MonitorMailboxMessagesV1").Methods("GET") } diff --git a/rest/socketv1_controller.go b/rest/socketv1_controller.go index 5bab16d..764519a 100644 --- a/rest/socketv1_controller.go +++ b/rest/socketv1_controller.go @@ -9,6 +9,7 @@ import ( "github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/msghub" "github.com/jhillyerd/inbucket/rest/model" + "github.com/jhillyerd/inbucket/smtpd" ) const ( @@ -33,15 +34,18 @@ var upgrader = websocket.Upgrader{ // msgListener handles messages from the msghub type msgListener struct { - hub *msghub.Hub - c chan msghub.Message + hub *msghub.Hub // Global message hub + c chan msghub.Message // Queue of messages from Receive() + mailbox string // Name of mailbox to monitor, "" == all mailboxes } -// newMsgListener creates a listener and registers it -func newMsgListener(hub *msghub.Hub) *msgListener { +// newMsgListener creates a listener and registers it. Optional mailbox parameter will restrict +// messages sent to WebSocket to that mailbox only. +func newMsgListener(hub *msghub.Hub, mailbox string) *msgListener { ml := &msgListener{ - hub: hub, - c: make(chan msghub.Message, 100), + hub: hub, + c: make(chan msghub.Message, 100), + mailbox: mailbox, } hub.AddListener(ml) return ml @@ -49,11 +53,15 @@ func newMsgListener(hub *msghub.Hub) *msgListener { // Receive handles an incoming message func (ml *msgListener) Receive(msg msghub.Message) error { + if ml.mailbox != "" && ml.mailbox != msg.Mailbox { + // Did not match mailbox name + return nil + } ml.c <- msg return nil } -// WSReader makes sure the websocket client is still connected +// WSReader makes sure the websocket client is still connected, discards any messages from client func (ml *msgListener) WSReader(conn *websocket.Conn) { defer ml.Close() conn.SetReadLimit(maxMessageSize) @@ -152,7 +160,34 @@ func MonitorAllMessagesV1( log.Tracef("HTTP[%v] Upgraded to websocket", req.RemoteAddr) // Create, register listener; then interact with conn - ml := newMsgListener(ctx.MsgHub) + ml := newMsgListener(ctx.MsgHub, "") + go ml.WSWriter(conn) + ml.WSReader(conn) + + return nil +} + +func MonitorMailboxMessagesV1( + w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { + name, err := smtpd.ParseMailboxName(ctx.Vars["name"]) + if err != nil { + return err + } + // Upgrade to Websocket + conn, err := upgrader.Upgrade(w, req, nil) + if err != nil { + return err + } + httpd.ExpWebSocketConnectsCurrent.Add(1) + defer func() { + _ = conn.Close() + httpd.ExpWebSocketConnectsCurrent.Add(-1) + }() + + log.Tracef("HTTP[%v] Upgraded to websocket", req.RemoteAddr) + + // Create, register listener; then interact with conn + ml := newMsgListener(ctx.MsgHub, name) go ml.WSWriter(conn) ml.WSReader(conn) diff --git a/themes/bootstrap/public/monitor.js b/themes/bootstrap/public/monitor.js index e7716d2..e670621 100644 --- a/themes/bootstrap/public/monitor.js +++ b/themes/bootstrap/public/monitor.js @@ -1,6 +1,6 @@ var baseURL = window.location.protocol + '//' + window.location.host; -function startMonitor() { +function startMonitor(mailbox) { $.addTemplateFormatter({ "date": function(value, template) { return moment(value).calendar(); @@ -13,7 +13,10 @@ function startMonitor() { } }); - var uri = '/api/v1/monitor/all/messages' + var uri = '/api/v1/monitor/messages' + if (mailbox) { + uri += '/' + mailbox; + } var l = window.location; var url = ((l.protocol === "https:") ? "wss://" : "ws://") + l.host + uri var ws = new WebSocket(url); diff --git a/themes/bootstrap/templates/root/monitor.html b/themes/bootstrap/templates/root/monitor.html index f20313d..fbbf03a 100644 --- a/themes/bootstrap/templates/root/monitor.html +++ b/themes/bootstrap/templates/root/monitor.html @@ -5,7 +5,7 @@