Blame


1 7583dd64 2022-04-13 o package mailmux
2 7583dd64 2022-04-13 o
3 7583dd64 2022-04-13 o import (
4 7583dd64 2022-04-13 o "encoding/json"
5 7583dd64 2022-04-13 o "errors"
6 7583dd64 2022-04-13 o "io"
7 7583dd64 2022-04-13 o "time"
8 7583dd64 2022-04-13 o )
9 7583dd64 2022-04-13 o
10 7583dd64 2022-04-13 o const (
11 7583dd64 2022-04-13 o Tregister = 1 + iota
12 7583dd64 2022-04-13 o Rregister
13 7583dd64 2022-04-13 o Rerror
14 cb474497 2022-04-19 o Tcreate
15 cb474497 2022-04-19 o Rcreate
16 7583dd64 2022-04-13 o Tlist
17 7583dd64 2022-04-13 o Rlist
18 7583dd64 2022-04-13 o Tremove
19 cb474497 2022-04-19 o Rremove
20 71bdede3 2022-04-21 o Tauth
21 71bdede3 2022-04-21 o Rauth
22 7583dd64 2022-04-13 o )
23 7583dd64 2022-04-13 o
24 c7ecbae7 2022-04-13 o // Mcall represents a message passed between mailmux clients and servers.
25 7583dd64 2022-04-13 o // Operations requested by clients are T-messages (such as Tregister).
26 c7ecbae7 2022-04-13 o // Servers respond with the corresponding R-message (such as Rregister).
27 c7ecbae7 2022-04-13 o // Servers may instead respond with Rerror to inform the client, with a diagnostic message,
28 c7ecbae7 2022-04-13 o // that the request was not completed successfully.
29 7583dd64 2022-04-13 o // This design is loosely based on the Plan 9 network file protocol 9P.
30 7583dd64 2022-04-13 o type Mcall struct {
31 5b8260a5 2022-04-13 o Type uint
32 925168e0 2022-04-14 o Username string `json:",omitempty"` // Tregister, Rregister
33 925168e0 2022-04-14 o Password string `json:",omitempty"` // Tregister
34 925168e0 2022-04-14 o Error string `json:",omitempty"` // Rerror
35 925168e0 2022-04-14 o Aliases []Alias `json:",omitempty"` // Rnew, Rlist, Tremove
36 cb474497 2022-04-19 o Expiry time.Time `json:",omitempty"` // Tcreate, Rnew
37 7583dd64 2022-04-13 o }
38 7583dd64 2022-04-13 o
39 c7ecbae7 2022-04-13 o // ParseMcall parses and validates a JSON-encoded Mcall from r.
40 7583dd64 2022-04-13 o func ParseMcall(r io.Reader) (*Mcall, error) {
41 7583dd64 2022-04-13 o var mc Mcall
42 7583dd64 2022-04-13 o if err := json.NewDecoder(r).Decode(&mc); err != nil {
43 7583dd64 2022-04-13 o return nil, err
44 7583dd64 2022-04-13 o }
45 a7e7d1d5 2022-04-13 o switch mc.Type {
46 a7e7d1d5 2022-04-13 o case Rerror:
47 a7e7d1d5 2022-04-13 o if mc.Error == "" {
48 a7e7d1d5 2022-04-13 o return nil, errors.New("empty error message")
49 a7e7d1d5 2022-04-13 o }
50 71bdede3 2022-04-21 o case Tauth:
51 a7e7d1d5 2022-04-13 o if mc.Username == "" {
52 a7e7d1d5 2022-04-13 o return nil, errors.New("empty username")
53 71bdede3 2022-04-21 o }
54 71bdede3 2022-04-21 o if mc.Password == "" {
55 a7e7d1d5 2022-04-13 o return nil, errors.New("empty password")
56 a7e7d1d5 2022-04-13 o }
57 71bdede3 2022-04-21 o case Tregister, Tcreate, Tlist, Tremove:
58 71bdede3 2022-04-21 o // check required params
59 7583dd64 2022-04-13 o }
60 7583dd64 2022-04-13 o return &mc, nil
61 7583dd64 2022-04-13 o }
62 71bdede3 2022-04-21 o
63 71bdede3 2022-04-21 o func writeMcall(w io.Writer, mcall *Mcall) error {
64 71bdede3 2022-04-21 o return json.NewEncoder(w).Encode(mcall)
65 71bdede3 2022-04-21 o }
66 71bdede3 2022-04-21 o
67 71bdede3 2022-04-21 o // rerror writes a JSON-encoded Rerror message to the underlying writer
68 71bdede3 2022-04-21 o // with its Error field set to errormsg.
69 71bdede3 2022-04-21 o func rerror(w io.Writer, errormsg string) error {
70 71bdede3 2022-04-21 o rmsg := &Mcall{Type: Rerror, Error: errormsg}
71 71bdede3 2022-04-21 o return writeMcall(w, rmsg)
72 71bdede3 2022-04-21 o }