Add streams database and password auth
parent
a6f6e1f01d
commit
ad5f6b8db5
|
@ -1 +1,2 @@
|
||||||
HTTP_ADDRESS=127.0.0.1:3001
|
HTTP_ADDRESS=127.0.0.1:3001
|
||||||
|
DATABASE_URL=./streams.db
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
/streams.db
|
|
@ -0,0 +1,4 @@
|
||||||
|
CREATE TABLE streams (
|
||||||
|
stream TEXT NOT NULL,
|
||||||
|
password TEXT NOT NULL
|
||||||
|
) STRICT;
|
|
@ -9,6 +9,7 @@ require (
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.16 // indirect
|
||||||
github.com/pion/datachannel v1.5.5 // indirect
|
github.com/pion/datachannel v1.5.5 // indirect
|
||||||
github.com/pion/dtls/v2 v2.2.4 // indirect
|
github.com/pion/dtls/v2 v2.2.4 // indirect
|
||||||
github.com/pion/logging v0.2.2 // indirect
|
github.com/pion/logging v0.2.2 // indirect
|
||||||
|
|
|
@ -24,6 +24,8 @@ github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwA
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
|
|
@ -10,9 +10,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"database/sql"
|
||||||
|
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
"github.com/pion/interceptor"
|
"github.com/pion/interceptor"
|
||||||
"github.com/pion/webrtc/v3"
|
"github.com/pion/webrtc/v3"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WebRTCStream struct {
|
type WebRTCStream struct {
|
||||||
|
@ -23,6 +27,7 @@ var (
|
||||||
runningStreams map[string]WebRTCStream
|
runningStreams map[string]WebRTCStream
|
||||||
runningStreamsLock sync.Mutex
|
runningStreamsLock sync.Mutex
|
||||||
api *webrtc.API
|
api *webrtc.API
|
||||||
|
db *sql.DB
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -30,6 +35,32 @@ func main() {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db = setupDatabase()
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
api = setupWebRTC()
|
||||||
|
runningStreams = map[string]WebRTCStream{}
|
||||||
|
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc("/api/wish-server/whip", withCors(HandleWHIP))
|
||||||
|
mux.HandleFunc("/api/wish-server/whep", withCors(HandleWHEP))
|
||||||
|
|
||||||
|
log.Fatal((&http.Server{
|
||||||
|
Handler: mux,
|
||||||
|
Addr: os.Getenv("HTTP_ADDRESS"),
|
||||||
|
}).ListenAndServe())
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupDatabase() *sql.DB {
|
||||||
|
db, err := sql.Open("sqlite3", os.Getenv("DATABASE_URL"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupWebRTC() *webrtc.API {
|
||||||
mediaEngine := &webrtc.MediaEngine{}
|
mediaEngine := &webrtc.MediaEngine{}
|
||||||
if err := mediaEngine.RegisterDefaultCodecs(); err != nil {
|
if err := mediaEngine.RegisterDefaultCodecs(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -42,21 +73,11 @@ func main() {
|
||||||
|
|
||||||
settingEngine := webrtc.SettingEngine{}
|
settingEngine := webrtc.SettingEngine{}
|
||||||
|
|
||||||
api = webrtc.NewAPI(
|
return webrtc.NewAPI(
|
||||||
webrtc.WithMediaEngine(mediaEngine),
|
webrtc.WithMediaEngine(mediaEngine),
|
||||||
webrtc.WithInterceptorRegistry(interceptorRegistry),
|
webrtc.WithInterceptorRegistry(interceptorRegistry),
|
||||||
webrtc.WithSettingEngine(settingEngine),
|
webrtc.WithSettingEngine(settingEngine),
|
||||||
)
|
)
|
||||||
|
|
||||||
runningStreams = map[string]WebRTCStream{}
|
|
||||||
mux := http.NewServeMux()
|
|
||||||
mux.HandleFunc("/api/wish-server/whip", withCors(HandleWHIP))
|
|
||||||
mux.HandleFunc("/api/wish-server/whep", withCors(HandleWHEP))
|
|
||||||
|
|
||||||
log.Fatal((&http.Server{
|
|
||||||
Handler: mux,
|
|
||||||
Addr: os.Getenv("HTTP_ADDRESS"),
|
|
||||||
}).ListenAndServe())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func withCors(next func(w http.ResponseWriter, r *http.Request)) http.HandlerFunc {
|
func withCors(next func(w http.ResponseWriter, r *http.Request)) http.HandlerFunc {
|
||||||
|
@ -107,14 +128,17 @@ func getTracksForStream(streamName string) (
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleWHIP(res http.ResponseWriter, req *http.Request) {
|
func HandleWHIP(res http.ResponseWriter, req *http.Request) {
|
||||||
// TODO: SQLite3 to store stream keys (split auth by colon)
|
authorization := req.Header.Get("Authorization")
|
||||||
|
if authorization == "" {
|
||||||
streamName := req.Header.Get("Authorization")
|
logHTTPError(res, "Authorization was not set", http.StatusBadRequest)
|
||||||
if streamName == "" {
|
|
||||||
logHTTPError(res, "Stream name was not set", http.StatusBadRequest)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
streamName, streamPassword, _ := strings.Cut(authorization, ":")
|
||||||
|
if db.QueryRow("SELECT * FROM streams WHERE stream = ? AND password = ?", streamName, streamPassword).Err() != nil {
|
||||||
|
logHTTPError(res, "Invalid stream authorization", http.StatusUnauthorized)
|
||||||
|
}
|
||||||
|
|
||||||
offer, err := io.ReadAll(req.Body)
|
offer, err := io.ReadAll(req.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logHTTPError(res, err.Error(), http.StatusInternalServerError)
|
logHTTPError(res, err.Error(), http.StatusInternalServerError)
|
||||||
|
|
Loading…
Reference in New Issue