From 6a696e3a6877db8d0e47d85e08e8d1b3ca8fcb95 Mon Sep 17 00:00:00 2001 From: Peter Stuifzand Date: Tue, 30 Jan 2018 20:01:33 +0100 Subject: [PATCH] Save subscribers, add load and save --- cmd/hubserver/main.go | 70 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/cmd/hubserver/main.go b/cmd/hubserver/main.go index aa47e83..acdb003 100644 --- a/cmd/hubserver/main.go +++ b/cmd/hubserver/main.go @@ -1,17 +1,21 @@ package main import ( + "encoding/json" "fmt" + "io/ioutil" "log" "math/rand" "net/http" "net/url" + "os" "strconv" + "strings" ) const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -func RandStringBytes(n int) string { +func randStringBytes(n int) string { b := make([]byte, n) for i := range b { b[i] = letterBytes[rand.Intn(len(letterBytes))] @@ -19,8 +23,13 @@ func RandStringBytes(n int) string { return string(b) } +type Subscriber struct { + Callback string + LeaseSeconds int64 +} + type subscriptionHandler struct { - Subscribers []string + Subscribers map[string][]Subscriber } func (handler *subscriptionHandler) handlePublish(w http.ResponseWriter, r *http.Request) error { @@ -34,11 +43,12 @@ func (handler *subscriptionHandler) handleSubscription(w http.ResponseWriter, r callback := r.Form.Get("hub.callback") topic := r.Form.Get("hub.topic") leaseSecondsStr := r.Form.Get("hub.lease_seconds") - _, err := strconv.ParseInt(leaseSecondsStr, 10, 64) + leaseSeconds, err := strconv.ParseInt(leaseSecondsStr, 10, 64) if leaseSecondsStr != "" && err != nil { http.Error(w, "hub.lease_seconds is used, but not valid", 400) return nil } + //secret := r.Form.Get("hub.secret") callbackURL, err := url.Parse(callback) if err != nil { @@ -56,25 +66,49 @@ func (handler *subscriptionHandler) handleSubscription(w http.ResponseWriter, r go func() { client := http.Client{} + ourChallenge := randStringBytes(12) + validationURL := callbackURL q := validationURL.Query() q.Add("hub.mode", "subscribe") q.Add("hub.topic", topicURL.String()) - q.Add("hub.challenge", RandStringBytes(12)) + q.Add("hub.challenge", ourChallenge) q.Add("hub.lease_seconds", leaseSecondsStr) validationURL.RawQuery = q.Encode() log.Println(validationURL) req, err := http.NewRequest(http.MethodGet, callbackURL.String(), nil) + if err != nil { + log.Println(err) + return + } res, err := client.Do(req) + if err != nil { + log.Println(err) + return + } + defer res.Body.Close() - log.Println(res, err) + body, err := ioutil.ReadAll(res.Body) + if err != nil { + log.Println(err) + } + + if strings.Contains(string(body), ourChallenge) { + // challenge accepted + handler.addSubscriberCallback(topicURL.String(), Subscriber{callbackURL.String(), leaseSeconds}) + } }() return nil } +func (handler *subscriptionHandler) addSubscriberCallback(topic string, subscriber Subscriber) { + handler.Subscribers[topic] = append(handler.Subscribers[topic], subscriber) + handler.save() +} + func (handler *subscriptionHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Content-Type") != "application/x-www-form-urlencoded" { http.Error(w, "Bad Request", 400) @@ -102,10 +136,32 @@ func (handler *subscriptionHandler) ServeHTTP(w http.ResponseWriter, r *http.Req } } +func (handler *subscriptionHandler) load() error { + file, err := os.Open("./subscription.json") + if err != nil { + return err + } + defer file.Close() + dec := json.NewDecoder(file) + dec.Decode(handler.Subscribers) + return nil +} + +func (handler *subscriptionHandler) save() error { + file, err := os.Create("./subscription.json") + if err != nil { + return err + } + defer file.Close() + dec := json.NewEncoder(file) + dec.SetIndent("", " ") + dec.Encode(handler.Subscribers) + return nil +} + func main() { handler := &subscriptionHandler{} - //handler.Subscribers - + handler.load() http.Handle("/", handler) log.Fatal(http.ListenAndServe(":80", nil)) }