aboutsummaryrefslogtreecommitdiff
path: root/inform/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'inform/server.go')
-rw-r--r--inform/server.go92
1 files changed, 92 insertions, 0 deletions
diff --git a/inform/server.go b/inform/server.go
new file mode 100644
index 0000000..7e33a86
--- /dev/null
+++ b/inform/server.go
@@ -0,0 +1,92 @@
1package inform
2
3import (
4 "fmt"
5 "log"
6 "net/http"
7 "time"
8)
9
10type StateTree struct {
11 states map[string]map[int]int
12}
13
14func NewStateTree() *StateTree {
15 return &StateTree{make(map[string]map[int]int)}
16}
17
18func (t *StateTree) ensureNode(device string, port int) {
19 _, ok := t.states[device]
20 if !ok {
21 t.states[device] = make(map[int]int)
22 }
23
24 _, ok = t.states[device][port]
25 if !ok {
26 t.states[device][port] = 0
27 }
28}
29
30func (t *StateTree) GetState(device string, port int) int {
31 t.ensureNode(device, port)
32 return t.states[device][port]
33}
34
35func (t *StateTree) SetState(device string, port, value int) {
36 t.ensureNode(device, port)
37 t.states[device][port] = value
38}
39
40func Log(handler http.Handler) http.Handler {
41 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
42 handler.ServeHTTP(w, r)
43 t := time.Now().Format("02/Jan/2006 15:04:05")
44 log.Printf("%s - - [%s] \"%s %s %s\"", r.RemoteAddr, t, r.Method, r.URL, r.Proto)
45 // Addr - - [D/M/Y H:M:S] "Method RequestURI Proto" Code Size
46 // 127.0.0.1 - - [24/Sep/2016 14:30:35] "GET / HTTP/1.1" 200 -
47 })
48}
49
50type InformHandler struct {
51 Codec *Codec
52 StateTree *StateTree
53}
54
55func (h *InformHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
56 if r.Method != http.MethodPost {
57 http.Error(w, "405 Method Not Allowed", http.StatusMethodNotAllowed)
58 return
59 }
60
61 if r.URL != nil && r.URL.Path != "/inform" {
62 http.Error(w, "404 Not Found", http.StatusNotFound)
63 return
64 }
65
66 msg, err := h.Codec.Unmarshal(r.Body)
67 if err != nil {
68 http.Error(w, "Bad Request", http.StatusBadRequest)
69 return
70 }
71
72 pl := NewInformWrapper()
73 copy(pl.MacAddr, msg.MacAddr)
74 pl.SetEncrypted(true)
75
76 // TODO: compare current state to tree and update
77
78 res, err := h.Codec.Marshal(pl)
79 if err != nil {
80 http.Error(w, "Server Error", 500)
81 return
82 }
83
84 fmt.Fprintf(w, "%s", res)
85}
86
87func NewServer(handler *InformHandler) *http.Server {
88 return &http.Server{
89 Addr: ":6080",
90 Handler: Log(handler),
91 }
92}