Skip to content

Commit 364ee0e

Browse files
committed
feat: add a reverse proxy to plex.tv
1 parent 3e4c500 commit 364ee0e

File tree

4 files changed

+40
-6
lines changed

4 files changed

+40
-6
lines changed

handler/const.go

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
)
66

77
const (
8+
domainPlexTv = "plex.tv"
9+
810
headerPlexPrefix = "X-Plex-"
911
headerCacheStatus = "X-Plex-Cache-Status"
1012
headerClientIdentity = "X-Plex-Client-Identifier"

handler/main.go

+23-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ package handler
33
import (
44
"log"
55
"net/http"
6+
"net/http/httputil"
7+
"net/url"
68
"os"
9+
"strings"
710

811
"github.com/go-chi/chi/v5/middleware"
912
"github.com/go-redis/redis/v8"
@@ -21,6 +24,7 @@ var (
2124
func init() {
2225
plexClient = NewPlexClient(PlexConfig{
2326
BaseUrl: os.Getenv("PLEX_BASEURL"),
27+
SslHost: os.Getenv("PLEX_SSL_HOST"),
2428
Token: os.Getenv("PLEX_TOKEN"),
2529
PlaxtUrl: os.Getenv("PLAXT_URL"),
2630
RedirectWebApp: os.Getenv("REDIRECT_WEB_APP"),
@@ -46,14 +50,27 @@ func NewRouter() http.Handler {
4650
if !plexClient.NoRequestLogs {
4751
r.Use(middleware.Logger)
4852
}
49-
r.Use(wrapMiddleware, middleware.Recoverer, trafficMiddleware)
5053

54+
plexTvUrl, _ := url.Parse("https://www." + domainPlexTv)
55+
plexTvProxy := httputil.NewSingleHostReverseProxy(plexTvUrl)
56+
plexTvRouter := r.Host(domainPlexTv).Subrouter()
57+
sslRouter := plexTvRouter.MatcherFunc(func(r *http.Request, match *mux.RouteMatch) bool {
58+
return strings.Index(r.URL.Path, "servers.xml") != -1
59+
}).Subrouter()
60+
sslRouter.Use(sslMiddleware)
61+
sslRouter.PathPrefix("/").Handler(plexTvProxy)
62+
plexTvRouter.PathPrefix("/").Handler(plexTvProxy)
63+
64+
pmsRouter := r.MatcherFunc(func(r *http.Request, match *mux.RouteMatch) bool {
65+
return r.Host != domainPlexTv
66+
}).Subrouter()
67+
pmsRouter.Use(wrapMiddleware, middleware.Recoverer, trafficMiddleware)
5168
if redisClient != nil {
5269
// bypass cache
53-
r.PathPrefix("/:/").Handler(plexClient)
54-
r.PathPrefix("/library/parts/").Handler(plexClient)
70+
pmsRouter.PathPrefix("/:/").Handler(plexClient)
71+
pmsRouter.PathPrefix("/library/parts/").Handler(plexClient)
5572

56-
staticRouter := r.Methods(http.MethodGet).Subrouter()
73+
staticRouter := pmsRouter.Methods(http.MethodGet).Subrouter()
5774
staticRouter.Use(staticMiddleware)
5875
staticRouter.Path("/library/media/{key}/chapterImages/{id}").Handler(plexClient)
5976
staticRouter.Path("/library/metadata/{key}/art/{id}").Handler(plexClient)
@@ -62,11 +79,11 @@ func NewRouter() http.Handler {
6279
staticRouter.PathPrefix("/web/js/").Handler(plexClient)
6380
staticRouter.PathPrefix("/web/static/").Handler(plexClient)
6481

65-
dynamicRouter := r.Methods(http.MethodGet).Subrouter()
82+
dynamicRouter := pmsRouter.Methods(http.MethodGet).Subrouter()
6683
dynamicRouter.Use(dynamicMiddleware)
6784
dynamicRouter.PathPrefix("/").Handler(plexClient)
6885
}
86+
pmsRouter.PathPrefix("/").Handler(plexClient)
6987

70-
r.PathPrefix("/").Handler(plexClient)
7188
return r
7289
}

handler/middleware.go

+12
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ var (
2323
userCtxKey = &ctxKeyType{"user"}
2424
)
2525

26+
func sslMiddleware(next http.Handler) http.Handler {
27+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
28+
if plexClient.sslHost != "" && r.Body != nil {
29+
bodyBytes, _ := io.ReadAll(r.Body)
30+
sslHost := fmt.Sprintf("address=\"%s\" scheme=\"https\"", plexClient.sslHost)
31+
modifiedBody := strings.ReplaceAll(string(bodyBytes), "host=\"\"", sslHost)
32+
r.Body = io.NopCloser(strings.NewReader(modifiedBody))
33+
}
34+
next.ServeHTTP(w, r)
35+
})
36+
}
37+
2638
func normalizeMiddleware(next http.Handler) http.Handler {
2739
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2840
headers := http.Header{}

handler/plex.go

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
type PlexConfig struct {
2323
BaseUrl string
24+
SslHost string
2425
Token string
2526
PlaxtUrl string
2627
RedirectWebApp string
@@ -32,6 +33,7 @@ type PlexClient struct {
3233
proxy *httputil.ReverseProxy
3334
client *plex.Plex
3435

36+
sslHost string
3537
plaxtUrl string
3638
redirectWebApp bool
3739
disableTranscode bool
@@ -92,6 +94,7 @@ func NewPlexClient(config PlexConfig) *PlexClient {
9294
return &PlexClient{
9395
proxy: proxy,
9496
client: client,
97+
sslHost: config.SslHost,
9598
plaxtUrl: plaxtUrl,
9699
redirectWebApp: redirectWebApp,
97100
disableTranscode: disableTranscode,

0 commit comments

Comments
 (0)