2019-02-10 00:08:21 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2019-04-29 09:34:13 +00:00
|
|
|
"encoding/base64"
|
2019-02-10 00:08:21 +00:00
|
|
|
"fmt"
|
|
|
|
"mime/multipart"
|
|
|
|
"net/http"
|
|
|
|
"net/textproto"
|
|
|
|
|
2019-04-29 09:34:13 +00:00
|
|
|
"github.com/pkg/errors"
|
2019-02-10 00:08:21 +00:00
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
|
|
|
func handleMJPEG(res http.ResponseWriter, r *http.Request, imgs chan []byte, uid string) {
|
|
|
|
if r.Method != "GET" {
|
|
|
|
http.Error(res, "405 Method Not Allowed", http.StatusMethodNotAllowed)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
logger := log.WithField("id", uid)
|
|
|
|
|
|
|
|
mimeWriter := multipart.NewWriter(res)
|
|
|
|
mimeWriter.SetBoundary("--boundary")
|
|
|
|
defer mimeWriter.Close()
|
|
|
|
|
|
|
|
res.Header().Add("Connection", "close")
|
|
|
|
res.Header().Add("Cache-Control", "no-store, no-cache")
|
|
|
|
res.Header().Add("Content-Type", fmt.Sprintf("multipart/x-mixed-replace;boundary=%s", mimeWriter.Boundary()))
|
|
|
|
|
|
|
|
cn := res.(http.CloseNotifier).CloseNotify()
|
|
|
|
errC := 0
|
|
|
|
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-cn:
|
|
|
|
return
|
|
|
|
|
|
|
|
case img := <-imgs:
|
2019-04-29 09:34:13 +00:00
|
|
|
err := func() error {
|
|
|
|
partHeader := make(textproto.MIMEHeader)
|
|
|
|
partHeader.Add("Content-Type", "image/jpeg")
|
|
|
|
partHeader.Add("Content-Transfer-Encoding", "base64")
|
2019-02-10 00:08:21 +00:00
|
|
|
|
2019-04-29 09:34:13 +00:00
|
|
|
partWriter, err := mimeWriter.CreatePart(partHeader)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "Unable to create mime part")
|
|
|
|
}
|
|
|
|
|
|
|
|
b64w := base64.NewEncoder(base64.StdEncoding, partWriter)
|
|
|
|
defer b64w.Close()
|
|
|
|
|
|
|
|
_, err = b64w.Write(img)
|
|
|
|
|
|
|
|
return errors.Wrap(err, "Unable to write image")
|
|
|
|
}()
|
2019-02-10 00:08:21 +00:00
|
|
|
|
|
|
|
if err != nil {
|
2019-04-29 09:34:13 +00:00
|
|
|
logger.WithError(err).Error("Unable to process image")
|
2019-02-10 00:08:21 +00:00
|
|
|
errC++
|
|
|
|
|
|
|
|
if errC > 5 {
|
|
|
|
logger.Error("Too many errors, killing connection")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
errC = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|