From a12147930caeeace35d89a6abacd2708a7cdcea1 Mon Sep 17 00:00:00 2001 From: James Hillyerd Date: Fri, 11 Oct 2013 14:42:00 -0700 Subject: [PATCH] Can now list mailbox contents via REST --- bin/mailbox-list.sh | 1 + web/context.go | 20 ++++++++++++++++++++ web/mailbox_controller.go | 26 +++++++++++++++++++++----- web/rest.go | 13 +++++++++++++ 4 files changed, 55 insertions(+), 5 deletions(-) create mode 100755 bin/mailbox-list.sh create mode 100644 web/rest.go diff --git a/bin/mailbox-list.sh b/bin/mailbox-list.sh new file mode 100755 index 0000000..384560f --- /dev/null +++ b/bin/mailbox-list.sh @@ -0,0 +1 @@ +curl -i -H "Accept: application/json" --noproxy localhost http://localhost:9000/mailbox/list/$1 diff --git a/web/context.go b/web/context.go index 7946cdc..5bf4400 100644 --- a/web/context.go +++ b/web/context.go @@ -5,18 +5,37 @@ import ( "github.com/gorilla/sessions" "github.com/jhillyerd/inbucket/smtpd" "net/http" + "strings" ) type Context struct { Vars map[string]string Session *sessions.Session DataStore smtpd.DataStore + IsJson bool } func (c *Context) Close() { // Do nothing } +// headerMatch returns true if the request header specified by name contains +// the specified value. Case is ignored. +func headerMatch(req *http.Request, name string, value string) bool { + name = http.CanonicalHeaderKey(name) + value = strings.ToLower(value) + + if header := req.Header[name]; header != nil { + for _, hv := range header { + if value == strings.ToLower(hv) { + return true + } + } + } + + return false +} + func NewContext(req *http.Request) (*Context, error) { vars := mux.Vars(req) sess, err := sessionStore.Get(req, "inbucket") @@ -25,6 +44,7 @@ func NewContext(req *http.Request) (*Context, error) { Vars: vars, Session: sess, DataStore: ds, + IsJson: headerMatch(req, "Accept", "application/json"), } if err != nil { return ctx, err diff --git a/web/mailbox_controller.go b/web/mailbox_controller.go index ef9866b..018a18b 100644 --- a/web/mailbox_controller.go +++ b/web/mailbox_controller.go @@ -9,6 +9,10 @@ import ( "strconv" ) +type JsonMessageHeader struct { + From, Subject, Date string +} + func MailboxIndex(w http.ResponseWriter, req *http.Request, ctx *Context) (err error) { name := req.FormValue("name") if len(name) == 0 { @@ -37,11 +41,23 @@ func MailboxList(w http.ResponseWriter, req *http.Request, ctx *Context) (err er } log.LogTrace("Got %v messsages", len(messages)) - return RenderPartial("mailbox/_list.html", w, map[string]interface{}{ - "ctx": ctx, - "name": name, - "messages": messages, - }) + if ctx.IsJson { + jmessages := make([]*JsonMessageHeader, len(messages)) + for i, msg := range messages { + jmessages[i] = &JsonMessageHeader{ + From: msg.From(), + Subject: msg.Subject(), + Date: msg.Date().String(), + } + } + return RenderJson(w, jmessages) + } else { + return RenderPartial("mailbox/_list.html", w, map[string]interface{}{ + "ctx": ctx, + "name": name, + "messages": messages, + }) + } } func MailboxShow(w http.ResponseWriter, req *http.Request, ctx *Context) (err error) { diff --git a/web/rest.go b/web/rest.go new file mode 100644 index 0000000..be5238d --- /dev/null +++ b/web/rest.go @@ -0,0 +1,13 @@ +package web + +import ( + "encoding/json" + "net/http" +) + +func RenderJson(w http.ResponseWriter, data interface{}) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.Header().Set("Expires", "-1") + enc := json.NewEncoder(w) + return enc.Encode(data) +}