Skip to content

Commit

Permalink
proxy: implement User data passover for graceful restarts
Browse files Browse the repository at this point in the history
util: added RedirectBack that tries to read the URL the request originated
from and modifies the request to go back there again. For use in website redirects

graceful: added ReadJSONConn that converts the fd passed to a net.Conn directly
  • Loading branch information
Wessie committed Mar 25, 2024
1 parent 9381f37 commit f0c5f2d
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 30 deletions.
9 changes: 2 additions & 7 deletions proxy/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,26 +181,21 @@ func (m *Mount) readSelf(ctx context.Context, cfg config.Config, src *net.UnixCo

zerolog.Ctx(ctx).Debug().Msg("resume: reading mount")

file, err := graceful.ReadJSONFile(src, &wm)
conn, err := graceful.ReadJSONConn(src, &wm)
if err != nil {
return err
}
defer file.Close()

zerolog.Ctx(ctx).Debug().Any("wireMount", wm).Msg("resume")

conn, err := net.FileConn(file)
if err != nil {
return err
}

newmount := NewMount(ctx, cfg, m.pm, wm.Name, wm.ContentType, conn)
*m = *newmount

if wm.SourceCount == 0 {
// this indicates the mount was probably in cleanup state and was gonna
// close connections soon, we do the same
m.pm.RemoveMount(newmount)
return nil
}

for i := 0; i < wm.SourceCount; i++ {
Expand Down
22 changes: 13 additions & 9 deletions proxy/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
radio "github.com/R-a-dio/valkyrie"
"github.com/R-a-dio/valkyrie/config"
"github.com/R-a-dio/valkyrie/proxy/compat"
"github.com/R-a-dio/valkyrie/storage"
"github.com/R-a-dio/valkyrie/util/graceful"
"github.com/R-a-dio/valkyrie/website/middleware"
"github.com/rs/xid"
Expand Down Expand Up @@ -164,7 +165,7 @@ type wireSource struct {
UserAgent string
ContentType string
MountName string
UserID radio.UserID
Username string
Identifier Identifier
Metadata *Metadata
}
Expand All @@ -175,7 +176,7 @@ func (sc *SourceClient) writeSelf(dst *net.UnixConn) error {
UserAgent: sc.UserAgent,
ContentType: sc.ContentType,
MountName: sc.MountName,
UserID: sc.User.ID,
Username: sc.User.Username,
Identifier: sc.Identifier,
Metadata: sc.Metadata.Load(),
}
Expand All @@ -198,30 +199,33 @@ func (sc *SourceClient) readSelf(ctx context.Context, cfg config.Config, src *ne
var ws wireSource

zerolog.Ctx(ctx).Info().Msg("resume: reading source client")
file, err := graceful.ReadJSONFile(src, &ws)
conn, err := graceful.ReadJSONConn(src, &ws)
if err != nil {
return err
}
defer file.Close()

zerolog.Ctx(ctx).Info().Any("ws", ws).Msg("resume")

conn, err := net.FileConn(file)
// we only get the username over the wire, so we need to grab the real user struct
// from storage
ss, err := storage.Open(ctx, cfg)
if err != nil {
return err
}

// TODO: implement this
var user radio.User
_ = user
user, err := ss.User(ctx).Get(ws.Username)
if err != nil {
return err
}

// construct the source client with the passed data
new := NewSourceClient(
ws.ID,
ws.UserAgent,
ws.ContentType,
ws.MountName,
conn,
user,
*user,
ws.Identifier,
ws.Metadata,
)
Expand Down
13 changes: 2 additions & 11 deletions templates/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package templates
import (
"context"
"net/http"
"net/url"
"strings"
"time"

Expand Down Expand Up @@ -81,20 +80,12 @@ func SetThemeHandler(cookieName string, resolve func(string) string) http.Handle
HttpOnly: true,
})

current, err := url.Parse(r.Header.Get("Hx-Current-Url"))
if err != nil {
r.URL = current
} else {
current, err = url.Parse(r.Header.Get("Referer"))
if err == nil {
r.URL = current
}
}
r = util.RedirectBack(r)

if !util.IsHTMX(r) {
// not a htmx request so probably no-js, send a http redirect to refresh
// the page instead with the new cookie set
http.Redirect(w, r, current.String(), http.StatusFound)
http.Redirect(w, r, r.URL.String(), http.StatusFound)
w.WriteHeader(http.StatusOK)
return
}
Expand Down
15 changes: 15 additions & 0 deletions util/graceful/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@ func ReadJSONFile(src *net.UnixConn, msg any) (*os.File, error) {
return handle, json.Unmarshal(buf[:n], msg)
}

func ReadJSONConn(src *net.UnixConn, msg any) (net.Conn, error) {
file, err := ReadJSONFile(src, msg)
if err != nil {
return nil, err
}
defer file.Close()

conn, err := net.FileConn(file)
if err != nil {
return nil, err
}

return conn, nil
}

func ReadJSON(src *net.UnixConn, msg any) error {
buf := make([]byte, 32*1024)
tiny := make([]byte, 512)
Expand Down
14 changes: 14 additions & 0 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package util
import (
"context"
"net/http"
"net/url"
"sync/atomic"
"time"

Expand All @@ -15,6 +16,19 @@ func IsHTMX(r *http.Request) bool {
return r.Header.Get("Hx-Request") == "true"
}

func RedirectBack(r *http.Request) *http.Request {
current, err := url.Parse(r.Header.Get("Hx-Current-Url"))
if err != nil {
r.URL = current
} else {
current, err = url.Parse(r.Header.Get("Referer"))
if err == nil {
r.URL = current
}
}
return r
}

type StreamFn[T any] func(context.Context) (eventstream.Stream[T], error)

type StreamCallbackFn[T any] func(context.Context, T)
Expand Down
14 changes: 11 additions & 3 deletions website/admin/songs.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,20 @@ func (s *State) PostSongs(w http.ResponseWriter, r *http.Request) {
return
}

if form == nil && util.IsHTMX(r) {
// delete operation that succeeded and htmx, return nothing
if util.IsHTMX(r) {
if form == nil {
return
}
err = s.TemplateExecutor.Execute(w, r, form)
if err != nil {
hlog.FromRequest(r).Error().Err(err).Msg("template failure")
return
}
return
}

// otherwise just return the new listing
// otherwise just return to the existing listing
r = util.RedirectBack(r)
s.GetSongs(w, r)
}

Expand Down

0 comments on commit f0c5f2d

Please sign in to comment.