Browse Source

webrtc: do not pass preflight requests to external auth (#1941) (#1972)

pull/1976/head
Alessandro Ros 2 years ago committed by GitHub
parent
commit
5224531551
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      internal/core/webrtc_http_server.go
  2. 4
      internal/core/webrtc_manager_test.go

36
internal/core/webrtc_http_server.go

@ -177,10 +177,14 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {
// remove leading prefix // remove leading prefix
pa := ctx.Request.URL.Path[1:] pa := ctx.Request.URL.Path[1:]
if !strings.HasSuffix(pa, "/whip") && !strings.HasSuffix(pa, "/whep") { isWHIPorWHEP := strings.HasSuffix(pa, "/whip") || strings.HasSuffix(pa, "/whep")
isPreflight := ctx.Request.Method == http.MethodOptions &&
ctx.Request.Header.Get("Access-Control-Request-Method") != ""
if !isWHIPorWHEP || isPreflight {
switch ctx.Request.Method { switch ctx.Request.Method {
case http.MethodOptions: case http.MethodOptions:
ctx.Writer.Header().Set("Access-Control-Allow-Methods", "OPTIONS, GET") ctx.Writer.Header().Set("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PATCH")
ctx.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, If-Match") ctx.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, If-Match")
ctx.Writer.WriteHeader(http.StatusOK) ctx.Writer.WriteHeader(http.StatusOK)
return return
@ -230,7 +234,7 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {
user, pass, hasCredentials := ctx.Request.BasicAuth() user, pass, hasCredentials := ctx.Request.BasicAuth()
authRes := s.pathManager.getPathConf(pathGetPathConfReq{ res := s.pathManager.getPathConf(pathGetPathConfReq{
name: dir, name: dir,
publish: publish, publish: publish,
credentials: authCredentials{ credentials: authCredentials{
@ -241,23 +245,21 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {
proto: authProtocolWebRTC, proto: authProtocolWebRTC,
}, },
}) })
if authRes.err != nil { if res.err != nil {
if ctx.Request.Method != http.MethodOptions { if terr, ok := res.err.(pathErrAuth); ok {
if terr, ok := authRes.err.(pathErrAuth); ok { if !hasCredentials {
if !hasCredentials { ctx.Header("WWW-Authenticate", `Basic realm="mediamtx"`)
ctx.Header("WWW-Authenticate", `Basic realm="mediamtx"`)
ctx.Writer.WriteHeader(http.StatusUnauthorized)
return
}
s.Log(logger.Info, "authentication error: %v", terr.wrapped)
ctx.Writer.WriteHeader(http.StatusUnauthorized) ctx.Writer.WriteHeader(http.StatusUnauthorized)
return return
} }
ctx.Writer.WriteHeader(http.StatusNotFound) s.Log(logger.Info, "authentication error: %v", terr.wrapped)
ctx.Writer.WriteHeader(http.StatusUnauthorized)
return return
} }
ctx.Writer.WriteHeader(http.StatusNotFound)
return
} }
switch fname { switch fname {
@ -274,11 +276,9 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {
case "whip", "whep": case "whip", "whep":
switch ctx.Request.Method { switch ctx.Request.Method {
case http.MethodOptions: case http.MethodOptions:
ctx.Writer.Header().Set("Access-Control-Allow-Methods", "OPTIONS, POST, PATCH") ctx.Writer.Header().Set("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PATCH")
ctx.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, If-Match") ctx.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, If-Match")
if authRes.err == nil { ctx.Writer.Header()["Link"] = iceServersToLinkHeader(s.parent.genICEServers())
ctx.Writer.Header()["Link"] = iceServersToLinkHeader(s.parent.genICEServers())
}
ctx.Writer.WriteHeader(http.StatusOK) ctx.Writer.WriteHeader(http.StatusOK)
case http.MethodPost: case http.MethodPost:

4
internal/core/webrtc_manager_test.go

@ -453,11 +453,13 @@ func TestWebRTCPublish(t *testing.T) {
hc := &http.Client{Transport: &http.Transport{}} hc := &http.Client{Transport: &http.Transport{}}
// OPTIONS preflight requests must always work, without authentication // preflight requests must always work, without authentication
func() { func() {
req, err := http.NewRequest("OPTIONS", "http://localhost:8889/teststream/whip", nil) req, err := http.NewRequest("OPTIONS", "http://localhost:8889/teststream/whip", nil)
require.NoError(t, err) require.NoError(t, err)
req.Header.Set("Access-Control-Request-Method", "OPTIONS")
res, err := hc.Do(req) res, err := hc.Do(req)
require.NoError(t, err) require.NoError(t, err)
defer res.Body.Close() defer res.Body.Close()

Loading…
Cancel
Save