diff options
author | Simon Ser <contact@emersion.fr> | 2019-12-03 13:07:25 +0100 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2019-12-03 13:07:25 +0100 |
commit | be14524c3384c88f0a5b0d64c4584abcc6ae0665 (patch) | |
tree | 157663357ab0c55b98d53e7feb8be0f7849f1ff1 /server.go | |
parent | 33b8679f1c6b2055196536b3e3ae808195202377 (diff) | |
download | alps-be14524c3384c88f0a5b0d64c4584abcc6ae0665.tar.gz alps-be14524c3384c88f0a5b0d64c4584abcc6ae0665.zip |
Display & download any message part
Diffstat (limited to 'server.go')
-rw-r--r-- | server.go | 86 |
1 files changed, 65 insertions, 21 deletions
@@ -2,8 +2,11 @@ package koushin import ( "fmt" + "io/ioutil" + "mime" "net/http" "net/url" + "strings" "time" imapclient "github.com/emersion/go-imap/client" @@ -94,6 +97,63 @@ func handleLogin(ectx echo.Context) error { return ctx.Render(http.StatusOK, "login.html", nil) } +func handleGetPart(ctx *context, raw bool) error { + mboxName := ctx.Param("mbox") + uid, err := parseUid(ctx.Param("uid")) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, err) + } + partPathString := ctx.QueryParam("part") + partPath, err := parsePartPath(partPathString) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, err) + } + + msg, part, err := getMessagePart(ctx.conn, mboxName, uid, partPath) + if err != nil { + return err + } + + mimeType, _, err := part.Header.ContentType() + if err != nil { + return err + } + if len(partPath) == 0 { + mimeType = "message/rfc822" + } + + if raw { + disp, dispParams, _ := part.Header.ContentDisposition() + filename := dispParams["filename"] + + if !strings.EqualFold(mimeType, "text/plain") || strings.EqualFold(disp, "attachment") { + dispParams := make(map[string]string) + if filename != "" { + dispParams["filename"] = filename + } + disp := mime.FormatMediaType("attachment", dispParams) + ctx.Response().Header().Set("Content-Disposition", disp) + } + return ctx.Stream(http.StatusOK, mimeType, part.Body) + } + + var body string + if strings.HasPrefix(strings.ToLower(mimeType), "text/") { + b, err := ioutil.ReadAll(part.Body) + if err != nil { + return err + } + body = string(b) + } + + return ctx.Render(http.StatusOK, "message.html", map[string]interface{}{ + "Mailbox": ctx.conn.Mailbox(), + "Message": msg, + "Body": body, + "PartPath": partPathString, + }) +} + func New(imapURL string) *echo.Echo { e := echo.New() @@ -157,27 +217,11 @@ func New(imapURL string) *echo.Echo { e.GET("/message/:mbox/:uid", func(ectx echo.Context) error { ctx := ectx.(*context) - - uid, err := parseUid(ctx.Param("uid")) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, err) - } - // TODO: handle messages without a text part - part, err := parsePartPath(ctx.QueryParam("part")) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, err) - } - - msg, body, err := getMessage(ctx.conn, ctx.Param("mbox"), uid, part) - if err != nil { - return err - } - - return ctx.Render(http.StatusOK, "message.html", map[string]interface{}{ - "Mailbox": ctx.conn.Mailbox(), - "Message": msg, - "Body": body, - }) + return handleGetPart(ctx, false) + }) + e.GET("/message/:mbox/:uid/raw", func(ectx echo.Context) error { + ctx := ectx.(*context) + return handleGetPart(ctx, true) }) e.GET("/login", handleLogin) |