summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/app/app.go26
-rw-r--r--pkg/app/config.go36
-rw-r--r--pkg/app/listener.go33
3 files changed, 89 insertions, 6 deletions
diff --git a/pkg/app/app.go b/pkg/app/app.go
index befe1a1..7774a71 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -4,6 +4,7 @@ import (
"errors"
"html/template"
"log"
+ "net"
"net/http"
"github.com/gorilla/mux"
@@ -11,16 +12,23 @@ import (
)
type App struct {
+ Config *Config
Library *media.Library
Playlist media.Playlist
Templates *template.Template
+ Listener net.Listener
Router *mux.Router
}
-func NewApp() (*App, error) {
- a := &App{}
+func NewApp(cfg *Config) (*App, error) {
+ if cfg == nil {
+ cfg = DefaultConfig()
+ }
+ a := &App{
+ Config: cfg,
+ }
lib := media.NewLibrary()
- err := lib.Import("./videos")
+ err := lib.Import(cfg.LibraryPath)
if err != nil {
return nil, err
}
@@ -30,6 +38,11 @@ func NewApp() (*App, error) {
return nil, errors.New("No valid videos found")
}
a.Playlist = pl
+ ln, err := newListener(cfg.Server)
+ if err != nil {
+ return nil, err
+ }
+ a.Listener = ln
a.Templates = template.Must(template.ParseGlob("templates/*"))
r := mux.NewRouter().StrictSlash(true)
r.HandleFunc("/", a.indexHandler).Methods("GET")
@@ -45,8 +58,8 @@ func NewApp() (*App, error) {
return a, nil
}
-func (a *App) Run(addr string) error {
- return http.ListenAndServe(addr, a.Router)
+func (a *App) Run() error {
+ return http.Serve(a.Listener, a.Router)
}
func (a *App) indexHandler(w http.ResponseWriter, r *http.Request) {
@@ -84,7 +97,8 @@ func (a *App) videoHandler(w http.ResponseWriter, r *http.Request) {
disposition := "attachment; filename=\"" + title + ".mp4\""
w.Header().Set("Content-Disposition", disposition)
w.Header().Set("Content-Type", "video/mp4")
- http.ServeFile(w, r, "./videos/"+id+".mp4")
+ path := a.Config.LibraryPath + "/" + id + ".mp4"
+ http.ServeFile(w, r, path)
}
func (a *App) thumbHandler(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/app/config.go b/pkg/app/config.go
new file mode 100644
index 0000000..c4ea170
--- /dev/null
+++ b/pkg/app/config.go
@@ -0,0 +1,36 @@
+package app
+
+import (
+ "encoding/json"
+ "os"
+)
+
+type Config struct {
+ LibraryPath string `json:"library"`
+ Server *ServerConfig `json:"server"`
+}
+
+type ServerConfig struct {
+ Host string `json:"host"`
+ Port int `json:"port"`
+}
+
+func DefaultConfig() *Config {
+ return &Config{
+ LibraryPath: "videos",
+ Server: &ServerConfig{
+ Host: "127.0.0.1",
+ Port: 0,
+ },
+ }
+}
+
+func (c *Config) ReadFile(path string) error {
+ f, err := os.Open(path)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ d := json.NewDecoder(f)
+ return d.Decode(c)
+}
diff --git a/pkg/app/listener.go b/pkg/app/listener.go
new file mode 100644
index 0000000..7d42290
--- /dev/null
+++ b/pkg/app/listener.go
@@ -0,0 +1,33 @@
+package app
+
+import (
+ "fmt"
+ "net"
+ "time"
+)
+
+func newListener(cfg *ServerConfig) (net.Listener, error) {
+ addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
+ ln, err := net.Listen("tcp", addr)
+ if err != nil {
+ return nil, err
+ }
+ // set actual port on config object (in case original port was 0)
+ cfg.Port = ln.Addr().(*net.TCPAddr).Port
+ return tcpListener{ln.(*net.TCPListener)}, nil
+}
+
+// custom TCP listener with keep-alive timeout
+type tcpListener struct {
+ *net.TCPListener
+}
+
+func (ln tcpListener) Accept() (net.Conn, error) {
+ tc, err := ln.AcceptTCP()
+ if err != nil {
+ return nil, err
+ }
+ tc.SetKeepAlive(true)
+ tc.SetKeepAlivePeriod(3 * time.Minute)
+ return tc, nil
+}