forked from External/mediamtx
This commit is contained in:
parent
a18bebfa58
commit
665e11a376
6 changed files with 62 additions and 111 deletions
|
|
@ -1,22 +0,0 @@
|
||||||
package httpp
|
|
||||||
|
|
||||||
import "net/url"
|
|
||||||
|
|
||||||
// LocationWithTrailingSlash returns the URL in a relative format, with a trailing slash.
|
|
||||||
func LocationWithTrailingSlash(u *url.URL) string {
|
|
||||||
l := "./"
|
|
||||||
|
|
||||||
for i := 1; i < len(u.Path); i++ {
|
|
||||||
if u.Path[i] == '/' {
|
|
||||||
l += "../"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
l += u.Path[1:] + "/"
|
|
||||||
|
|
||||||
if u.RawQuery != "" {
|
|
||||||
l += "?" + u.RawQuery
|
|
||||||
}
|
|
||||||
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
package httpp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/url"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestLocationWithTrailingSlash(t *testing.T) {
|
|
||||||
for _, ca := range []struct {
|
|
||||||
name string
|
|
||||||
url *url.URL
|
|
||||||
loc string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"with query",
|
|
||||||
&url.URL{
|
|
||||||
Path: "/test",
|
|
||||||
RawQuery: "key=value",
|
|
||||||
},
|
|
||||||
"./test/?key=value",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"xss",
|
|
||||||
&url.URL{
|
|
||||||
Path: "/www.example.com",
|
|
||||||
},
|
|
||||||
"./www.example.com/",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"slashes in path",
|
|
||||||
&url.URL{
|
|
||||||
Path: "/my/path",
|
|
||||||
},
|
|
||||||
"./../my/path/",
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
t.Run(ca.name, func(t *testing.T) {
|
|
||||||
require.Equal(t, ca.loc, LocationWithTrailingSlash(ca.url))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -31,7 +31,7 @@ func (c *WHIPClient) Publish(
|
||||||
videoTrack format.Format,
|
videoTrack format.Format,
|
||||||
audioTrack format.Format,
|
audioTrack format.Format,
|
||||||
) ([]*OutgoingTrack, error) {
|
) ([]*OutgoingTrack, error) {
|
||||||
iceServers, err := c.optionsICEServers(ctx, c.URL.String())
|
iceServers, err := c.optionsICEServers(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -67,7 +67,7 @@ func (c *WHIPClient) Publish(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.postOffer(ctx, c.URL.String(), offer)
|
res, err := c.postOffer(ctx, offer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.pc.Close()
|
c.pc.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -81,7 +81,7 @@ func (c *WHIPClient) Publish(
|
||||||
|
|
||||||
err = c.pc.SetAnswer(res.Answer)
|
err = c.pc.SetAnswer(res.Answer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.deleteSession(context.Background(), c.URL.String()) //nolint:errcheck
|
c.deleteSession(context.Background()) //nolint:errcheck
|
||||||
c.pc.Close()
|
c.pc.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -93,9 +93,9 @@ outer:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case ca := <-c.pc.NewLocalCandidate():
|
case ca := <-c.pc.NewLocalCandidate():
|
||||||
err := c.patchCandidate(ctx, c.URL.String(), offer, res.ETag, ca)
|
err := c.patchCandidate(ctx, offer, res.ETag, ca)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.deleteSession(context.Background(), c.URL.String()) //nolint:errcheck
|
c.deleteSession(context.Background()) //nolint:errcheck
|
||||||
c.pc.Close()
|
c.pc.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +106,7 @@ outer:
|
||||||
break outer
|
break outer
|
||||||
|
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
c.deleteSession(context.Background(), c.URL.String()) //nolint:errcheck
|
c.deleteSession(context.Background()) //nolint:errcheck
|
||||||
c.pc.Close()
|
c.pc.Close()
|
||||||
return nil, fmt.Errorf("deadline exceeded while waiting connection")
|
return nil, fmt.Errorf("deadline exceeded while waiting connection")
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +117,7 @@ outer:
|
||||||
|
|
||||||
// Read reads tracks.
|
// Read reads tracks.
|
||||||
func (c *WHIPClient) Read(ctx context.Context) ([]*IncomingTrack, error) {
|
func (c *WHIPClient) Read(ctx context.Context) ([]*IncomingTrack, error) {
|
||||||
iceServers, err := c.optionsICEServers(ctx, c.URL.String())
|
iceServers, err := c.optionsICEServers(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -147,7 +147,7 @@ func (c *WHIPClient) Read(ctx context.Context) ([]*IncomingTrack, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.postOffer(ctx, c.URL.String(), offer)
|
res, err := c.postOffer(ctx, offer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.pc.Close()
|
c.pc.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -162,7 +162,7 @@ func (c *WHIPClient) Read(ctx context.Context) ([]*IncomingTrack, error) {
|
||||||
var sdp sdp.SessionDescription
|
var sdp sdp.SessionDescription
|
||||||
err = sdp.Unmarshal([]byte(res.Answer.SDP))
|
err = sdp.Unmarshal([]byte(res.Answer.SDP))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.deleteSession(context.Background(), c.URL.String()) //nolint:errcheck
|
c.deleteSession(context.Background()) //nolint:errcheck
|
||||||
c.pc.Close()
|
c.pc.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -170,14 +170,14 @@ func (c *WHIPClient) Read(ctx context.Context) ([]*IncomingTrack, error) {
|
||||||
// check that there are at most two tracks
|
// check that there are at most two tracks
|
||||||
_, err = TrackCount(sdp.MediaDescriptions)
|
_, err = TrackCount(sdp.MediaDescriptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.deleteSession(context.Background(), c.URL.String()) //nolint:errcheck
|
c.deleteSession(context.Background()) //nolint:errcheck
|
||||||
c.pc.Close()
|
c.pc.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.pc.SetAnswer(res.Answer)
|
err = c.pc.SetAnswer(res.Answer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.deleteSession(context.Background(), c.URL.String()) //nolint:errcheck
|
c.deleteSession(context.Background()) //nolint:errcheck
|
||||||
c.pc.Close()
|
c.pc.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -189,9 +189,9 @@ outer:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case ca := <-c.pc.NewLocalCandidate():
|
case ca := <-c.pc.NewLocalCandidate():
|
||||||
err := c.patchCandidate(ctx, c.URL.String(), offer, res.ETag, ca)
|
err := c.patchCandidate(ctx, offer, res.ETag, ca)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.deleteSession(context.Background(), c.URL.String()) //nolint:errcheck
|
c.deleteSession(context.Background()) //nolint:errcheck
|
||||||
c.pc.Close()
|
c.pc.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +202,7 @@ outer:
|
||||||
break outer
|
break outer
|
||||||
|
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
c.deleteSession(context.Background(), c.URL.String()) //nolint:errcheck
|
c.deleteSession(context.Background()) //nolint:errcheck
|
||||||
c.pc.Close()
|
c.pc.Close()
|
||||||
return nil, fmt.Errorf("deadline exceeded while waiting connection")
|
return nil, fmt.Errorf("deadline exceeded while waiting connection")
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +210,7 @@ outer:
|
||||||
|
|
||||||
tracks, err := c.pc.GatherIncomingTracks(ctx, 0)
|
tracks, err := c.pc.GatherIncomingTracks(ctx, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.deleteSession(context.Background(), c.URL.String()) //nolint:errcheck
|
c.deleteSession(context.Background()) //nolint:errcheck
|
||||||
c.pc.Close()
|
c.pc.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -220,7 +220,7 @@ outer:
|
||||||
|
|
||||||
// Close closes the client.
|
// Close closes the client.
|
||||||
func (c *WHIPClient) Close() error {
|
func (c *WHIPClient) Close() error {
|
||||||
err := c.deleteSession(context.Background(), c.URL.String())
|
err := c.deleteSession(context.Background())
|
||||||
c.pc.Close()
|
c.pc.Close()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -238,9 +238,8 @@ func (c *WHIPClient) Wait(ctx context.Context) error {
|
||||||
|
|
||||||
func (c *WHIPClient) optionsICEServers(
|
func (c *WHIPClient) optionsICEServers(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
ur string,
|
|
||||||
) ([]webrtc.ICEServer, error) {
|
) ([]webrtc.ICEServer, error) {
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodOptions, ur, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodOptions, c.URL.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -266,10 +265,9 @@ type whipPostOfferResponse struct {
|
||||||
|
|
||||||
func (c *WHIPClient) postOffer(
|
func (c *WHIPClient) postOffer(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
ur string,
|
|
||||||
offer *webrtc.SessionDescription,
|
offer *webrtc.SessionDescription,
|
||||||
) (*whipPostOfferResponse, error) {
|
) (*whipPostOfferResponse, error) {
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, ur, bytes.NewReader([]byte(offer.SDP)))
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.URL.String(), bytes.NewReader([]byte(offer.SDP)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -322,7 +320,6 @@ func (c *WHIPClient) postOffer(
|
||||||
|
|
||||||
func (c *WHIPClient) patchCandidate(
|
func (c *WHIPClient) patchCandidate(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
ur string,
|
|
||||||
offer *webrtc.SessionDescription,
|
offer *webrtc.SessionDescription,
|
||||||
etag string,
|
etag string,
|
||||||
candidate *webrtc.ICECandidateInit,
|
candidate *webrtc.ICECandidateInit,
|
||||||
|
|
@ -332,7 +329,7 @@ func (c *WHIPClient) patchCandidate(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, ur, bytes.NewReader(frag))
|
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, c.URL.String(), bytes.NewReader(frag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -355,9 +352,8 @@ func (c *WHIPClient) patchCandidate(
|
||||||
|
|
||||||
func (c *WHIPClient) deleteSession(
|
func (c *WHIPClient) deleteSession(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
ur string,
|
|
||||||
) error {
|
) error {
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, ur, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, c.URL.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,14 @@ var hlsIndex []byte
|
||||||
//go:embed hls.min.js
|
//go:embed hls.min.js
|
||||||
var hlsMinJS []byte
|
var hlsMinJS []byte
|
||||||
|
|
||||||
|
func mergePathAndQuery(path string, rawQuery string) string {
|
||||||
|
res := path
|
||||||
|
if rawQuery != "" {
|
||||||
|
res += "?" + rawQuery
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
type httpServer struct {
|
type httpServer struct {
|
||||||
address string
|
address string
|
||||||
encryption bool
|
encryption bool
|
||||||
|
|
@ -134,7 +142,7 @@ func (s *httpServer) onRequest(ctx *gin.Context) {
|
||||||
dir, fname = pa, ""
|
dir, fname = pa, ""
|
||||||
|
|
||||||
if !strings.HasSuffix(dir, "/") {
|
if !strings.HasSuffix(dir, "/") {
|
||||||
ctx.Writer.Header().Set("Location", httpp.LocationWithTrailingSlash(ctx.Request.URL))
|
ctx.Writer.Header().Set("Location", mergePathAndQuery(ctx.Request.URL.Path+"/", ctx.Request.URL.RawQuery))
|
||||||
ctx.Writer.WriteHeader(http.StatusMovedPermanently)
|
ctx.Writer.WriteHeader(http.StatusMovedPermanently)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,14 +34,22 @@ var (
|
||||||
reWHIPWHEPWithID = regexp.MustCompile("^/(.+?)/(whip|whep)/(.+?)$")
|
reWHIPWHEPWithID = regexp.MustCompile("^/(.+?)/(whip|whep)/(.+?)$")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func mergePathAndQuery(path string, rawQuery string) string {
|
||||||
|
res := path
|
||||||
|
if rawQuery != "" {
|
||||||
|
res += "?" + rawQuery
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
func writeError(ctx *gin.Context, statusCode int, err error) {
|
func writeError(ctx *gin.Context, statusCode int, err error) {
|
||||||
ctx.JSON(statusCode, &defs.APIError{
|
ctx.JSON(statusCode, &defs.APIError{
|
||||||
Error: err.Error(),
|
Error: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func sessionLocation(publish bool, secret uuid.UUID) string {
|
func sessionLocation(publish bool, path string, secret uuid.UUID) string {
|
||||||
ret := ""
|
ret := "/" + path + "/"
|
||||||
if publish {
|
if publish {
|
||||||
ret += "whip"
|
ret += "whip"
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -107,12 +115,12 @@ func (s *httpServer) close() {
|
||||||
s.inner.Close()
|
s.inner.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *httpServer) checkAuthOutsideSession(ctx *gin.Context, path string, publish bool) bool {
|
func (s *httpServer) checkAuthOutsideSession(ctx *gin.Context, pathName string, publish bool) bool {
|
||||||
user, pass, hasCredentials := ctx.Request.BasicAuth()
|
user, pass, hasCredentials := ctx.Request.BasicAuth()
|
||||||
|
|
||||||
_, err := s.pathManager.FindPathConf(defs.PathFindPathConfReq{
|
_, err := s.pathManager.FindPathConf(defs.PathFindPathConfReq{
|
||||||
AccessRequest: defs.PathAccessRequest{
|
AccessRequest: defs.PathAccessRequest{
|
||||||
Name: path,
|
Name: pathName,
|
||||||
Query: ctx.Request.URL.RawQuery,
|
Query: ctx.Request.URL.RawQuery,
|
||||||
Publish: publish,
|
Publish: publish,
|
||||||
IP: net.ParseIP(ctx.ClientIP()),
|
IP: net.ParseIP(ctx.ClientIP()),
|
||||||
|
|
@ -146,8 +154,8 @@ func (s *httpServer) checkAuthOutsideSession(ctx *gin.Context, path string, publ
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *httpServer) onWHIPOptions(ctx *gin.Context, path string, publish bool) {
|
func (s *httpServer) onWHIPOptions(ctx *gin.Context, pathName string, publish bool) {
|
||||||
if !s.checkAuthOutsideSession(ctx, path, publish) {
|
if !s.checkAuthOutsideSession(ctx, pathName, publish) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,7 +172,7 @@ func (s *httpServer) onWHIPOptions(ctx *gin.Context, path string, publish bool)
|
||||||
ctx.Writer.WriteHeader(http.StatusNoContent)
|
ctx.Writer.WriteHeader(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *httpServer) onWHIPPost(ctx *gin.Context, path string, publish bool) {
|
func (s *httpServer) onWHIPPost(ctx *gin.Context, pathName string, publish bool) {
|
||||||
if ctx.Request.Header.Get("Content-Type") != "application/sdp" {
|
if ctx.Request.Header.Get("Content-Type") != "application/sdp" {
|
||||||
writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid Content-Type"))
|
writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid Content-Type"))
|
||||||
return
|
return
|
||||||
|
|
@ -178,7 +186,7 @@ func (s *httpServer) onWHIPPost(ctx *gin.Context, path string, publish bool) {
|
||||||
user, pass, _ := ctx.Request.BasicAuth()
|
user, pass, _ := ctx.Request.BasicAuth()
|
||||||
|
|
||||||
res := s.parent.newSession(webRTCNewSessionReq{
|
res := s.parent.newSession(webRTCNewSessionReq{
|
||||||
pathName: path,
|
pathName: pathName,
|
||||||
remoteAddr: httpp.RemoteAddr(ctx),
|
remoteAddr: httpp.RemoteAddr(ctx),
|
||||||
query: ctx.Request.URL.RawQuery,
|
query: ctx.Request.URL.RawQuery,
|
||||||
user: user,
|
user: user,
|
||||||
|
|
@ -203,12 +211,12 @@ func (s *httpServer) onWHIPPost(ctx *gin.Context, path string, publish bool) {
|
||||||
ctx.Writer.Header().Set("ID", res.sx.uuid.String())
|
ctx.Writer.Header().Set("ID", res.sx.uuid.String())
|
||||||
ctx.Writer.Header().Set("Accept-Patch", "application/trickle-ice-sdpfrag")
|
ctx.Writer.Header().Set("Accept-Patch", "application/trickle-ice-sdpfrag")
|
||||||
ctx.Writer.Header()["Link"] = webrtc.LinkHeaderMarshal(servers)
|
ctx.Writer.Header()["Link"] = webrtc.LinkHeaderMarshal(servers)
|
||||||
ctx.Writer.Header().Set("Location", sessionLocation(publish, res.sx.secret))
|
ctx.Writer.Header().Set("Location", sessionLocation(publish, pathName, res.sx.secret))
|
||||||
ctx.Writer.WriteHeader(http.StatusCreated)
|
ctx.Writer.WriteHeader(http.StatusCreated)
|
||||||
ctx.Writer.Write(res.answer)
|
ctx.Writer.Write(res.answer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *httpServer) onWHIPPatch(ctx *gin.Context, rawSecret string) {
|
func (s *httpServer) onWHIPPatch(ctx *gin.Context, pathName string, rawSecret string) {
|
||||||
secret, err := uuid.Parse(rawSecret)
|
secret, err := uuid.Parse(rawSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid secret"))
|
writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid secret"))
|
||||||
|
|
@ -232,6 +240,7 @@ func (s *httpServer) onWHIPPatch(ctx *gin.Context, rawSecret string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
res := s.parent.addSessionCandidates(webRTCAddSessionCandidatesReq{
|
res := s.parent.addSessionCandidates(webRTCAddSessionCandidatesReq{
|
||||||
|
pathName: pathName,
|
||||||
secret: secret,
|
secret: secret,
|
||||||
candidates: candidates,
|
candidates: candidates,
|
||||||
})
|
})
|
||||||
|
|
@ -247,7 +256,7 @@ func (s *httpServer) onWHIPPatch(ctx *gin.Context, rawSecret string) {
|
||||||
ctx.Writer.WriteHeader(http.StatusNoContent)
|
ctx.Writer.WriteHeader(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *httpServer) onWHIPDelete(ctx *gin.Context, rawSecret string) {
|
func (s *httpServer) onWHIPDelete(ctx *gin.Context, pathName string, rawSecret string) {
|
||||||
secret, err := uuid.Parse(rawSecret)
|
secret, err := uuid.Parse(rawSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid secret"))
|
writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid secret"))
|
||||||
|
|
@ -255,7 +264,8 @@ func (s *httpServer) onWHIPDelete(ctx *gin.Context, rawSecret string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.parent.deleteSession(webRTCDeleteSessionReq{
|
err = s.parent.deleteSession(webRTCDeleteSessionReq{
|
||||||
secret: secret,
|
pathName: pathName,
|
||||||
|
secret: secret,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, ErrSessionNotFound) {
|
if errors.Is(err, ErrSessionNotFound) {
|
||||||
|
|
@ -269,8 +279,8 @@ func (s *httpServer) onWHIPDelete(ctx *gin.Context, rawSecret string) {
|
||||||
ctx.Writer.WriteHeader(http.StatusOK)
|
ctx.Writer.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *httpServer) onPage(ctx *gin.Context, path string, publish bool) {
|
func (s *httpServer) onPage(ctx *gin.Context, pathName string, publish bool) {
|
||||||
if !s.checkAuthOutsideSession(ctx, path, publish) {
|
if !s.checkAuthOutsideSession(ctx, pathName, publish) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -320,10 +330,10 @@ func (s *httpServer) onRequest(ctx *gin.Context) {
|
||||||
if m := reWHIPWHEPWithID.FindStringSubmatch(ctx.Request.URL.Path); m != nil {
|
if m := reWHIPWHEPWithID.FindStringSubmatch(ctx.Request.URL.Path); m != nil {
|
||||||
switch ctx.Request.Method {
|
switch ctx.Request.Method {
|
||||||
case http.MethodPatch:
|
case http.MethodPatch:
|
||||||
s.onWHIPPatch(ctx, m[3])
|
s.onWHIPPatch(ctx, m[1], m[3])
|
||||||
|
|
||||||
case http.MethodDelete:
|
case http.MethodDelete:
|
||||||
s.onWHIPDelete(ctx, m[3])
|
s.onWHIPDelete(ctx, m[1], m[3])
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -339,7 +349,7 @@ func (s *httpServer) onRequest(ctx *gin.Context) {
|
||||||
s.onPage(ctx, ctx.Request.URL.Path[1:len(ctx.Request.URL.Path)-len("/publish")], true)
|
s.onPage(ctx, ctx.Request.URL.Path[1:len(ctx.Request.URL.Path)-len("/publish")], true)
|
||||||
|
|
||||||
case ctx.Request.URL.Path[len(ctx.Request.URL.Path)-1] != '/':
|
case ctx.Request.URL.Path[len(ctx.Request.URL.Path)-1] != '/':
|
||||||
ctx.Writer.Header().Set("Location", httpp.LocationWithTrailingSlash(ctx.Request.URL))
|
ctx.Writer.Header().Set("Location", mergePathAndQuery(ctx.Request.URL.Path+"/", ctx.Request.URL.RawQuery))
|
||||||
ctx.Writer.WriteHeader(http.StatusMovedPermanently)
|
ctx.Writer.WriteHeader(http.StatusMovedPermanently)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,7 @@ type webRTCAddSessionCandidatesRes struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type webRTCAddSessionCandidatesReq struct {
|
type webRTCAddSessionCandidatesReq struct {
|
||||||
|
pathName string
|
||||||
secret uuid.UUID
|
secret uuid.UUID
|
||||||
candidates []*pwebrtc.ICECandidateInit
|
candidates []*pwebrtc.ICECandidateInit
|
||||||
res chan webRTCAddSessionCandidatesRes
|
res chan webRTCAddSessionCandidatesRes
|
||||||
|
|
@ -160,8 +161,9 @@ type webRTCDeleteSessionRes struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type webRTCDeleteSessionReq struct {
|
type webRTCDeleteSessionReq struct {
|
||||||
secret uuid.UUID
|
pathName string
|
||||||
res chan webRTCDeleteSessionRes
|
secret uuid.UUID
|
||||||
|
res chan webRTCDeleteSessionRes
|
||||||
}
|
}
|
||||||
|
|
||||||
type serverPathManager interface {
|
type serverPathManager interface {
|
||||||
|
|
@ -343,7 +345,7 @@ outer:
|
||||||
|
|
||||||
case req := <-s.chAddSessionCandidates:
|
case req := <-s.chAddSessionCandidates:
|
||||||
sx, ok := s.sessionsBySecret[req.secret]
|
sx, ok := s.sessionsBySecret[req.secret]
|
||||||
if !ok {
|
if !ok || sx.req.pathName != req.pathName {
|
||||||
req.res <- webRTCAddSessionCandidatesRes{err: ErrSessionNotFound}
|
req.res <- webRTCAddSessionCandidatesRes{err: ErrSessionNotFound}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -352,7 +354,7 @@ outer:
|
||||||
|
|
||||||
case req := <-s.chDeleteSession:
|
case req := <-s.chDeleteSession:
|
||||||
sx, ok := s.sessionsBySecret[req.secret]
|
sx, ok := s.sessionsBySecret[req.secret]
|
||||||
if !ok {
|
if !ok || sx.req.pathName != req.pathName {
|
||||||
req.res <- webRTCDeleteSessionRes{err: ErrSessionNotFound}
|
req.res <- webRTCDeleteSessionRes{err: ErrSessionNotFound}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue