mirror of
https://gitlab.crans.org/nounous/ghostream.git
synced 2024-12-22 18:32:19 +00:00
Restructure configuration
This commit is contained in:
parent
c799a5b613
commit
5ac336393b
11
auth/auth.go
Normal file
11
auth/auth.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gitlab.crans.org/nounous/ghostream/auth/ldap"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Options holds web package configuration
|
||||||
|
type Options struct {
|
||||||
|
Backend string
|
||||||
|
LDAP ldap.Options
|
||||||
|
}
|
7
auth/ldap/ldap.go
Normal file
7
auth/ldap/ldap.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package ldap
|
||||||
|
|
||||||
|
// Options holds web package configuration
|
||||||
|
type Options struct {
|
||||||
|
URI string
|
||||||
|
UserDn string
|
||||||
|
}
|
1
go.mod
1
go.mod
@ -5,4 +5,5 @@ go 1.13
|
|||||||
require (
|
require (
|
||||||
github.com/prometheus/client_golang v1.7.1
|
github.com/prometheus/client_golang v1.7.1
|
||||||
github.com/spf13/viper v1.7.1
|
github.com/spf13/viper v1.7.1
|
||||||
|
honnef.co/go/tools v0.0.1-2019.2.3
|
||||||
)
|
)
|
||||||
|
3
go.sum
3
go.sum
@ -11,6 +11,7 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl
|
|||||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
@ -296,6 +297,7 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw
|
|||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc h1:NCy3Ohtk6Iny5V/reW2Ktypo4zIpWBdRJ1uFMjBxdg8=
|
||||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@ -345,5 +347,6 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2020 Cr@ns <roots@crans.org>
|
|
||||||
* Authors : Alexandre Iooss <erdnaxe@crans.org>
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Config holds app configuration
|
|
||||||
type Config struct {
|
|
||||||
AuthBackend string
|
|
||||||
LDAP struct {
|
|
||||||
URI string
|
|
||||||
UserDn string
|
|
||||||
}
|
|
||||||
Prometheus struct {
|
|
||||||
ListenAddress string
|
|
||||||
}
|
|
||||||
Site struct {
|
|
||||||
ListenAddress string
|
|
||||||
Name string
|
|
||||||
Hostname string
|
|
||||||
Favicon string
|
|
||||||
WidgetURL string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// New configuration
|
|
||||||
func New() (*Config, error) {
|
|
||||||
// Load configuration from environnement variables
|
|
||||||
// Replace "." to "_" for nested structs
|
|
||||||
// e.g. GHOSTREAM_LDAP_URI will apply to Config.LDAP.URI
|
|
||||||
viper.SetEnvPrefix("ghostream")
|
|
||||||
replacer := strings.NewReplacer(".", "_")
|
|
||||||
viper.SetEnvKeyReplacer(replacer)
|
|
||||||
viper.AutomaticEnv()
|
|
||||||
|
|
||||||
// Load configuration file if exists
|
|
||||||
viper.SetConfigName("ghostream")
|
|
||||||
viper.SetConfigType("yaml")
|
|
||||||
viper.AddConfigPath("$HOME/.ghostream")
|
|
||||||
viper.AddConfigPath("/etc/ghostream")
|
|
||||||
viper.AddConfigPath(".")
|
|
||||||
if err := viper.ReadInConfig(); err != nil {
|
|
||||||
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
|
||||||
// Config file not found, ignore and use defaults
|
|
||||||
log.Print(err)
|
|
||||||
} else {
|
|
||||||
// Config file was found but another error was produced
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Config loaded
|
|
||||||
log.Printf("Using config file: %s", viper.ConfigFileUsed())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define configuration default values
|
|
||||||
viper.SetDefault("AuthBackend", "LDAP")
|
|
||||||
viper.SetDefault("LDAP.URI", "ldap://127.0.0.1:389")
|
|
||||||
viper.SetDefault("LDAP.UserDn", "cn=users,dc=example,dc=com")
|
|
||||||
viper.SetDefault("Prometheus.ListenAddress", "0.0.0.0:2112")
|
|
||||||
viper.SetDefault("Site.ListenAddress", "127.0.0.1:8080")
|
|
||||||
viper.SetDefault("Site.Name", "Ghostream")
|
|
||||||
viper.SetDefault("Site.Hostname", "localhost")
|
|
||||||
viper.SetDefault("Site.Favicon", "/favicon.ico")
|
|
||||||
|
|
||||||
config := &Config{}
|
|
||||||
err := viper.Unmarshal(config)
|
|
||||||
return config, err
|
|
||||||
}
|
|
@ -7,9 +7,13 @@ import (
|
|||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
"gitlab.crans.org/nounous/ghostream/internal/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Options holds web package configuration
|
||||||
|
type Options struct {
|
||||||
|
ListenAddress string
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ViewerServed is the total amount of viewer page served
|
// ViewerServed is the total amount of viewer page served
|
||||||
ViewerServed = promauto.NewCounter(prometheus.CounterOpts{
|
ViewerServed = promauto.NewCounter(prometheus.CounterOpts{
|
||||||
@ -19,9 +23,9 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ServeHTTP server that expose prometheus metrics
|
// ServeHTTP server that expose prometheus metrics
|
||||||
func ServeHTTP(cfg *config.Config) {
|
func ServeHTTP(cfg *Options) {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.Handle("/metrics", promhttp.Handler())
|
mux.Handle("/metrics", promhttp.Handler())
|
||||||
log.Printf("Monitoring listening on http://%s/", cfg.Prometheus.ListenAddress)
|
log.Printf("Monitoring HTTP server listening on %s", cfg.ListenAddress)
|
||||||
log.Fatal(http.ListenAndServe(cfg.Prometheus.ListenAddress, mux))
|
log.Fatal(http.ListenAndServe(cfg.ListenAddress, mux))
|
||||||
}
|
}
|
||||||
|
58
main.go
58
main.go
@ -2,27 +2,73 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"gitlab.crans.org/nounous/ghostream/internal/config"
|
"github.com/spf13/viper"
|
||||||
|
"gitlab.crans.org/nounous/ghostream/auth"
|
||||||
"gitlab.crans.org/nounous/ghostream/internal/monitoring"
|
"gitlab.crans.org/nounous/ghostream/internal/monitoring"
|
||||||
"gitlab.crans.org/nounous/ghostream/web"
|
"gitlab.crans.org/nounous/ghostream/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func loadConfiguration() {
|
||||||
|
// Load configuration from environnement variables
|
||||||
|
// Replace "." to "_" for nested structs
|
||||||
|
// e.g. GHOSTREAM_LDAP_URI will apply to Config.LDAP.URI
|
||||||
|
viper.SetEnvPrefix("ghostream")
|
||||||
|
replacer := strings.NewReplacer(".", "_")
|
||||||
|
viper.SetEnvKeyReplacer(replacer)
|
||||||
|
viper.AutomaticEnv()
|
||||||
|
|
||||||
|
// Load configuration file if exists
|
||||||
|
viper.SetConfigName("ghostream")
|
||||||
|
viper.SetConfigType("yaml")
|
||||||
|
viper.AddConfigPath("$HOME/.ghostream")
|
||||||
|
viper.AddConfigPath("/etc/ghostream")
|
||||||
|
viper.AddConfigPath(".")
|
||||||
|
if err := viper.ReadInConfig(); err != nil {
|
||||||
|
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
||||||
|
// Config file not found, ignore and use defaults
|
||||||
|
log.Print(err)
|
||||||
|
} else {
|
||||||
|
// Config file was found but another error was produced
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Config loaded
|
||||||
|
log.Printf("Using config file: %s", viper.ConfigFileUsed())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define configuration default values
|
||||||
|
viper.SetDefault("Auth.Backend", "LDAP")
|
||||||
|
viper.SetDefault("Auth.LDAP.URI", "ldap://127.0.0.1:389")
|
||||||
|
viper.SetDefault("Auth.LDAP.UserDn", "cn=users,dc=example,dc=com")
|
||||||
|
viper.SetDefault("Monitoring.ListenAddress", ":2112")
|
||||||
|
viper.SetDefault("Web.ListenAddress", "127.0.0.1:8080")
|
||||||
|
viper.SetDefault("Web.Name", "Ghostream")
|
||||||
|
viper.SetDefault("Web.Hostname", "localhost")
|
||||||
|
viper.SetDefault("Web.Favicon", "/favicon.ico")
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Load configuration
|
// Load configuration
|
||||||
cfg, err := config.New()
|
loadConfiguration()
|
||||||
if err != nil {
|
cfg := struct {
|
||||||
log.Fatal(err)
|
Auth auth.Options
|
||||||
|
Monitoring monitoring.Options
|
||||||
|
Web web.Options
|
||||||
|
}{}
|
||||||
|
if err := viper.Unmarshal(&cfg); err != nil {
|
||||||
|
log.Fatalln("Failed to load settings", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start web server routine
|
// Start web server routine
|
||||||
go func() {
|
go func() {
|
||||||
web.ServeHTTP(cfg)
|
web.ServeHTTP(&cfg.Web)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Start monitoring server routine
|
// Start monitoring server routine
|
||||||
go func() {
|
go func() {
|
||||||
monitoring.ServeHTTP(cfg)
|
monitoring.ServeHTTP(&cfg.Monitoring)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Wait for routines
|
// Wait for routines
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>{{if .Path}}{{.Path}} - {{end}}{{.Cfg.Site.Name}}</title>
|
<title>{{if .Path}}{{.Path}} - {{end}}{{.Cfg.Name}}</title>
|
||||||
<link rel="stylesheet" href="static/style.css">
|
<link rel="stylesheet" href="static/style.css">
|
||||||
<link rel="shortcut icon" href="static/favicon.ico">
|
<link rel="shortcut icon" href="static/favicon.ico">
|
||||||
</head>
|
</head>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{{define "index"}}
|
{{define "index"}}
|
||||||
<div style="max-width:720px;margin:0 auto; padding: 1rem">
|
<div style="max-width:720px;margin:0 auto; padding: 1rem">
|
||||||
<h1>{{.Cfg.Site.Name}}</h1>
|
<h1>{{.Cfg.Name}}</h1>
|
||||||
<p>
|
<p>
|
||||||
{{.Cfg.Site.Name}} est un service maintenu par le
|
{{.Cfg.Name}} est un service maintenu par le
|
||||||
<a href="https://crans.org/">Crans</a> permettant de diffuser
|
<a href="https://crans.org/">Crans</a> permettant de diffuser
|
||||||
un contenu vidéo. Il a pour but d'être utilisé pour diffuser
|
un contenu vidéo. Il a pour but d'être utilisé pour diffuser
|
||||||
des séminaires ou évènements.
|
des séminaires ou évènements.
|
||||||
@ -21,7 +21,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<b>Serveur :</b>
|
<b>Serveur :</b>
|
||||||
<code>rtmps://{{.Cfg.Site.Hostname}}:1935/stream</code>,
|
<code>rtmps://{{.Cfg.Hostname}}:1935/stream</code>,
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>Clé de stream :</b>
|
<b>Clé de stream :</b>
|
||||||
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
Votre stream sera alors disponible sur
|
Votre stream sera alors disponible sur
|
||||||
<code>https://{{.Cfg.Site.Hostname}}/IDENTIFIANT</code>.
|
<code>https://{{.Cfg.Hostname}}/IDENTIFIANT</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3>Avec FFmpeg</h3>
|
<h3>Avec FFmpeg</h3>
|
||||||
@ -49,7 +49,7 @@
|
|||||||
<code>
|
<code>
|
||||||
ffmpeg -re -i mavideo.webm -vcodec libx264 -vprofile baseline
|
ffmpeg -re -i mavideo.webm -vcodec libx264 -vprofile baseline
|
||||||
-acodec aac -strict -2 -f flv
|
-acodec aac -strict -2 -f flv
|
||||||
rtmps://{{.Cfg.Site.Hostname}}:1935/stream/IDENTIFIANT?pass=MOT_DE_PASSE
|
rtmps://{{.Cfg.Hostname}}:1935/stream/IDENTIFIANT?pass=MOT_DE_PASSE
|
||||||
</code>
|
</code>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<path fill-rule="evenodd" d="M1.5 13A1.5 1.5 0 0 0 3 14.5h8a1.5 1.5 0 0 0 1.5-1.5V9a.5.5 0 0 0-1 0v4a.5.5 0 0 1-.5.5H3a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 0 0-1H3A1.5 1.5 0 0 0 1.5 5v8zm7-11a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 .5.5v5a.5.5 0 0 1-1 0V2.5H9a.5.5 0 0 1-.5-.5z"/>
|
<path fill-rule="evenodd" d="M1.5 13A1.5 1.5 0 0 0 3 14.5h8a1.5 1.5 0 0 0 1.5-1.5V9a.5.5 0 0 0-1 0v4a.5.5 0 0 1-.5.5H3a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 0 0-1H3A1.5 1.5 0 0 0 1.5 5v8zm7-11a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 .5.5v5a.5.5 0 0 1-1 0V2.5H9a.5.5 0 0 1-.5-.5z"/>
|
||||||
<path fill-rule="evenodd" d="M14.354 1.646a.5.5 0 0 1 0 .708l-8 8a.5.5 0 0 1-.708-.708l8-8a.5.5 0 0 1 .708 0z"/>
|
<path fill-rule="evenodd" d="M14.354 1.646a.5.5 0 0 1 0 .708l-8 8a.5.5 0 0 1-.708-.708l8-8a.5.5 0 0 1 .708 0z"/>
|
||||||
</svg>
|
</svg>
|
||||||
<code>rtmps://{{.Cfg.Site.Hostname}}:1935/play/{{.Path}}</code>
|
<code>rtmps://{{.Cfg.Hostname}}:1935/play/{{.Path}}</code>
|
||||||
<a href="#" id="chatToggle" title="Cacher/Afficher le chat">»</a>
|
<a href="#" id="chatToggle" title="Cacher/Afficher le chat">»</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -43,7 +43,7 @@ player = OvenPlayer.create("player", {
|
|||||||
expandFullScreenUI: true,
|
expandFullScreenUI: true,
|
||||||
sources: [
|
sources: [
|
||||||
{
|
{
|
||||||
"file": "wss://{{.Cfg.Site.Hostname}}/play/{{.Path}}",
|
"file": "wss://{{.Cfg.Hostname}}/play/{{.Path}}",
|
||||||
"type": "webrtc",
|
"type": "webrtc",
|
||||||
"label": "WebRTC Source"
|
"label": "WebRTC Source"
|
||||||
}
|
}
|
||||||
|
26
web/web.go
26
web/web.go
@ -6,19 +6,27 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"gitlab.crans.org/nounous/ghostream/internal/config"
|
|
||||||
"gitlab.crans.org/nounous/ghostream/internal/monitoring"
|
"gitlab.crans.org/nounous/ghostream/internal/monitoring"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Options holds web package configuration
|
||||||
|
type Options struct {
|
||||||
|
ListenAddress string
|
||||||
|
Name string
|
||||||
|
Hostname string
|
||||||
|
Favicon string
|
||||||
|
WidgetURL string
|
||||||
|
}
|
||||||
|
|
||||||
// Preload templates
|
// Preload templates
|
||||||
var templates = template.Must(template.ParseGlob("web/template/*.tmpl"))
|
var templates = template.Must(template.ParseGlob("web/template/*.tmpl"))
|
||||||
|
|
||||||
// Handle site index and viewer pages
|
// Handle site index and viewer pages
|
||||||
func viewerHandler(w http.ResponseWriter, r *http.Request, cfg *config.Config) {
|
func viewerHandler(w http.ResponseWriter, r *http.Request, cfg *Options) {
|
||||||
// Data for template
|
// Data for template
|
||||||
data := struct {
|
data := struct {
|
||||||
Path string
|
Path string
|
||||||
Cfg *config.Config
|
Cfg *Options
|
||||||
}{Path: r.URL.Path[1:], Cfg: cfg}
|
}{Path: r.URL.Path[1:], Cfg: cfg}
|
||||||
|
|
||||||
// FIXME validation on path: https://golang.org/doc/articles/wiki/#tmp_11
|
// FIXME validation on path: https://golang.org/doc/articles/wiki/#tmp_11
|
||||||
@ -35,7 +43,7 @@ func viewerHandler(w http.ResponseWriter, r *http.Request, cfg *config.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Auth incoming stream
|
// Auth incoming stream
|
||||||
func streamAuthHandler(w http.ResponseWriter, r *http.Request, cfg *config.Config) {
|
func streamAuthHandler(w http.ResponseWriter, r *http.Request, cfg *Options) {
|
||||||
// FIXME POST request only with "name" and "pass"
|
// FIXME POST request only with "name" and "pass"
|
||||||
// if name or pass missing => 400 Malformed request
|
// if name or pass missing => 400 Malformed request
|
||||||
// else login in against LDAP or static users
|
// else login in against LDAP or static users
|
||||||
@ -44,7 +52,7 @@ func streamAuthHandler(w http.ResponseWriter, r *http.Request, cfg *config.Confi
|
|||||||
|
|
||||||
// Handle static files
|
// Handle static files
|
||||||
// We do not use http.FileServer as we do not want directory listing
|
// We do not use http.FileServer as we do not want directory listing
|
||||||
func staticHandler(w http.ResponseWriter, r *http.Request, cfg *config.Config) {
|
func staticHandler(w http.ResponseWriter, r *http.Request, cfg *Options) {
|
||||||
path := "./web/" + r.URL.Path
|
path := "./web/" + r.URL.Path
|
||||||
if f, err := os.Stat(path); err == nil && !f.IsDir() {
|
if f, err := os.Stat(path); err == nil && !f.IsDir() {
|
||||||
http.ServeFile(w, r, path)
|
http.ServeFile(w, r, path)
|
||||||
@ -54,19 +62,19 @@ func staticHandler(w http.ResponseWriter, r *http.Request, cfg *config.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Closure to pass configuration
|
// Closure to pass configuration
|
||||||
func makeHandler(fn func(http.ResponseWriter, *http.Request, *config.Config), cfg *config.Config) http.HandlerFunc {
|
func makeHandler(fn func(http.ResponseWriter, *http.Request, *Options), cfg *Options) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
fn(w, r, cfg)
|
fn(w, r, cfg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeHTTP server
|
// ServeHTTP server
|
||||||
func ServeHTTP(cfg *config.Config) {
|
func ServeHTTP(cfg *Options) {
|
||||||
// Set up HTTP router and server
|
// Set up HTTP router and server
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.HandleFunc("/", makeHandler(viewerHandler, cfg))
|
mux.HandleFunc("/", makeHandler(viewerHandler, cfg))
|
||||||
mux.HandleFunc("/rtmp/auth", makeHandler(streamAuthHandler, cfg))
|
mux.HandleFunc("/rtmp/auth", makeHandler(streamAuthHandler, cfg))
|
||||||
mux.HandleFunc("/static/", makeHandler(staticHandler, cfg))
|
mux.HandleFunc("/static/", makeHandler(staticHandler, cfg))
|
||||||
log.Printf("Listening on http://%s/", cfg.Site.ListenAddress)
|
log.Printf("HTTP server listening on %s", cfg.ListenAddress)
|
||||||
log.Fatal(http.ListenAndServe(cfg.Site.ListenAddress, mux))
|
log.Fatal(http.ListenAndServe(cfg.ListenAddress, mux))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user