bluenviron / mediamtx

Ready-to-use SRT / WebRTC / RTSP / RTMP / LL-HLS media server and media proxy that allows to read, publish, proxy, record and playback video and audio streams.
MIT License
10.93k stars 1.42k forks source link

Feature Request - handle CORS for APIs and config allow origin #1792

Closed hu-xd closed 1 month ago

hu-xd commented 1 year ago

Describe the feature

currently mediamtx REST api don't handle OPTIONS requests, so CORS will fail, this means web-based apps can't call APIs from client-side JavaScript.

I hope mediamtx can handle browser CORS OPTIONS requests, and the allowed origins can be set in config file

ChoongTuckWai commented 1 year ago

I added import "github.com/gin-contrib/cors"

and add code in func newAPI in api.go

    router.Use(cors.New(cors.Config{
        AllowOrigins: []string{"*"},
        AllowMethods: []string{"GET", "POST"},
        AllowHeaders: []string{"Content-Type, access-control-allow-origin, access-control-allow-headers"},

could dirty solve CORS when call APIs from client-side JavaScript for me. looking for better way to do that.

phadkesharan commented 1 month ago

I have solved the cors issue using gin-contrib/cors package should I create a pull request?

aler9 commented 1 month ago

since v1.8.0 there's option apiAllowOrigin that allows to solve the CORS issue without manually hacking the code.

phadkesharan commented 1 month ago

I tried setting apiAllowOrigin but it did not work.

in mediamtx.yml apiAllowOrigin: 'http://localhost:4200'

I tried calling the control API from angular frontend but it failed due to CORS

Error in the browser console: Access to XMLHttpRequest at 'http://localhost:9997/v3/config/paths/add/sample-webrtc' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

aler9 commented 1 month ago

@phadkesharan i tried using the API through an external page with XMLHttpRequest, and i can confirm that the Access-Control-Allow-Origin is present.

It is not present on non-existing pages or when you call the end point with the wrong method (therefore, you're probably using the wrong method, which in case of the /config/paths/add endpoint should be POST). This is a secondary bug that will be fixed.

phadkesharan commented 1 month ago

@phadkesharan i tried using the API through an external page with XMLHttpRequest, and i can confirm that the Access-Control-Allow-Origin is present.

It is not present on non-existing pages or when you call the end point with the wrong method (therefore, you're probably using the wrong method, which in case of the /config/paths/add endpoint should be POST). This is a secondary bug that will be fixed.

I am sure I used the right method (POST) while calling the API This is my request :

let bodyContent = JSON.stringify({
  "name": "sample-webrtc" ,
  "source": "rtsp://localhost:8554/sample"
});

let response = await fetch("http://localhost:9997/v3/config/paths/add/sample-webrtc", { 
  method: "POST",
  body: bodyContent
});

let data = await response.text();
console.log(data);

I have enabled origin for control API in mediamtx.yml file

# Enable controlling the server through the Control API.
api: yes
# Address of the Control API listener.
apiAddress: :9997
# Enable TLS/HTTPS on the Control API server.
apiEncryption: no
# Path to the server key. This is needed only when encryption is yes.
# This can be generated with:
# openssl genrsa -out server.key 2048
# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
apiServerKey: server.key
# Path to the server certificate.
apiServerCert: server.crt
# Value of the Access-Control-Allow-Origin header provided in every HTTP response.
apiAllowOrigin: 'http://localhost:4200'

but when I make the request from my frontend application I get the error : Access to XMLHttpRequest at 'http://localhost:9997/v3/config/paths/add/sample-webrtc' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

jonra1993 commented 1 month ago

I was facing the same error when using React on the client side. The best I could do was use Caddy as reverse proxy and add CORS.

Caddyfile

(cors) {
  @cors_preflight method OPTIONS
  @cors header Origin {args.0}

  handle @cors_preflight {
    header Access-Control-Allow-Origin "*"
    header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE"
    header Access-Control-Allow-Headers "Content-Type"
    header Access-Control-Max-Age "3600"
    respond "" 204
  }

  handle @cors {
    header Access-Control-Allow-Origin "*"
    header Access-Control-Expose-Headers "Link"
  }
}

http://localhost:4000 {
    import cors http://localhost
    reverse_proxy localhost:9997   
}

caddy run --config Caddyfile

Reference is here https://kalnytskyi.com/posts/setup-cors-caddy-2/

phadkesharan commented 1 month ago

@aler9 should I create a new issue for addressing this problem ?

github-actions[bot] commented 1 month ago

This issue is mentioned in release v1.8.3 🚀 Check out the entire changelog by clicking here

aler9 commented 2 weeks ago

Fixed again by #3535

github-actions[bot] commented 1 week ago

This issue is mentioned in release v1.8.4 🚀 Check out the entire changelog by clicking here