112 lines
2.5 KiB
Go
112 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// filter filters mails based on the To: and From: fields.
|
|
// The zero value matches all mails.
|
|
type filter struct {
|
|
To string
|
|
From string
|
|
}
|
|
|
|
func (f *filter) Match(m rcvdMail) bool {
|
|
if f.To != "" && f.To != m.To {
|
|
return false
|
|
}
|
|
if f.From != "" && f.From != m.From {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
/*
|
|
/count - number of mails
|
|
/count?to=foo@bar.com - number of mails for foo@bar.com
|
|
/count?from=service@test.org - number of mails sent by service@test.org
|
|
/clear - clear the mail list
|
|
/mail/0 - first mail
|
|
/mail/1 - second mail
|
|
/mail/0?to=foo@bar.com - first mail for foo@bar.com
|
|
/mail/1?to=foo@bar.com - second mail for foo@bar.com
|
|
/mail/1?to=foo@bar.com&from=service@test.org - second mail for foo@bar.com from service@test.org
|
|
*/
|
|
|
|
func (srv *mailSrv) setupHTTP(serveMux *http.ServeMux) {
|
|
serveMux.HandleFunc("/count", srv.httpCount)
|
|
serveMux.HandleFunc("/clear", srv.httpClear)
|
|
serveMux.Handle("/mail/", http.StripPrefix("/mail/", http.HandlerFunc(srv.httpGetMail)))
|
|
}
|
|
|
|
func (srv *mailSrv) httpClear(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method == "POST" {
|
|
srv.allMailMutex.Lock()
|
|
srv.allReceivedMail = nil
|
|
srv.allMailMutex.Unlock()
|
|
w.WriteHeader(200)
|
|
} else {
|
|
w.WriteHeader(405)
|
|
}
|
|
}
|
|
|
|
func (srv *mailSrv) httpCount(w http.ResponseWriter, r *http.Request) {
|
|
count := 0
|
|
srv.iterMail(extractFilter(r), func(m rcvdMail) bool {
|
|
count++
|
|
return false
|
|
})
|
|
fmt.Fprintf(w, "%d\n", count)
|
|
}
|
|
|
|
func (srv *mailSrv) httpGetMail(w http.ResponseWriter, r *http.Request) {
|
|
mailNum, err := strconv.Atoi(strings.Trim(r.URL.Path, "/"))
|
|
if err != nil {
|
|
w.WriteHeader(400)
|
|
log.Println("mail-test-srv: bad request:", r.URL.Path, "-", err)
|
|
return
|
|
}
|
|
idx := 0
|
|
found := srv.iterMail(extractFilter(r), func(m rcvdMail) bool {
|
|
if mailNum == idx {
|
|
printMail(w, m)
|
|
return true
|
|
}
|
|
idx++
|
|
return false
|
|
})
|
|
if !found {
|
|
w.WriteHeader(404)
|
|
}
|
|
}
|
|
|
|
func extractFilter(r *http.Request) filter {
|
|
values := r.URL.Query()
|
|
return filter{To: values.Get("to"), From: values.Get("from")}
|
|
}
|
|
|
|
func (srv *mailSrv) iterMail(f filter, cb func(rcvdMail) bool) bool {
|
|
srv.allMailMutex.Lock()
|
|
defer srv.allMailMutex.Unlock()
|
|
for _, v := range srv.allReceivedMail {
|
|
if !f.Match(v) {
|
|
continue
|
|
}
|
|
if cb(v) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func printMail(w io.Writer, mail rcvdMail) {
|
|
fmt.Fprintf(w, "FROM %s\n", mail.From)
|
|
fmt.Fprintf(w, "TO %s\n", mail.To)
|
|
fmt.Fprintf(w, "\n%s\n", mail.Mail)
|
|
}
|