File: server.go

package info (click to toggle)
cam2ip 1.6-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 280 kB
  • sloc: sh: 81; makefile: 3
file content (87 lines) | stat: -rw-r--r-- 1,986 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Package server.
package server

import (
	"fmt"
	"net"
	"net/http"

	"github.com/abbot/go-http-auth"

	"github.com/gen2brain/cam2ip/handlers"
	"github.com/gen2brain/cam2ip/reader"
)

// Server struct.
type Server struct {
	Name    string
	Version string

	Bind     string
	Htpasswd string

	Index int
	Delay int

	FrameWidth  float64
	FrameHeight float64

	Rotate int

	NoWebGL   bool
	Timestamp bool

	FileName string

	Reader reader.ImageReader
}

// 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))
	}

	http.Handle("/html", newAuthHandler(handlers.NewHTML(s.FrameWidth, s.FrameHeight, s.NoWebGL), basic))
	http.Handle("/jpeg", newAuthHandler(handlers.NewJPEG(s.Reader), basic))
	http.Handle("/mjpeg", newAuthHandler(handlers.NewMJPEG(s.Reader, s.Delay), basic))
	http.Handle("/socket", newAuthHandler(handlers.NewSocket(s.Reader, s.Delay), basic))

	http.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
	})

	http.Handle("/", newAuthHandler(handlers.NewIndex(), basic))

	srv := &http.Server{}

	listener, err := net.Listen("tcp4", 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)
	})
}