allow reverse proxies to change the schema of URLs returned by the server through the X-Forwarded-Proto header.
This commit is contained in:
+2
-2
@@ -2623,7 +2623,7 @@ paths:
|
||||
get:
|
||||
operationId: recordingsList
|
||||
tags: [Recordings]
|
||||
summary: returns all recordings.
|
||||
summary: returns all recordings, splitted by path.
|
||||
description: ''
|
||||
parameters:
|
||||
- name: page
|
||||
@@ -2662,7 +2662,7 @@ paths:
|
||||
get:
|
||||
operationId: recordingsGet
|
||||
tags: [Recordings]
|
||||
summary: returns recordings for a path.
|
||||
summary: returns recordings of a path.
|
||||
description: ''
|
||||
parameters:
|
||||
- name: name
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -83,6 +84,21 @@ func parseSegments(segments []*recordstore.Segment) ([]*parsedSegment, error) {
|
||||
return parsed, err
|
||||
}
|
||||
|
||||
func urlScheme(ctx *gin.Context, trustedProxies conf.IPNetworks, encryption bool) string {
|
||||
if trustedProxies.Contains(net.ParseIP(ctx.RemoteIP())) {
|
||||
xForwardedProto := ctx.Request.Header.Get("X-Forwarded-Proto")
|
||||
if xForwardedProto != "" {
|
||||
return xForwardedProto
|
||||
}
|
||||
}
|
||||
|
||||
if encryption {
|
||||
return "https"
|
||||
}
|
||||
|
||||
return "http"
|
||||
}
|
||||
|
||||
type listEntry struct {
|
||||
Start time.Time `json:"start"`
|
||||
Duration listEntryDuration `json:"duration"`
|
||||
@@ -212,12 +228,7 @@ func (s *Server) onList(ctx *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
var scheme string
|
||||
if s.Encryption {
|
||||
scheme = "https"
|
||||
} else {
|
||||
scheme = "http"
|
||||
}
|
||||
scheme := urlScheme(ctx, s.TrustedProxies, s.Encryption)
|
||||
|
||||
for i := range entries {
|
||||
v := url.Values{}
|
||||
|
||||
@@ -336,3 +336,68 @@ func TestOnListCachedDuration(t *testing.T) {
|
||||
},
|
||||
}, out)
|
||||
}
|
||||
|
||||
func TestOnListXForwardedProto(t *testing.T) {
|
||||
dir, err := os.MkdirTemp("", "mediamtx-playback")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
err = os.Mkdir(filepath.Join(dir, "mypath"), 0o755)
|
||||
require.NoError(t, err)
|
||||
|
||||
writeSegment1(t, filepath.Join(dir, "mypath", "2008-11-07_11-22-00-500000.mp4"))
|
||||
|
||||
var trustedProxies conf.IPNetworks
|
||||
err = json.Unmarshal([]byte(`["127.0.0.0/8"]`), &trustedProxies)
|
||||
require.NoError(t, err)
|
||||
|
||||
s := &Server{
|
||||
Address: "127.0.0.1:9996",
|
||||
ReadTimeout: conf.Duration(10 * time.Second),
|
||||
WriteTimeout: conf.Duration(10 * time.Second),
|
||||
TrustedProxies: trustedProxies,
|
||||
PathConfs: map[string]*conf.Path{
|
||||
"mypath": {
|
||||
Name: "mypath",
|
||||
RecordPath: filepath.Join(dir, "%path/%Y-%m-%d_%H-%M-%S-%f"),
|
||||
RecordFormat: conf.RecordFormatFMP4,
|
||||
},
|
||||
},
|
||||
AuthManager: test.NilAuthManager,
|
||||
Parent: test.NilLogger,
|
||||
}
|
||||
err = s.Initialize()
|
||||
require.NoError(t, err)
|
||||
defer s.Close()
|
||||
|
||||
u, err := url.Parse("http://localhost:9996/list")
|
||||
require.NoError(t, err)
|
||||
|
||||
v := url.Values{}
|
||||
v.Set("path", "mypath")
|
||||
u.RawQuery = v.Encode()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
req.Header.Set("X-Forwarded-Proto", "https")
|
||||
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
defer res.Body.Close()
|
||||
|
||||
require.Equal(t, http.StatusOK, res.StatusCode)
|
||||
|
||||
var out any
|
||||
err = json.NewDecoder(res.Body).Decode(&out)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, []any{
|
||||
map[string]any{
|
||||
"duration": float64(62),
|
||||
"start": time.Date(2008, 11, 7, 11, 22, 0, 500000000, time.Local).Format(time.RFC3339Nano),
|
||||
"url": "https://localhost:9996/get?duration=62&path=mypath&start=" +
|
||||
url.QueryEscape(time.Date(2008, 11, 7, 11, 22, 0, 500000000, time.Local).Format(time.RFC3339Nano)),
|
||||
},
|
||||
}, out)
|
||||
}
|
||||
|
||||
+8
-8
@@ -171,8 +171,8 @@ apiServerCert: server.crt
|
||||
# Supports wildcards: ['http://*.example.com']
|
||||
apiAllowOrigins: ['*']
|
||||
# IPs or CIDRs of proxies placed before the HTTP server.
|
||||
# If the server receives a request from one of these entries, IP in logs
|
||||
# will be taken from the X-Forwarded-For header.
|
||||
# These proxies can use the X-Forwarded-For header to set the real IP of clients,
|
||||
# and the X-Forwarded-Proto header to set the original protocol.
|
||||
apiTrustedProxies: []
|
||||
|
||||
###############################################
|
||||
@@ -195,8 +195,8 @@ metricsServerCert: server.crt
|
||||
# Supports wildcards: ['http://*.example.com']
|
||||
metricsAllowOrigins: ['*']
|
||||
# IPs or CIDRs of proxies placed before the HTTP server.
|
||||
# If the server receives a request from one of these entries, IP in logs
|
||||
# will be taken from the X-Forwarded-For header.
|
||||
# These proxies can use the X-Forwarded-For header to set the real IP of clients,
|
||||
# and the X-Forwarded-Proto header to set the original protocol.
|
||||
metricsTrustedProxies: []
|
||||
|
||||
###############################################
|
||||
@@ -219,8 +219,8 @@ pprofServerCert: server.crt
|
||||
# Supports wildcards: ['http://*.example.com']
|
||||
pprofAllowOrigins: ['*']
|
||||
# IPs or CIDRs of proxies placed before the HTTP server.
|
||||
# If the server receives a request from one of these entries, IP in logs
|
||||
# will be taken from the X-Forwarded-For header.
|
||||
# These proxies can use the X-Forwarded-For header to set the real IP of clients,
|
||||
# and the X-Forwarded-Proto header to set the original protocol.
|
||||
pprofTrustedProxies: []
|
||||
|
||||
###############################################
|
||||
@@ -243,8 +243,8 @@ playbackServerCert: server.crt
|
||||
# Supports wildcards: ['http://*.example.com']
|
||||
playbackAllowOrigins: ['*']
|
||||
# IPs or CIDRs of proxies placed before the HTTP server.
|
||||
# If the server receives a request from one of these entries, IP in logs
|
||||
# will be taken from the X-Forwarded-For header.
|
||||
# These proxies can use the X-Forwarded-For header to set the real IP of clients,
|
||||
# and the X-Forwarded-Proto header to set the original protocol.
|
||||
playbackTrustedProxies: []
|
||||
|
||||
###############################################
|
||||
|
||||
Reference in New Issue
Block a user