Files
cam2ip/server/server.go

101 lines
2.1 KiB
Go

// Package server.
package server
import (
"fmt"
"net"
"net/http"
"time"
"github.com/abbot/go-http-auth"
"github.com/gen2brain/cam2ip/handlers"
)
// Server struct.
type Server struct {
Name string
Version string
Index int
Device string
Delay int
Width float64
Height float64
Quality int
Rotate int
Flip string
NoWebGL bool
Timestamp bool
TimeFormat string
Bind string
Htpasswd string
Lazy bool
Open func() (handlers.ImageReader, error)
}
// NewServer returns new Server.
func NewServer() *Server {
s := &Server{}
return s
}
// ListenAndServe listens on the TCP address and serves requests.
func (s *Server) ListenAndServe() error {
var basic *auth.BasicAuth
if s.Htpasswd != "" {
realm := fmt.Sprintf("%s/%s", s.Name, s.Version)
basic = auth.NewBasicAuthenticator(realm, auth.HtpasswdFileProvider(s.Htpasswd))
}
stream := handlers.NewStream(s.Open, s.Delay, s.Quality, s.Lazy)
mux := http.NewServeMux()
mux.Handle("/html", newAuthHandler(handlers.NewHTML(s.Width, s.Height, s.NoWebGL), basic))
mux.Handle("/jpeg", newAuthHandler(handlers.NewJPEG(stream), basic))
mux.Handle("/mjpeg", newAuthHandler(handlers.NewMJPEG(stream), basic))
mux.Handle("/socket", newAuthHandler(handlers.NewSocket(stream), basic))
mux.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
mux.Handle("/", newAuthHandler(handlers.NewIndex(), basic))
srv := &http.Server{
Handler: mux,
ReadHeaderTimeout: 5 * time.Second,
}
listener, err := net.Listen("tcp", s.Bind)
if err != nil {
return err
}
return srv.Serve(listener)
}
// newAuthHandler wraps handler and checks auth.
func newAuthHandler(handler http.Handler, authenticator *auth.BasicAuth) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if authenticator != nil {
w.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=\"%s\"", authenticator.Realm))
if authenticator.CheckAuth(r) == "" {
http.Error(w, "401 Unauthorized", http.StatusUnauthorized)
return
}
}
handler.ServeHTTP(w, r)
})
}