简体   繁体   中英

How to call an hls server in a react app that is using https

So, I have a react app that is built and run through a nodejs server. This nodejs server is run with nginx which handles the cert. This react/nodejs server also is running a RTMP server this RTMP server is running an hls server.

So, basically the website has certs and runs over https://. I need to know what approach to take to call the hls server to display a stream on the website. The problem is that the package I am using "node-media-server" doesn't make it obvious how to convert the http to https and so when I cam calling the url from the react app I get a "(blocked:mixed-content)" error. when i am calling the.m3u8 file. So the react app will call the url "http://website.com/live/stream/index.m3u8". Do I need to convert this hls stream to https? If so how do I do this? maybe I need to change my nginx config?

Below is my nginx configuration.

upstream socketio {
#       ip_hash;
        server 127.0.0.1:8174;
}

upstream reactserve {
        server 127.0.0.1:3000;
}


upstream hls {
        server 127.0.0.1:8179;
}

#server {
#       listen          80;
#        server_name     www.idealgambler.com;
#       rewrite         ^(.*)   https://$host$1 permanent;


#}

server {

        listen                  443 ssl;
        ssl                     on;
        server_name             idealgambler.com www.idealgambler.com;

        access_log              /var/log/nginx/access-ssl.log;
        error_log               /var/log/nginx/error-ssl.log;


        location / {
        #       include proxy_params;
                proxy_pass              http://socketio;
                proxy_next_upstream     error timeout invalid_header http_500 http_502 http_503 http_504;
                proxy_redirect          off;
                proxy_buffering         off;

                proxy_set_header        Host                    $host;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto       $scheme;
                proxy_set_header Access-Control-Allow-Origin *;
                add_header              Front-End-Https         on;
                add_header              Access-Control-Allow-Origin *;
        }

        location /socket.io/ {
                proxy_pass              http://socketio;
                proxy_redirect off;

                proxy_http_version      1.1;

                proxy_set_header        Upgrade                 $http_upgrade;
                proxy_set_header        Connection              "upgrade";

                proxy_set_header        Host                    $host;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header Access-Control-Allow-Origin *;
                add_header              Access-Control-Allow-Origin *;
        }

        location /hls {
                proxy_pass              http://hls;
                proxy_redirect off;
                proxy_set_header        Host                    $host;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header Access-Control-Allow-Origin *;
                add_header              Access-Control-Allow-Origin *;
        }


    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


    ssl_certificate /etc/letsencrypt/live/idealgambler.com-0001/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/idealgambler.com-0001/privkey.pem; # managed by Certbot

}

Here is the NodeMediaServer code in nodejs:

require("./Casino/CasinoRouters/client-connected")(app, io);

const NodeMediaServer = require("node-media-server");
const config = {
  rtmp: {
    port: 1935,
    chunk_size: 60000,
    gop_cache: true,
    ping: 60,
    ping_timeout: 30,
  },
  http: {
    port: 8179,
    mediaroot: "./media",
    allow_origin: "*",
  },
  log_file: "./logs/nms.log",
  trans: {
    ffmpeg: process.env.FFMPEG_PATH,
    tasks: [
      {
        app: "live",
        hls: true,
        hlsFlags: "[hls_time=2:hls_list_size=3:hls_flags=delete_segments]",
        hlsKeep: true, // to prevent hls file delete after end the stream
        dash: true,
        dashFlags: "[f=dash:window_size=3:extra_window_size=5]",
        dashKeep: true, // to prevent dash file delete after end the stream
      },
    ],
  },
};

var nms = new NodeMediaServer(config);
nms.run();

So I have tried to update the nginx file, as well as changing the config for the nodemediaserver to https. The problem with changing http to https in the config is that the key "mediaroot" does not exist in https of nodemediaserver. The error I get is that it can't find the file "./media" when changing it to https in the express app. So basically the https hls will not run only http will run. perhaps there is a different config for running it through https.

I have tried adding the hls to the nginx configuration, but I don't think this did anything.

Ideally you should try to fix the URL and make it match the scheme of application (ie never mix http:// with https://) or make the app detect and correct it if the URL comes from an external source.

If it's not doable you might try to fall back to inserting Content-Security-Policy: upgrade-insecure-requests in the HTTP response headers. This would make the browser automatically convert all http:// to https:// as if the latter was originally requested by the app. You seem to have control over the deployment so this can be accomplished within Nginx configuration. Alternatively the header can be added to HTML head, as shown in this answer .

Watch out for WebSockets too. Secure ones (wss://) may require Sec-WebSocket-* headers to be passed by the proxy as per RFC6455 . Nginx doesn't do it by default. You will probably want to add the following lines to the configuration:

location /socket.io/ {
    # ...

    # pass client-to-server Sec-WebSocket-* headers
    proxy_set_header Sec-WebSocket-Key        $http_sec_websocket_key;
    proxy_set_header Sec-WebSocket-Version    $http_sec_websocket_version;
    proxy_set_header Sec-WebSocket-Extensions $http_sec_websocket_extensions;
    proxy_set_header Sec-WebSocket-Protocol   $http_sec_websocket_protocol;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM