mirror of
https://github.com/speatzle/nfsense.git
synced 2025-09-13 07:19:07 +00:00
restructure project
This commit is contained in:
parent
dd2db438f3
commit
2ca35d4461
46 changed files with 158 additions and 84 deletions
36
internal/server/api.go
Normal file
36
internal/server/api.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"runtime/debug"
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/slog"
|
||||
"nfsense.net/nfsense/internal/session"
|
||||
)
|
||||
|
||||
func HandleAPI(w http.ResponseWriter, r *http.Request) {
|
||||
slog.Info("Api Handler hit")
|
||||
_, s := session.GetSession(r)
|
||||
if s == nil {
|
||||
// Fallthrough after so that jsonrpc can still deliver a valid jsonrpc error
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
slog.Error("Recovered Panic Handling HTTP API Request", fmt.Errorf("%v", r), "stack", debug.Stack())
|
||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}()
|
||||
ctx, cancel := context.WithTimeout(context.WithValue(r.Context(), session.SessionKey, s), time.Second*10)
|
||||
defer cancel()
|
||||
|
||||
err := apiHandler.HandleRequest(ctx, s, r.Body, w)
|
||||
if err != nil {
|
||||
slog.Error("Handling HTTP API Request", err)
|
||||
}
|
||||
}
|
53
internal/server/server.go
Normal file
53
internal/server/server.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/exp/slog"
|
||||
|
||||
"nfsense.net/nfsense/internal/definitions"
|
||||
"nfsense.net/nfsense/internal/jsonrpc"
|
||||
"nfsense.net/nfsense/internal/session"
|
||||
)
|
||||
|
||||
var server http.Server
|
||||
var mux = http.NewServeMux()
|
||||
var apiHandler *jsonrpc.Handler
|
||||
var stopCleanup chan struct{}
|
||||
|
||||
func StartWebserver(conf *definitions.Config, _apiHandler *jsonrpc.Handler) {
|
||||
server.Addr = ":8080"
|
||||
server.Handler = mux
|
||||
apiHandler = _apiHandler
|
||||
|
||||
// Routing
|
||||
mux.HandleFunc("/login", HandleLogin)
|
||||
mux.HandleFunc("/logout", HandleLogout)
|
||||
mux.HandleFunc("/session", HandleSession)
|
||||
mux.HandleFunc("/api", HandleAPI)
|
||||
mux.HandleFunc("/ws/api", HandleWebsocketAPI)
|
||||
mux.HandleFunc("/", HandleWebinterface)
|
||||
|
||||
stopCleanup = make(chan struct{})
|
||||
|
||||
go session.CleanupSessions(stopCleanup)
|
||||
|
||||
go func() {
|
||||
if err := server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
|
||||
slog.Error("Webserver error", err)
|
||||
}
|
||||
slog.Info("Webserver Stopped")
|
||||
}()
|
||||
}
|
||||
|
||||
func ShutdownWebserver(ctx context.Context) error {
|
||||
stopCleanup <- struct{}{}
|
||||
err := server.Shutdown(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Shutting down: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
63
internal/server/session.go
Normal file
63
internal/server/session.go
Normal file
|
@ -0,0 +1,63 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/slog"
|
||||
"nfsense.net/nfsense/internal/session"
|
||||
)
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
func HandleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
buf, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
slog.Error("Reading Body", err)
|
||||
return
|
||||
}
|
||||
var req LoginRequest
|
||||
err = json.Unmarshal(buf, &req)
|
||||
if err != nil {
|
||||
slog.Error("Unmarshal", err)
|
||||
return
|
||||
}
|
||||
if req.Username == "admin" && req.Password == "12345" {
|
||||
slog.Info("User Login Successfull")
|
||||
session.GenerateSession(w, req.Username)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
}
|
||||
|
||||
func HandleLogout(w http.ResponseWriter, r *http.Request) {
|
||||
http.SetCookie(w, session.GetCookie("", time.Now()))
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func HandleSession(w http.ResponseWriter, r *http.Request) {
|
||||
id, s := session.GetSession(r)
|
||||
if s == nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
session.ExtendSession(s)
|
||||
http.SetCookie(w, session.GetCookie(id, s.Expires))
|
||||
w.WriteHeader(http.StatusOK)
|
||||
resp := session.SessionResponse{
|
||||
CommitHash: session.CommitHash,
|
||||
}
|
||||
res, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(res)
|
||||
}
|
9
internal/server/webinterface.go
Normal file
9
internal/server/webinterface.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func HandleWebinterface(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
}
|
61
internal/server/websocket.go
Normal file
61
internal/server/websocket.go
Normal file
|
@ -0,0 +1,61 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"runtime/debug"
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/slog"
|
||||
"nfsense.net/nfsense/internal/session"
|
||||
"nhooyr.io/websocket"
|
||||
)
|
||||
|
||||
func HandleWebsocketAPI(w http.ResponseWriter, r *http.Request) {
|
||||
_, s := session.GetSession(r)
|
||||
if s == nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.WithValue(r.Context(), session.SessionKey, s))
|
||||
defer cancel()
|
||||
c, err := websocket.Accept(w, r, nil)
|
||||
if err != nil {
|
||||
slog.Error("Accepting Websocket Connection", err)
|
||||
return
|
||||
}
|
||||
defer c.Close(websocket.StatusInternalError, "Unexpected Closing")
|
||||
|
||||
slog.Info("Accepted API Websocket Connection")
|
||||
|
||||
for {
|
||||
_, m, err := c.Read(ctx)
|
||||
if websocket.CloseStatus(err) == websocket.StatusNormalClosure {
|
||||
slog.Info("API Websocket Closed Normally")
|
||||
cancel()
|
||||
return
|
||||
} else if err != nil {
|
||||
slog.Error("API Websocket Closed Unexpectedly", err)
|
||||
cancel()
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
slog.Error("Recovered Panic Handling Websocket API Request", fmt.Errorf("%v", r), "stack", debug.Stack())
|
||||
return
|
||||
}
|
||||
}()
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
|
||||
defer cancel()
|
||||
|
||||
err := apiHandler.HandleRequest(ctx, s, bytes.NewReader(m), w)
|
||||
if err != nil {
|
||||
slog.Error("Handling Websocket API Request", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue