1
0
mirror of https://github.com/jhillyerd/inbucket.git synced 2025-12-18 18:17:03 +00:00

Reorganize packages, closes #79

- All packages go into either cmd or pkg directories
- Most packages renamed
- Server packages moved into pkg/server
- sanitize moved into webui, as that's the only place it's used
- filestore moved into pkg/storage/file
- Makefile updated, and PKG variable use fixed
This commit is contained in:
James Hillyerd
2018-03-09 19:32:45 -08:00
parent f00b9ddef0
commit f8c30a678a
55 changed files with 225 additions and 220 deletions

4
.gitignore vendored
View File

@@ -26,8 +26,12 @@ _testmain.go
*.swo *.swo
# our binaries # our binaries
/client
/client.exe
/inbucket /inbucket
/inbucket.exe /inbucket.exe
/dist/** /dist/**
/cmd/client/client /cmd/client/client
/cmd/client/client.exe /cmd/client/client.exe
/cmd/inbucket/inbucket
/cmd/inbucket/inbucket.exe

View File

@@ -1,26 +1,27 @@
PKG := inbucket SHELL = /bin/sh
SHELL := /bin/sh
SRC := $(shell find . -type f -name '*.go' -not -path "./vendor/*") SRC ::= $(shell find . -type f -name '*.go' -not -path "./vendor/*")
PKGS := $$(go list ./... | grep -v /vendor/) PKGS ::= $(shell go list ./... | grep -v /vendor/)
.PHONY: all build clean fmt install lint simplify test .PHONY: all build clean fmt lint simplify test
all: test lint build commands ::= client inbucket
all: clean test lint build
$(commands): %: cmd/%
go build ./$<
clean: clean:
go clean go clean $(PKGS)
rm -f $(commands)
deps: deps:
go get -t ./... go get -t ./...
build: clean deps build: deps $(commands)
go build
install: build test: deps
go install
test: clean deps
go test -race ./... go test -race ./...
fmt: fmt:
@@ -31,5 +32,5 @@ simplify:
lint: lint:
@test -z "$(shell gofmt -l . | tee /dev/stderr)" || echo "[WARN] Fix formatting issues with 'make fmt'" @test -z "$(shell gofmt -l . | tee /dev/stderr)" || echo "[WARN] Fix formatting issues with 'make fmt'"
@golint -set_exit_status $${PKGS} @golint -set_exit_status $(PKGS)
@go vet $${PKGS} @go vet $(PKGS)

View File

@@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"github.com/google/subcommands" "github.com/google/subcommands"
"github.com/jhillyerd/inbucket/rest/client" "github.com/jhillyerd/inbucket/pkg/rest/client"
) )
type listCmd struct { type listCmd struct {

View File

@@ -10,7 +10,7 @@ import (
"time" "time"
"github.com/google/subcommands" "github.com/google/subcommands"
"github.com/jhillyerd/inbucket/rest/client" "github.com/jhillyerd/inbucket/pkg/rest/client"
) )
type matchCmd struct { type matchCmd struct {

View File

@@ -7,7 +7,7 @@ import (
"os" "os"
"github.com/google/subcommands" "github.com/google/subcommands"
"github.com/jhillyerd/inbucket/rest/client" "github.com/jhillyerd/inbucket/pkg/rest/client"
) )
type mboxCmd struct { type mboxCmd struct {

View File

@@ -12,15 +12,15 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/pkg/config"
"github.com/jhillyerd/inbucket/filestore" "github.com/jhillyerd/inbucket/pkg/log"
"github.com/jhillyerd/inbucket/httpd" "github.com/jhillyerd/inbucket/pkg/msghub"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/rest"
"github.com/jhillyerd/inbucket/msghub" "github.com/jhillyerd/inbucket/pkg/server/pop3"
"github.com/jhillyerd/inbucket/pop3d" "github.com/jhillyerd/inbucket/pkg/server/smtp"
"github.com/jhillyerd/inbucket/rest" "github.com/jhillyerd/inbucket/pkg/server/web"
"github.com/jhillyerd/inbucket/smtpd" "github.com/jhillyerd/inbucket/pkg/storage/file"
"github.com/jhillyerd/inbucket/webui" "github.com/jhillyerd/inbucket/pkg/webui"
) )
var ( var (
@@ -39,8 +39,8 @@ var (
shutdownChan = make(chan bool) shutdownChan = make(chan bool)
// Server instances // Server instances
smtpServer *smtpd.Server smtpServer *smtp.Server
pop3Server *pop3d.Server pop3Server *pop3.Server
) )
func init() { func init() {
@@ -119,17 +119,17 @@ func main() {
ds := filestore.DefaultFileDataStore() ds := filestore.DefaultFileDataStore()
// Start HTTP server // Start HTTP server
httpd.Initialize(config.GetWebConfig(), shutdownChan, ds, msgHub) web.Initialize(config.GetWebConfig(), shutdownChan, ds, msgHub)
webui.SetupRoutes(httpd.Router) webui.SetupRoutes(web.Router)
rest.SetupRoutes(httpd.Router) rest.SetupRoutes(web.Router)
go httpd.Start(rootCtx) go web.Start(rootCtx)
// Start POP3 server // Start POP3 server
pop3Server = pop3d.New(config.GetPOP3Config(), shutdownChan, ds) pop3Server = pop3.New(config.GetPOP3Config(), shutdownChan, ds)
go pop3Server.Start(rootCtx) go pop3Server.Start(rootCtx)
// Startup SMTP server // Startup SMTP server
smtpServer = smtpd.NewServer(config.GetSMTPConfig(), shutdownChan, ds, msgHub) smtpServer = smtp.NewServer(config.GetSMTPConfig(), shutdownChan, ds, msgHub)
go smtpServer.Start(rootCtx) go smtpServer.Start(rootCtx)
// Loop forever waiting for signals or shutdown channel // Loop forever waiting for signals or shutdown channel

View File

@@ -10,15 +10,15 @@ import (
"io/ioutil" "io/ioutil"
"strconv" "strconv"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/log"
"github.com/jhillyerd/inbucket/httpd" "github.com/jhillyerd/inbucket/pkg/rest/model"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/server/web"
"github.com/jhillyerd/inbucket/rest/model" "github.com/jhillyerd/inbucket/pkg/storage"
"github.com/jhillyerd/inbucket/stringutil" "github.com/jhillyerd/inbucket/pkg/stringutil"
) )
// MailboxListV1 renders a list of messages in a mailbox // MailboxListV1 renders a list of messages in a mailbox
func MailboxListV1(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxListV1(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Don't have to validate these aren't empty, Gorilla returns 404 // Don't have to validate these aren't empty, Gorilla returns 404
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
if err != nil { if err != nil {
@@ -48,11 +48,11 @@ func MailboxListV1(w http.ResponseWriter, req *http.Request, ctx *httpd.Context)
Size: msg.Size(), Size: msg.Size(),
} }
} }
return httpd.RenderJSON(w, jmessages) return web.RenderJSON(w, jmessages)
} }
// MailboxShowV1 renders a particular message from a mailbox // MailboxShowV1 renders a particular message from a mailbox
func MailboxShowV1(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxShowV1(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Don't have to validate these aren't empty, Gorilla returns 404 // Don't have to validate these aren't empty, Gorilla returns 404
id := ctx.Vars["id"] id := ctx.Vars["id"]
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
@@ -96,7 +96,7 @@ func MailboxShowV1(w http.ResponseWriter, req *http.Request, ctx *httpd.Context)
} }
} }
return httpd.RenderJSON(w, return web.RenderJSON(w,
&model.JSONMessageV1{ &model.JSONMessageV1{
Mailbox: name, Mailbox: name,
ID: msg.ID(), ID: msg.ID(),
@@ -115,7 +115,7 @@ func MailboxShowV1(w http.ResponseWriter, req *http.Request, ctx *httpd.Context)
} }
// MailboxPurgeV1 deletes all messages from a mailbox // MailboxPurgeV1 deletes all messages from a mailbox
func MailboxPurgeV1(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxPurgeV1(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Don't have to validate these aren't empty, Gorilla returns 404 // Don't have to validate these aren't empty, Gorilla returns 404
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
if err != nil { if err != nil {
@@ -133,11 +133,11 @@ func MailboxPurgeV1(w http.ResponseWriter, req *http.Request, ctx *httpd.Context
} }
log.Tracef("HTTP purged mailbox for %q", name) log.Tracef("HTTP purged mailbox for %q", name)
return httpd.RenderJSON(w, "OK") return web.RenderJSON(w, "OK")
} }
// MailboxSourceV1 displays the raw source of a message, including headers. Renders text/plain // MailboxSourceV1 displays the raw source of a message, including headers. Renders text/plain
func MailboxSourceV1(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxSourceV1(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Don't have to validate these aren't empty, Gorilla returns 404 // Don't have to validate these aren't empty, Gorilla returns 404
id := ctx.Vars["id"] id := ctx.Vars["id"]
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
@@ -171,7 +171,7 @@ func MailboxSourceV1(w http.ResponseWriter, req *http.Request, ctx *httpd.Contex
} }
// MailboxDeleteV1 removes a particular message from a mailbox // MailboxDeleteV1 removes a particular message from a mailbox
func MailboxDeleteV1(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxDeleteV1(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Don't have to validate these aren't empty, Gorilla returns 404 // Don't have to validate these aren't empty, Gorilla returns 404
id := ctx.Vars["id"] id := ctx.Vars["id"]
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
@@ -197,5 +197,5 @@ func MailboxDeleteV1(w http.ResponseWriter, req *http.Request, ctx *httpd.Contex
return fmt.Errorf("Delete(%q) failed: %v", id, err) return fmt.Errorf("Delete(%q) failed: %v", id, err)
} }
return httpd.RenderJSON(w, "OK") return web.RenderJSON(w, "OK")
} }

View File

@@ -9,7 +9,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/storage"
) )
const ( const (

View File

@@ -8,7 +8,7 @@ import (
"net/url" "net/url"
"time" "time"
"github.com/jhillyerd/inbucket/rest/model" "github.com/jhillyerd/inbucket/pkg/rest/model"
) )
// Client accesses the Inbucket REST API v1 // Client accesses the Inbucket REST API v1

23
pkg/rest/routes.go Normal file
View File

@@ -0,0 +1,23 @@
package rest
import "github.com/gorilla/mux"
import "github.com/jhillyerd/inbucket/pkg/server/web"
// SetupRoutes populates the routes for the REST interface
func SetupRoutes(r *mux.Router) {
// API v1
r.Path("/api/v1/mailbox/{name}").Handler(
web.Handler(MailboxListV1)).Name("MailboxListV1").Methods("GET")
r.Path("/api/v1/mailbox/{name}").Handler(
web.Handler(MailboxPurgeV1)).Name("MailboxPurgeV1").Methods("DELETE")
r.Path("/api/v1/mailbox/{name}/{id}").Handler(
web.Handler(MailboxShowV1)).Name("MailboxShowV1").Methods("GET")
r.Path("/api/v1/mailbox/{name}/{id}").Handler(
web.Handler(MailboxDeleteV1)).Name("MailboxDeleteV1").Methods("DELETE")
r.Path("/api/v1/mailbox/{name}/{id}/source").Handler(
web.Handler(MailboxSourceV1)).Name("MailboxSourceV1").Methods("GET")
r.Path("/api/v1/monitor/messages").Handler(
web.Handler(MonitorAllMessagesV1)).Name("MonitorAllMessagesV1").Methods("GET")
r.Path("/api/v1/monitor/messages/{name}").Handler(
web.Handler(MonitorMailboxMessagesV1)).Name("MonitorMailboxMessagesV1").Methods("GET")
}

View File

@@ -5,11 +5,11 @@ import (
"time" "time"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/jhillyerd/inbucket/httpd" "github.com/jhillyerd/inbucket/pkg/log"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/msghub"
"github.com/jhillyerd/inbucket/msghub" "github.com/jhillyerd/inbucket/pkg/rest/model"
"github.com/jhillyerd/inbucket/rest/model" "github.com/jhillyerd/inbucket/pkg/server/web"
"github.com/jhillyerd/inbucket/stringutil" "github.com/jhillyerd/inbucket/pkg/stringutil"
) )
const ( const (
@@ -145,16 +145,16 @@ func (ml *msgListener) Close() {
} }
func MonitorAllMessagesV1( func MonitorAllMessagesV1(
w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Upgrade to Websocket // Upgrade to Websocket
conn, err := upgrader.Upgrade(w, req, nil) conn, err := upgrader.Upgrade(w, req, nil)
if err != nil { if err != nil {
return err return err
} }
httpd.ExpWebSocketConnectsCurrent.Add(1) web.ExpWebSocketConnectsCurrent.Add(1)
defer func() { defer func() {
_ = conn.Close() _ = conn.Close()
httpd.ExpWebSocketConnectsCurrent.Add(-1) web.ExpWebSocketConnectsCurrent.Add(-1)
}() }()
log.Tracef("HTTP[%v] Upgraded to websocket", req.RemoteAddr) log.Tracef("HTTP[%v] Upgraded to websocket", req.RemoteAddr)
@@ -168,7 +168,7 @@ func MonitorAllMessagesV1(
} }
func MonitorMailboxMessagesV1( func MonitorMailboxMessagesV1(
w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
if err != nil { if err != nil {
return err return err
@@ -178,10 +178,10 @@ func MonitorMailboxMessagesV1(
if err != nil { if err != nil {
return err return err
} }
httpd.ExpWebSocketConnectsCurrent.Add(1) web.ExpWebSocketConnectsCurrent.Add(1)
defer func() { defer func() {
_ = conn.Close() _ = conn.Close()
httpd.ExpWebSocketConnectsCurrent.Add(-1) web.ExpWebSocketConnectsCurrent.Add(-1)
}() }()
log.Tracef("HTTP[%v] Upgraded to websocket", req.RemoteAddr) log.Tracef("HTTP[%v] Upgraded to websocket", req.RemoteAddr)

View File

@@ -10,10 +10,10 @@ import (
"time" "time"
"github.com/jhillyerd/enmime" "github.com/jhillyerd/enmime"
"github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/pkg/config"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/msghub"
"github.com/jhillyerd/inbucket/httpd" "github.com/jhillyerd/inbucket/pkg/server/web"
"github.com/jhillyerd/inbucket/msghub" "github.com/jhillyerd/inbucket/pkg/storage"
) )
type InputMessageData struct { type InputMessageData struct {
@@ -184,7 +184,7 @@ func testRestGet(url string) (*httptest.ResponseRecorder, error) {
} }
w := httptest.NewRecorder() w := httptest.NewRecorder()
httpd.Router.ServeHTTP(w, req) web.Router.ServeHTTP(w, req)
return w, nil return w, nil
} }
@@ -200,8 +200,8 @@ func setupWebServer(ds datastore.DataStore) *bytes.Buffer {
PublicDir: "../themes/bootstrap/public", PublicDir: "../themes/bootstrap/public",
} }
shutdownChan := make(chan bool) shutdownChan := make(chan bool)
httpd.Initialize(cfg, shutdownChan, ds, &msghub.Hub{}) web.Initialize(cfg, shutdownChan, ds, &msghub.Hub{})
SetupRoutes(httpd.Router) SetupRoutes(web.Router)
return buf return buf
} }

View File

@@ -1,4 +1,4 @@
package pop3d package pop3
import ( import (
"bufio" "bufio"
@@ -11,8 +11,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/log"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/storage"
) )
// State tracks the current mode of our POP3 state machine // State tracks the current mode of our POP3 state machine

View File

@@ -1,4 +1,4 @@
package pop3d package pop3
import ( import (
"context" "context"
@@ -7,9 +7,9 @@ import (
"sync" "sync"
"time" "time"
"github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/pkg/config"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/log"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/storage"
) )
// Server defines an instance of our POP3 server // Server defines an instance of our POP3 server

View File

@@ -1,4 +1,4 @@
package smtpd package smtp
import ( import (
"bufio" "bufio"
@@ -12,10 +12,10 @@ import (
"strings" "strings"
"time" "time"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/log"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/msghub"
"github.com/jhillyerd/inbucket/msghub" "github.com/jhillyerd/inbucket/pkg/storage"
"github.com/jhillyerd/inbucket/stringutil" "github.com/jhillyerd/inbucket/pkg/stringutil"
) )
// State tracks the current mode of our SMTP state machine // State tracks the current mode of our SMTP state machine

View File

@@ -1,4 +1,4 @@
package smtpd package smtp
import ( import (
"bytes" "bytes"
@@ -13,9 +13,9 @@ import (
"testing" "testing"
"time" "time"
"github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/pkg/config"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/msghub"
"github.com/jhillyerd/inbucket/msghub" "github.com/jhillyerd/inbucket/pkg/storage"
) )
type scriptStep struct { type scriptStep struct {

View File

@@ -1,4 +1,4 @@
package smtpd package smtp
import ( import (
"container/list" "container/list"
@@ -10,10 +10,10 @@ import (
"sync" "sync"
"time" "time"
"github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/pkg/config"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/log"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/msghub"
"github.com/jhillyerd/inbucket/msghub" "github.com/jhillyerd/inbucket/pkg/storage"
) )
func init() { func init() {

View File

@@ -1,4 +1,4 @@
package httpd package web
import ( import (
"net/http" "net/http"
@@ -6,9 +6,9 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
"github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/pkg/config"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/msghub"
"github.com/jhillyerd/inbucket/msghub" "github.com/jhillyerd/inbucket/pkg/storage"
) )
// Context is passed into every request handler function // Context is passed into every request handler function

View File

@@ -1,4 +1,4 @@
package httpd package web
import ( import (
"fmt" "fmt"
@@ -8,7 +8,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/log"
) )
// TemplateFuncs declares functions made available to all templates (including partials) // TemplateFuncs declares functions made available to all templates (including partials)

View File

@@ -1,4 +1,4 @@
package httpd package web
import ( import (
"html/template" "html/template"

View File

@@ -1,4 +1,4 @@
package httpd package web
import ( import (
"encoding/json" "encoding/json"

View File

@@ -1,5 +1,5 @@
// Package httpd provides the plumbing for Inbucket's web GUI and RESTful API // Package web provides the plumbing for Inbucket's web GUI and RESTful API
package httpd package web
import ( import (
"context" "context"
@@ -12,10 +12,10 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/gorilla/securecookie" "github.com/gorilla/securecookie"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
"github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/pkg/config"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/log"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/msghub"
"github.com/jhillyerd/inbucket/msghub" "github.com/jhillyerd/inbucket/pkg/storage"
) )
// Handler is a function type that handles an HTTP request in Inbucket // Handler is a function type that handles an HTTP request in Inbucket

View File

@@ -1,4 +1,4 @@
package httpd package web
import ( import (
"html/template" "html/template"
@@ -8,7 +8,7 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/log"
) )
var cachedMutex sync.Mutex var cachedMutex sync.Mutex

View File

@@ -11,8 +11,8 @@ import (
"time" "time"
"github.com/jhillyerd/enmime" "github.com/jhillyerd/enmime"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/storage"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/log"
) )
// FileMessage implements Message and contains a little bit of data about a // FileMessage implements Message and contains a little bit of data about a

View File

@@ -11,10 +11,10 @@ import (
"sync" "sync"
"time" "time"
"github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/pkg/config"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/storage"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/log"
"github.com/jhillyerd/inbucket/stringutil" "github.com/jhillyerd/inbucket/pkg/stringutil"
) )
// Name of index file in each mailbox // Name of index file in each mailbox

View File

@@ -11,7 +11,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/pkg/config"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View File

@@ -3,7 +3,7 @@ package datastore_test
import ( import (
"testing" "testing"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/storage"
) )
func TestHashLock(t *testing.T) { func TestHashLock(t *testing.T) {

View File

@@ -6,8 +6,8 @@ import (
"sync" "sync"
"time" "time"
"github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/pkg/config"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/log"
) )
var ( var (

View File

@@ -7,29 +7,29 @@ import (
"net/http" "net/http"
"strconv" "strconv"
"github.com/jhillyerd/inbucket/datastore" "github.com/jhillyerd/inbucket/pkg/log"
"github.com/jhillyerd/inbucket/httpd" "github.com/jhillyerd/inbucket/pkg/server/web"
"github.com/jhillyerd/inbucket/log" "github.com/jhillyerd/inbucket/pkg/storage"
"github.com/jhillyerd/inbucket/sanitize" "github.com/jhillyerd/inbucket/pkg/stringutil"
"github.com/jhillyerd/inbucket/stringutil" "github.com/jhillyerd/inbucket/pkg/webui/sanitize"
) )
// MailboxIndex renders the index page for a particular mailbox // MailboxIndex renders the index page for a particular mailbox
func MailboxIndex(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxIndex(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Form values must be validated manually // Form values must be validated manually
name := req.FormValue("name") name := req.FormValue("name")
selected := req.FormValue("id") selected := req.FormValue("id")
if len(name) == 0 { if len(name) == 0 {
ctx.Session.AddFlash("Account name is required", "errors") ctx.Session.AddFlash("Account name is required", "errors")
_ = ctx.Session.Save(req, w) _ = ctx.Session.Save(req, w)
http.Redirect(w, req, httpd.Reverse("RootIndex"), http.StatusSeeOther) http.Redirect(w, req, web.Reverse("RootIndex"), http.StatusSeeOther)
return nil return nil
} }
name, err = stringutil.ParseMailboxName(name) name, err = stringutil.ParseMailboxName(name)
if err != nil { if err != nil {
ctx.Session.AddFlash(err.Error(), "errors") ctx.Session.AddFlash(err.Error(), "errors")
_ = ctx.Session.Save(req, w) _ = ctx.Session.Save(req, w)
http.Redirect(w, req, httpd.Reverse("RootIndex"), http.StatusSeeOther) http.Redirect(w, req, web.Reverse("RootIndex"), http.StatusSeeOther)
return nil return nil
} }
// Remember this mailbox was visited // Remember this mailbox was visited
@@ -40,7 +40,7 @@ func MailboxIndex(w http.ResponseWriter, req *http.Request, ctx *httpd.Context)
return err return err
} }
// Render template // Render template
return httpd.RenderTemplate("mailbox/index.html", w, map[string]interface{}{ return web.RenderTemplate("mailbox/index.html", w, map[string]interface{}{
"ctx": ctx, "ctx": ctx,
"errorFlash": errorFlash, "errorFlash": errorFlash,
"name": name, "name": name,
@@ -49,24 +49,24 @@ func MailboxIndex(w http.ResponseWriter, req *http.Request, ctx *httpd.Context)
} }
// MailboxLink handles pretty links to a particular message. Renders a redirect // MailboxLink handles pretty links to a particular message. Renders a redirect
func MailboxLink(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxLink(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Don't have to validate these aren't empty, Gorilla returns 404 // Don't have to validate these aren't empty, Gorilla returns 404
id := ctx.Vars["id"] id := ctx.Vars["id"]
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
if err != nil { if err != nil {
ctx.Session.AddFlash(err.Error(), "errors") ctx.Session.AddFlash(err.Error(), "errors")
_ = ctx.Session.Save(req, w) _ = ctx.Session.Save(req, w)
http.Redirect(w, req, httpd.Reverse("RootIndex"), http.StatusSeeOther) http.Redirect(w, req, web.Reverse("RootIndex"), http.StatusSeeOther)
return nil return nil
} }
// Build redirect // Build redirect
uri := fmt.Sprintf("%s?name=%s&id=%s", httpd.Reverse("MailboxIndex"), name, id) uri := fmt.Sprintf("%s?name=%s&id=%s", web.Reverse("MailboxIndex"), name, id)
http.Redirect(w, req, uri, http.StatusSeeOther) http.Redirect(w, req, uri, http.StatusSeeOther)
return nil return nil
} }
// MailboxList renders a list of messages in a mailbox. Renders a partial // MailboxList renders a list of messages in a mailbox. Renders a partial
func MailboxList(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxList(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Don't have to validate these aren't empty, Gorilla returns 404 // Don't have to validate these aren't empty, Gorilla returns 404
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
if err != nil { if err != nil {
@@ -84,7 +84,7 @@ func MailboxList(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (
} }
log.Tracef("Got %v messsages", len(messages)) log.Tracef("Got %v messsages", len(messages))
// Render partial template // Render partial template
return httpd.RenderPartial("mailbox/_list.html", w, map[string]interface{}{ return web.RenderPartial("mailbox/_list.html", w, map[string]interface{}{
"ctx": ctx, "ctx": ctx,
"name": name, "name": name,
"messages": messages, "messages": messages,
@@ -92,7 +92,7 @@ func MailboxList(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (
} }
// MailboxShow renders a particular message from a mailbox. Renders an HTML partial // MailboxShow renders a particular message from a mailbox. Renders an HTML partial
func MailboxShow(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxShow(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Don't have to validate these aren't empty, Gorilla returns 404 // Don't have to validate these aren't empty, Gorilla returns 404
id := ctx.Vars["id"] id := ctx.Vars["id"]
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
@@ -117,7 +117,7 @@ func MailboxShow(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (
if err != nil { if err != nil {
return fmt.Errorf("ReadBody(%q) failed: %v", id, err) return fmt.Errorf("ReadBody(%q) failed: %v", id, err)
} }
body := template.HTML(httpd.TextToHTML(mime.Text)) body := template.HTML(web.TextToHTML(mime.Text))
htmlAvailable := mime.HTML != "" htmlAvailable := mime.HTML != ""
var htmlBody template.HTML var htmlBody template.HTML
if htmlAvailable { if htmlAvailable {
@@ -128,7 +128,7 @@ func MailboxShow(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (
} }
} }
// Render partial template // Render partial template
return httpd.RenderPartial("mailbox/_show.html", w, map[string]interface{}{ return web.RenderPartial("mailbox/_show.html", w, map[string]interface{}{
"ctx": ctx, "ctx": ctx,
"name": name, "name": name,
"message": msg, "message": msg,
@@ -141,7 +141,7 @@ func MailboxShow(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (
} }
// MailboxHTML displays the HTML content of a message. Renders a partial // MailboxHTML displays the HTML content of a message. Renders a partial
func MailboxHTML(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxHTML(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Don't have to validate these aren't empty, Gorilla returns 404 // Don't have to validate these aren't empty, Gorilla returns 404
id := ctx.Vars["id"] id := ctx.Vars["id"]
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
@@ -168,7 +168,7 @@ func MailboxHTML(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (
} }
// Render partial template // Render partial template
w.Header().Set("Content-Type", "text/html; charset=UTF-8") w.Header().Set("Content-Type", "text/html; charset=UTF-8")
return httpd.RenderPartial("mailbox/_html.html", w, map[string]interface{}{ return web.RenderPartial("mailbox/_html.html", w, map[string]interface{}{
"ctx": ctx, "ctx": ctx,
"name": name, "name": name,
"message": message, "message": message,
@@ -178,7 +178,7 @@ func MailboxHTML(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (
} }
// MailboxSource displays the raw source of a message, including headers. Renders text/plain // MailboxSource displays the raw source of a message, including headers. Renders text/plain
func MailboxSource(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxSource(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Don't have to validate these aren't empty, Gorilla returns 404 // Don't have to validate these aren't empty, Gorilla returns 404
id := ctx.Vars["id"] id := ctx.Vars["id"]
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
@@ -213,14 +213,14 @@ func MailboxSource(w http.ResponseWriter, req *http.Request, ctx *httpd.Context)
// MailboxDownloadAttach sends the attachment to the client; disposition: // MailboxDownloadAttach sends the attachment to the client; disposition:
// attachment, type: application/octet-stream // attachment, type: application/octet-stream
func MailboxDownloadAttach(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxDownloadAttach(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Don't have to validate these aren't empty, Gorilla returns 404 // Don't have to validate these aren't empty, Gorilla returns 404
id := ctx.Vars["id"] id := ctx.Vars["id"]
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
if err != nil { if err != nil {
ctx.Session.AddFlash(err.Error(), "errors") ctx.Session.AddFlash(err.Error(), "errors")
_ = ctx.Session.Save(req, w) _ = ctx.Session.Save(req, w)
http.Redirect(w, req, httpd.Reverse("RootIndex"), http.StatusSeeOther) http.Redirect(w, req, web.Reverse("RootIndex"), http.StatusSeeOther)
return nil return nil
} }
numStr := ctx.Vars["num"] numStr := ctx.Vars["num"]
@@ -228,7 +228,7 @@ func MailboxDownloadAttach(w http.ResponseWriter, req *http.Request, ctx *httpd.
if err != nil { if err != nil {
ctx.Session.AddFlash("Attachment number must be unsigned numeric", "errors") ctx.Session.AddFlash("Attachment number must be unsigned numeric", "errors")
_ = ctx.Session.Save(req, w) _ = ctx.Session.Save(req, w)
http.Redirect(w, req, httpd.Reverse("RootIndex"), http.StatusSeeOther) http.Redirect(w, req, web.Reverse("RootIndex"), http.StatusSeeOther)
return nil return nil
} }
mb, err := ctx.DataStore.MailboxFor(name) mb, err := ctx.DataStore.MailboxFor(name)
@@ -252,7 +252,7 @@ func MailboxDownloadAttach(w http.ResponseWriter, req *http.Request, ctx *httpd.
if int(num) >= len(body.Attachments) { if int(num) >= len(body.Attachments) {
ctx.Session.AddFlash("Attachment number too high", "errors") ctx.Session.AddFlash("Attachment number too high", "errors")
_ = ctx.Session.Save(req, w) _ = ctx.Session.Save(req, w)
http.Redirect(w, req, httpd.Reverse("RootIndex"), http.StatusSeeOther) http.Redirect(w, req, web.Reverse("RootIndex"), http.StatusSeeOther)
return nil return nil
} }
part := body.Attachments[num] part := body.Attachments[num]
@@ -266,13 +266,13 @@ func MailboxDownloadAttach(w http.ResponseWriter, req *http.Request, ctx *httpd.
} }
// MailboxViewAttach sends the attachment to the client for online viewing // MailboxViewAttach sends the attachment to the client for online viewing
func MailboxViewAttach(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func MailboxViewAttach(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
// Don't have to validate these aren't empty, Gorilla returns 404 // Don't have to validate these aren't empty, Gorilla returns 404
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
if err != nil { if err != nil {
ctx.Session.AddFlash(err.Error(), "errors") ctx.Session.AddFlash(err.Error(), "errors")
_ = ctx.Session.Save(req, w) _ = ctx.Session.Save(req, w)
http.Redirect(w, req, httpd.Reverse("RootIndex"), http.StatusSeeOther) http.Redirect(w, req, web.Reverse("RootIndex"), http.StatusSeeOther)
return nil return nil
} }
id := ctx.Vars["id"] id := ctx.Vars["id"]
@@ -281,7 +281,7 @@ func MailboxViewAttach(w http.ResponseWriter, req *http.Request, ctx *httpd.Cont
if err != nil { if err != nil {
ctx.Session.AddFlash("Attachment number must be unsigned numeric", "errors") ctx.Session.AddFlash("Attachment number must be unsigned numeric", "errors")
_ = ctx.Session.Save(req, w) _ = ctx.Session.Save(req, w)
http.Redirect(w, req, httpd.Reverse("RootIndex"), http.StatusSeeOther) http.Redirect(w, req, web.Reverse("RootIndex"), http.StatusSeeOther)
return nil return nil
} }
mb, err := ctx.DataStore.MailboxFor(name) mb, err := ctx.DataStore.MailboxFor(name)
@@ -305,7 +305,7 @@ func MailboxViewAttach(w http.ResponseWriter, req *http.Request, ctx *httpd.Cont
if int(num) >= len(body.Attachments) { if int(num) >= len(body.Attachments) {
ctx.Session.AddFlash("Attachment number too high", "errors") ctx.Session.AddFlash("Attachment number too high", "errors")
_ = ctx.Session.Save(req, w) _ = ctx.Session.Save(req, w)
http.Redirect(w, req, httpd.Reverse("RootIndex"), http.StatusSeeOther) http.Redirect(w, req, web.Reverse("RootIndex"), http.StatusSeeOther)
return nil return nil
} }
part := body.Attachments[num] part := body.Attachments[num]

View File

@@ -1,7 +1,7 @@
package webui package webui
import ( import (
"github.com/jhillyerd/inbucket/httpd" "github.com/jhillyerd/inbucket/pkg/server/web"
) )
const ( const (
@@ -12,7 +12,7 @@ const (
) )
// RememberMailbox manages the list of recently accessed mailboxes stored in the session // RememberMailbox manages the list of recently accessed mailboxes stored in the session
func RememberMailbox(ctx *httpd.Context, mailbox string) { func RememberMailbox(ctx *web.Context, mailbox string) {
recent := RecentMailboxes(ctx) recent := RecentMailboxes(ctx)
newRecent := make([]string, 1, maxRemembered) newRecent := make([]string, 1, maxRemembered)
newRecent[0] = mailbox newRecent[0] = mailbox
@@ -28,7 +28,7 @@ func RememberMailbox(ctx *httpd.Context, mailbox string) {
} }
// RecentMailboxes returns a slice of the most recently accessed mailboxes // RecentMailboxes returns a slice of the most recently accessed mailboxes
func RecentMailboxes(ctx *httpd.Context) []string { func RecentMailboxes(ctx *web.Context) []string {
val := ctx.Session.Values[mailboxKey] val := ctx.Session.Values[mailboxKey]
recent, _ := val.([]string) recent, _ := val.([]string)
return recent return recent

View File

@@ -6,13 +6,13 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/pkg/config"
"github.com/jhillyerd/inbucket/httpd" "github.com/jhillyerd/inbucket/pkg/server/web"
"github.com/jhillyerd/inbucket/stringutil" "github.com/jhillyerd/inbucket/pkg/stringutil"
) )
// RootIndex serves the Inbucket landing page // RootIndex serves the Inbucket landing page
func RootIndex(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func RootIndex(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
greeting, err := ioutil.ReadFile(config.GetWebConfig().GreetingFile) greeting, err := ioutil.ReadFile(config.GetWebConfig().GreetingFile)
if err != nil { if err != nil {
return fmt.Errorf("Failed to load greeting: %v", err) return fmt.Errorf("Failed to load greeting: %v", err)
@@ -23,7 +23,7 @@ func RootIndex(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (er
return err return err
} }
// Render template // Render template
return httpd.RenderTemplate("root/index.html", w, map[string]interface{}{ return web.RenderTemplate("root/index.html", w, map[string]interface{}{
"ctx": ctx, "ctx": ctx,
"errorFlash": errorFlash, "errorFlash": errorFlash,
"greeting": template.HTML(string(greeting)), "greeting": template.HTML(string(greeting)),
@@ -31,11 +31,11 @@ func RootIndex(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (er
} }
// RootMonitor serves the Inbucket monitor page // RootMonitor serves the Inbucket monitor page
func RootMonitor(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func RootMonitor(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
if !config.GetWebConfig().MonitorVisible { if !config.GetWebConfig().MonitorVisible {
ctx.Session.AddFlash("Monitor is disabled in configuration", "errors") ctx.Session.AddFlash("Monitor is disabled in configuration", "errors")
_ = ctx.Session.Save(req, w) _ = ctx.Session.Save(req, w)
http.Redirect(w, req, httpd.Reverse("RootIndex"), http.StatusSeeOther) http.Redirect(w, req, web.Reverse("RootIndex"), http.StatusSeeOther)
return nil return nil
} }
// Get flash messages, save session // Get flash messages, save session
@@ -44,25 +44,25 @@ func RootMonitor(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (
return err return err
} }
// Render template // Render template
return httpd.RenderTemplate("root/monitor.html", w, map[string]interface{}{ return web.RenderTemplate("root/monitor.html", w, map[string]interface{}{
"ctx": ctx, "ctx": ctx,
"errorFlash": errorFlash, "errorFlash": errorFlash,
}) })
} }
// RootMonitorMailbox serves the Inbucket monitor page for a particular mailbox // RootMonitorMailbox serves the Inbucket monitor page for a particular mailbox
func RootMonitorMailbox(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func RootMonitorMailbox(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
if !config.GetWebConfig().MonitorVisible { if !config.GetWebConfig().MonitorVisible {
ctx.Session.AddFlash("Monitor is disabled in configuration", "errors") ctx.Session.AddFlash("Monitor is disabled in configuration", "errors")
_ = ctx.Session.Save(req, w) _ = ctx.Session.Save(req, w)
http.Redirect(w, req, httpd.Reverse("RootIndex"), http.StatusSeeOther) http.Redirect(w, req, web.Reverse("RootIndex"), http.StatusSeeOther)
return nil return nil
} }
name, err := stringutil.ParseMailboxName(ctx.Vars["name"]) name, err := stringutil.ParseMailboxName(ctx.Vars["name"])
if err != nil { if err != nil {
ctx.Session.AddFlash(err.Error(), "errors") ctx.Session.AddFlash(err.Error(), "errors")
_ = ctx.Session.Save(req, w) _ = ctx.Session.Save(req, w)
http.Redirect(w, req, httpd.Reverse("RootIndex"), http.StatusSeeOther) http.Redirect(w, req, web.Reverse("RootIndex"), http.StatusSeeOther)
return nil return nil
} }
// Get flash messages, save session // Get flash messages, save session
@@ -71,7 +71,7 @@ func RootMonitorMailbox(w http.ResponseWriter, req *http.Request, ctx *httpd.Con
return err return err
} }
// Render template // Render template
return httpd.RenderTemplate("root/monitor.html", w, map[string]interface{}{ return web.RenderTemplate("root/monitor.html", w, map[string]interface{}{
"ctx": ctx, "ctx": ctx,
"errorFlash": errorFlash, "errorFlash": errorFlash,
"name": name, "name": name,
@@ -79,7 +79,7 @@ func RootMonitorMailbox(w http.ResponseWriter, req *http.Request, ctx *httpd.Con
} }
// RootStatus serves the Inbucket status page // RootStatus serves the Inbucket status page
func RootStatus(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (err error) { func RootStatus(w http.ResponseWriter, req *http.Request, ctx *web.Context) (err error) {
smtpListener := fmt.Sprintf("%s:%d", config.GetSMTPConfig().IP4address.String(), smtpListener := fmt.Sprintf("%s:%d", config.GetSMTPConfig().IP4address.String(),
config.GetSMTPConfig().IP4port) config.GetSMTPConfig().IP4port)
pop3Listener := fmt.Sprintf("%s:%d", config.GetPOP3Config().IP4address.String(), pop3Listener := fmt.Sprintf("%s:%d", config.GetPOP3Config().IP4address.String(),
@@ -92,7 +92,7 @@ func RootStatus(w http.ResponseWriter, req *http.Request, ctx *httpd.Context) (e
return err return err
} }
// Render template // Render template
return httpd.RenderTemplate("root/status.html", w, map[string]interface{}{ return web.RenderTemplate("root/status.html", w, map[string]interface{}{
"ctx": ctx, "ctx": ctx,
"errorFlash": errorFlash, "errorFlash": errorFlash,
"version": config.Version, "version": config.Version,

35
pkg/webui/routes.go Normal file
View File

@@ -0,0 +1,35 @@
// Package webui powers Inbucket's web GUI
package webui
import (
"github.com/gorilla/mux"
"github.com/jhillyerd/inbucket/pkg/server/web"
)
// SetupRoutes populates routes for the webui into the provided Router
func SetupRoutes(r *mux.Router) {
r.Path("/").Handler(
web.Handler(RootIndex)).Name("RootIndex").Methods("GET")
r.Path("/monitor").Handler(
web.Handler(RootMonitor)).Name("RootMonitor").Methods("GET")
r.Path("/monitor/{name}").Handler(
web.Handler(RootMonitorMailbox)).Name("RootMonitorMailbox").Methods("GET")
r.Path("/status").Handler(
web.Handler(RootStatus)).Name("RootStatus").Methods("GET")
r.Path("/link/{name}/{id}").Handler(
web.Handler(MailboxLink)).Name("MailboxLink").Methods("GET")
r.Path("/mailbox").Handler(
web.Handler(MailboxIndex)).Name("MailboxIndex").Methods("GET")
r.Path("/mailbox/{name}").Handler(
web.Handler(MailboxList)).Name("MailboxList").Methods("GET")
r.Path("/mailbox/{name}/{id}").Handler(
web.Handler(MailboxShow)).Name("MailboxShow").Methods("GET")
r.Path("/mailbox/{name}/{id}/html").Handler(
web.Handler(MailboxHTML)).Name("MailboxHtml").Methods("GET")
r.Path("/mailbox/{name}/{id}/source").Handler(
web.Handler(MailboxSource)).Name("MailboxSource").Methods("GET")
r.Path("/mailbox/dattach/{name}/{id}/{num}/{file}").Handler(
web.Handler(MailboxDownloadAttach)).Name("MailboxDownloadAttach").Methods("GET")
r.Path("/mailbox/vattach/{name}/{id}/{num}/{file}").Handler(
web.Handler(MailboxViewAttach)).Name("MailboxViewAttach").Methods("GET")
}

View File

@@ -3,7 +3,7 @@ package sanitize_test
import ( import (
"testing" "testing"
"github.com/jhillyerd/inbucket/sanitize" "github.com/jhillyerd/inbucket/pkg/webui/sanitize"
) )
// TestHTMLPlainStrings test plain text passthrough // TestHTMLPlainStrings test plain text passthrough

View File

@@ -1,23 +0,0 @@
package rest
import "github.com/gorilla/mux"
import "github.com/jhillyerd/inbucket/httpd"
// SetupRoutes populates the routes for the REST interface
func SetupRoutes(r *mux.Router) {
// API v1
r.Path("/api/v1/mailbox/{name}").Handler(
httpd.Handler(MailboxListV1)).Name("MailboxListV1").Methods("GET")
r.Path("/api/v1/mailbox/{name}").Handler(
httpd.Handler(MailboxPurgeV1)).Name("MailboxPurgeV1").Methods("DELETE")
r.Path("/api/v1/mailbox/{name}/{id}").Handler(
httpd.Handler(MailboxShowV1)).Name("MailboxShowV1").Methods("GET")
r.Path("/api/v1/mailbox/{name}/{id}").Handler(
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/messages").Handler(
httpd.Handler(MonitorAllMessagesV1)).Name("MonitorAllMessagesV1").Methods("GET")
r.Path("/api/v1/monitor/messages/{name}").Handler(
httpd.Handler(MonitorMailboxMessagesV1)).Name("MonitorMailboxMessagesV1").Methods("GET")
}

View File

@@ -1,35 +0,0 @@
// Package webui powers Inbucket's web GUI
package webui
import (
"github.com/gorilla/mux"
"github.com/jhillyerd/inbucket/httpd"
)
// SetupRoutes populates routes for the webui into the provided Router
func SetupRoutes(r *mux.Router) {
r.Path("/").Handler(
httpd.Handler(RootIndex)).Name("RootIndex").Methods("GET")
r.Path("/monitor").Handler(
httpd.Handler(RootMonitor)).Name("RootMonitor").Methods("GET")
r.Path("/monitor/{name}").Handler(
httpd.Handler(RootMonitorMailbox)).Name("RootMonitorMailbox").Methods("GET")
r.Path("/status").Handler(
httpd.Handler(RootStatus)).Name("RootStatus").Methods("GET")
r.Path("/link/{name}/{id}").Handler(
httpd.Handler(MailboxLink)).Name("MailboxLink").Methods("GET")
r.Path("/mailbox").Handler(
httpd.Handler(MailboxIndex)).Name("MailboxIndex").Methods("GET")
r.Path("/mailbox/{name}").Handler(
httpd.Handler(MailboxList)).Name("MailboxList").Methods("GET")
r.Path("/mailbox/{name}/{id}").Handler(
httpd.Handler(MailboxShow)).Name("MailboxShow").Methods("GET")
r.Path("/mailbox/{name}/{id}/html").Handler(
httpd.Handler(MailboxHTML)).Name("MailboxHtml").Methods("GET")
r.Path("/mailbox/{name}/{id}/source").Handler(
httpd.Handler(MailboxSource)).Name("MailboxSource").Methods("GET")
r.Path("/mailbox/dattach/{name}/{id}/{num}/{file}").Handler(
httpd.Handler(MailboxDownloadAttach)).Name("MailboxDownloadAttach").Methods("GET")
r.Path("/mailbox/vattach/{name}/{id}/{num}/{file}").Handler(
httpd.Handler(MailboxViewAttach)).Name("MailboxViewAttach").Methods("GET")
}