...
1 package main
2
3 import (
4 "fmt"
5 "io"
6 "log"
7 "net/http"
8 "strconv"
9 "strings"
10 )
11
12
13
14 type filter struct {
15 To string
16 From string
17 }
18
19 func (f *filter) Match(m rcvdMail) bool {
20 if f.To != "" && f.To != m.To {
21 return false
22 }
23 if f.From != "" && f.From != m.From {
24 return false
25 }
26 return true
27 }
28
29
40
41 func (srv *mailSrv) setupHTTP(serveMux *http.ServeMux) {
42 serveMux.HandleFunc("/count", srv.httpCount)
43 serveMux.HandleFunc("/clear", srv.httpClear)
44 serveMux.Handle("/mail/", http.StripPrefix("/mail/", http.HandlerFunc(srv.httpGetMail)))
45 }
46
47 func (srv *mailSrv) httpClear(w http.ResponseWriter, r *http.Request) {
48 if r.Method == "POST" {
49 srv.allMailMutex.Lock()
50 srv.allReceivedMail = nil
51 srv.allMailMutex.Unlock()
52 w.WriteHeader(200)
53 } else {
54 w.WriteHeader(405)
55 }
56 }
57
58 func (srv *mailSrv) httpCount(w http.ResponseWriter, r *http.Request) {
59 count := 0
60 srv.iterMail(extractFilter(r), func(m rcvdMail) bool {
61 count++
62 return false
63 })
64 fmt.Fprintf(w, "%d\n", count)
65 }
66
67 func (srv *mailSrv) httpGetMail(w http.ResponseWriter, r *http.Request) {
68 mailNum, err := strconv.Atoi(strings.Trim(r.URL.Path, "/"))
69 if err != nil {
70 w.WriteHeader(400)
71 log.Println("mail-test-srv: bad request:", r.URL.Path, "-", err)
72 return
73 }
74 idx := 0
75 found := srv.iterMail(extractFilter(r), func(m rcvdMail) bool {
76 if mailNum == idx {
77 printMail(w, m)
78 return true
79 }
80 idx++
81 return false
82 })
83 if !found {
84 w.WriteHeader(404)
85 }
86 }
87
88 func extractFilter(r *http.Request) filter {
89 values := r.URL.Query()
90 return filter{To: values.Get("to"), From: values.Get("from")}
91 }
92
93 func (srv *mailSrv) iterMail(f filter, cb func(rcvdMail) bool) bool {
94 srv.allMailMutex.Lock()
95 defer srv.allMailMutex.Unlock()
96 for _, v := range srv.allReceivedMail {
97 if !f.Match(v) {
98 continue
99 }
100 if cb(v) {
101 return true
102 }
103 }
104 return false
105 }
106
107 func printMail(w io.Writer, mail rcvdMail) {
108 fmt.Fprintf(w, "FROM %s\n", mail.From)
109 fmt.Fprintf(w, "TO %s\n", mail.To)
110 fmt.Fprintf(w, "\n%s\n", mail.Mail)
111 }
112
View as plain text