boulder/test/mail-test-srv/http.go

110 lines
2.2 KiB
Go

package main
import (
"fmt"
"io"
"log"
"net/http"
"regexp"
"strconv"
"strings"
)
// toFilter filters mails based on the To: field.
// The zero value matches all mails.
type toFilter struct {
To string
}
func (f *toFilter) Match(m rcvdMail) bool {
if f.To != "" && f.To != m.To {
return false
}
return true
}
/*
/count - number of mails
/count?to=foo@bar.com - number of mails for foo@bar.com
/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
*/
func (s *mailSrv) setupHTTP(serveMux *http.ServeMux) {
serveMux.HandleFunc("/count", s.httpCount)
serveMux.HandleFunc("/clear", s.httpClear)
serveMux.Handle("/mail/", http.StripPrefix("/mail/", http.HandlerFunc(s.httpGetMail)))
}
func (s *mailSrv) httpClear(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
s.allMailMutex.Lock()
s.allReceivedMail = nil
s.allMailMutex.Unlock()
w.WriteHeader(200)
} else {
w.WriteHeader(405)
}
}
func (s *mailSrv) httpCount(w http.ResponseWriter, r *http.Request) {
count := 0
s.iterMail(extractFilter(r), func(m rcvdMail) bool {
count++
return false
})
fmt.Fprintf(w, "%d\n", count)
}
var rgxGetMail = regexp.MustCompile(`^(\d+)/?$`)
func (s *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 := s.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) toFilter {
values := r.URL.Query()
to := values.Get("to")
return toFilter{To: to}
}
func (s *mailSrv) iterMail(f toFilter, cb func(rcvdMail) bool) bool {
s.allMailMutex.Lock()
defer s.allMailMutex.Unlock()
for _, v := range s.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)
}