diff --git a/go.mod b/go.mod index a2b47c9..c9a49e1 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/dim13/otpauth go 1.15 require ( + github.com/dim13/sse v0.0.0-20201210183205-eb3832327322 github.com/golang/protobuf v1.4.3 github.com/google/uuid v1.1.2 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e diff --git a/go.sum b/go.sum index cf7de7c..53af973 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/dim13/sse v0.0.0-20201210183205-eb3832327322 h1:4+OqyQ9YCRC0WrQKfJHR0Dvqk7tQdML7h2T4e4RjN7o= +github.com/dim13/sse v0.0.0-20201210183205-eb3832327322/go.mod h1:N3FRoDR3nzgckc5E5A5XPpmIlGvEdOBRMlhh5hXLvqk= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= diff --git a/http.go b/http.go index d049f9d..f9d4de0 100644 --- a/http.go +++ b/http.go @@ -9,7 +9,7 @@ import ( "time" "github.com/dim13/otpauth/migration" - "github.com/dim13/otpauth/sse" + "github.com/dim13/sse" "github.com/google/uuid" ) @@ -83,7 +83,7 @@ func serve(addr string, p *migration.Payload) error { for _, op := range p.OtpParameters { http.Handle("/"+op.UUID().String()+".png", op) } - events := sse.NewBroker("data", 100) + events := sse.New("data", 100) http.Handle("/events", events) go func() { enc := json.NewEncoder(events) diff --git a/sse/sse.go b/sse/sse.go deleted file mode 100644 index 97b371c..0000000 --- a/sse/sse.go +++ /dev/null @@ -1,64 +0,0 @@ -package sse - -import ( - "fmt" - "net/http" - "strings" - "sync" -) - -type Broker struct { - event string - queue int - clients *sync.Map -} - -func (b *Broker) Write(p []byte) (n int, err error) { - b.clients.Range(func(key, value interface{}) bool { - ch := key.(chan string) - select { - case ch <- string(p): - default: - } - return true - }) - return len(p), nil -} - -func NewBroker(event string, queue int) *Broker { - return &Broker{event: event, clients: new(sync.Map), queue: queue} -} - -func (b Broker) ServeHTTP(w http.ResponseWriter, r *http.Request) { - flusher, ok := w.(http.Flusher) - if !ok { - http.Error(w, "not a flusher", http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "text/event-stream") - w.Header().Set("Cache-Control", "no-cache") - w.Header().Set("Connection", "keep-alive") - w.Header().Set("Access-Control-Allow-Origin", "*") - - ch := make(chan string, b.queue) - defer close(ch) - - b.clients.Store(ch, nil) - defer b.clients.Delete(ch) - - for data := range ch { - select { - case <-r.Context().Done(): - return - default: - if b.event != "" { - fmt.Fprintf(w, "event: %s\n", b.event) - } - for _, s := range strings.Split(data, "\n") { - fmt.Fprintf(w, "data: %s\n", s) - } - fmt.Fprintf(w, "\n") - flusher.Flush() - } - } -}