PHP websockets with nginx via SSL

PHP websockets with nginx via SSL

How to setup websockets with PHP in nginx?
I have looked at this tutorial, but cant make it work
https://www.sanwebe.com/2013/05/chat-using-websocket-php-socket
Have copied the three files into the root of the www directory
/index.php
/jquery-3.1.1.js
/websocket/server.php
In index.php I have changed the URI
var wsUri = "wss://domain.com/websocket/server.php";

In nginx I have added this
http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }
    server {
        location /websocket/ {
            proxy_pass https://domain.com:9000/websocket/server.php;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }
    }
}

http://nginx.org/en/docs/http/websocket.html
To start websocket server
php -q /var/www/websocket/server.php

The chat is located at https://domain.com/chat.php and loads but get this error in the chat window Error Occurred - Connection closed
Have also tried to connect through this tool, but get this error
http://www.websocket.org/echo.html
ERROR: undefined
DISCONNECTED

If requested through browser
wss://domain.com/websocket/server.php


ERR_DISALLOWED_URL_SCHEME

Solutions/Answers:

Answer 1:

You’re using port 9000 in your nginx configuration, while PHP’s built-in web server runs on port 8000.

Try change the port to 8000 and see if that resolves it.

proxy_pass http://domain.com:8000/websocket/;

Edit:

Regarding ERR_DISALLOWED_URL_SCHEME

Chrome, since ~version 50, requires that all websocket communication be over SSL. You’re probably going to need to enable that in order to have your app work in Chrome.

You have two options:

  1. Use a certificate issued by a trusted certificate authority
  2. Add the certificate manually to your trusted certificate roots. Your web application won’t work for anyone who doesn’t do this manually

Answer 2:

I have spotted few glitches in your config file; my observations are as follows:

  • Running php -q /var/www/websocket/server.php will start simple socket server. It won’t be SSL; i guess thay’s why you are passing it through nginx. isn’t it?
  • Thus proxy_pass https://domain.com:9000/websocket/server.php; should not be https. You also don’t need the full path as it’s a simple tcp socket and not a file path. Thus just proxy_pass http://127.0.0.1:9000; should do.
  • If you are implementing SSL at nginx; where are those settings?
  • In all new browsers; you can’t access unsecured http or ws resources from a secured https page.

Thus following is my config file which seems to be working as intended.

 server {
    listen 8080 default_server;
    listen 8443 ssl;

    ssl_certificate /home/ubuntu/Desktop/php-sock/newcert.pem;
    ssl_certificate_key /home/ubuntu/Desktop/php-sock/newkey.pem;

    root /home/ubuntu/Desktop/php-sock;

    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location /websocket/ {
        proxy_pass http://127.0.0.1:9000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
    }
}

Also make change in index.php to var wsUri = "wss://localhost:8443/websocket/";

Our Awesome Free Tools

References

How to get redirector.googlevideo.com link from a Google drive video

How to get redirector.googlevideo.com link from a Google drive video

I have a google drive video file (like https://drive.google.com/file/d/FILE_ID/view) and I want to get its redirector.googlevideo.com link.
How do sites like http://api.getlinkdrive.com/ do it? I've tried using the Google Drive REST API, (both v2 and v3) but still can't find a way to do it. Many tv-show and movie sites host their content on google drive, and use this "cloaked" URL that expires so you can't for example embed it somewhere else.
The closest I've gotten is by going to docs.google.com/get_video_info?docid=FILE_ID and getting the fmt_stream_map links, but that doesn't return the redirector link which I need.

Solutions/Answers:

Answer 1:

He is talking about getting the URL from google drive all qualities in 360p,480p,720p,1080p and convert just before the /videoplayback to redirector.googlevideo.com and make it as video/mp4 to do playback in JW Player.I have the full script but it has got a minor problem it says forbidden 403 and it is because of changes google made in API.Have a look at the codes in PHP and let me know if someone can fix it,i will post full script later.

function Drive($link) {
    $url = urldecode($link);
    $get = curl1($url);
    $data = explode(',["fmt_stream_map","', $get);
    $data = explode('"]', $data[1]);
    $data = str_replace(array('\u003d', '\u0026'), array('=', '&'), $data[0]);
    $data = explode(',', $data);
    asort($data);
    foreach($data as $list) {
        $data2 = explode('|', $list);
        if($data2[0] == 37) {$q1080p = preg_replace("/\/[^\/]+\.google\.com/","/redirector.googlevideo.com",$data2[1]);}    // 1080P
        if($data2[0] == 22) {$q720p = preg_replace("/\/[^\/]+\.google\.com/","/redirector.googlevideo.com",$data2[1]);}     // 720P
        if($data2[0] == 59) {$q480p = preg_replace("/\/[^\/]+\.google\.com/","/redirector.googlevideo.com",$data2[1]);}     // 480P
        if($data2[0] == 18) {$q360p = preg_replace("/\/[^\/]+\.google\.com/","/redirector.googlevideo.com",$data2[1]);}     // 360P
    }
    $js[0][0] = "$q1080p";
    $js[0][1] = "$q720p";
    $js[0][2] = "$q480p";
    $js[0][3] = "$q360p";
    $js[1][0] = "1080P";
    $js[1][1] = "720P";
    $js[1][2] = "480P";
    $js[1][3] = "360P";
    return $js;     
}
if ($jw[0][0] != "") {
    echo('{file: "'.urldecode($jw[0][0]).'",type: "video/mp4",label: "'.urldecode($jw[1][0]).'"},');
}
if ($jw[0][1] != "") {
    echo('{file: "'.urldecode($jw[0][1]).'",type: "video/mp4",label: "'.urldecode($jw[1][1]).'"},');
}   
if ($jw[0][2] != "") {
    echo('{file: "'.urldecode($jw[0][2]).'",type: "video/mp4",label: "'.urldecode($jw[1][2]).'"},');
}   
if ($jw[0][3] != "") {
    echo('{file: "'.urldecode($jw[0][3]).'",type: "video/mp4",label: "'.urldecode($jw[1][3]).'"},');
}

Answer 2:

I implemented a better algorithm from the previous answer.

function curl($url){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER, $return);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

function Drive($id) {
    $o = [];
    $url = "https://docs.google.com/get_video_info?docid=$id";
    $get = curl($url);

    parse_str($get, $out);
    $data = explode(",", $out["fmt_stream_map"]);

    foreach($data as $d) {
        switch ((int)substr($d, 0, 2)) {
            case 18:
                $r = "360P";
                break;
            case 22:
                $r = "720P";
                break;
            case 37:
                $r = "1080P";
                break;
            case 59:
                $r = "480P";
                break;
            default:
                break;
        }
        $o[$r] = substr(preg_replace("/\/[^\/]+\.google\.com/","/redirector.googlevideo.com", $d), 3);
    }
    ksort($o);
    return $o;
}
$jw = Drive(FILE_ID_HERE);

foreach ($jw as $k => $r) {
    echo json_encode(array("file"=> $r, "type"=> "video/mp4", "label"=> $k))."\n";
}

Answer 3:

Php code will not work here and even meaningless, because it will return the result for server side.

This is my Javascript/Ajax code.
Unfortunately, you should use Access-Control-Allow-Origin extension in Chrome browser.
First, please see this screenshot of console window.

<!DOCTYPE html>
<html>
   <head>
      <script src="https://code.jquery.com/jquery-3.2.1.min.js"  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="  crossorigin="anonymous"></script>
      <script src="https://content.jwplatform.com/libraries/YOUR-JW-PLAYER-LICENSE-KEY.js"></script>
   </head>

   <body>
      <p id="urls"></p>
      <div id="myElement"></div>
   </body>

   <script>
      var docid = "0B4Mn0g4wWmQ1ZThycVhOcDJQc2c";
      var api_url = "https://docs.google.com/get_video_info";
      var ans = {};
      var url = "";

      getGoogleVideoUrl();

      function getGoogleVideoUrl(){
        $.ajax({
          url: api_url,
          type: "get",
          data: { 
            docid: docid,
          },
          success: function(response) {
            //
            // get value of which key is 'fmt_stream_map'.
            //
            var fmt_stream_map = getQueryVariable(response, 'fmt_stream_map');
            //
            // split my comma
            //
            var maps = fmt_stream_map.split("%2C");
            //
            // loop all links, 
            //  
            var purl = "";          
            for (x in maps) {
                var res = decodeURIComponent(decodeURIComponent(maps[x])).split('|');
                // purl = res[1].replace(new RegExp("/\/[^\/]+\.google\.com/", 'g'),"//redirector.googlevideo.com/");
                // purl = res[1].replace(new RegExp("\.google\.com/", 'g'),".googlevideo.com/");

                purl = res[1];
                //.replace(/.c.docs.google.com/g,".googlevideo.com")
                //.replace(/app=explorer/g,"app=storage")
                //.replace(/key=ck2/g,"key=cms1")
                //.replace(/&cp=/g,"&api=")
                //.replace(/,cp&/g,',api&')
                //.replace(/,cp,/g,',api,')
                //.replace(/=cp,/g,'=api,')
                //.replace(/&sparams=/g,'&cms_redirect=yes&sparams=');

                switch (parseInt(res[0])) {
                case 5:
                    quality = 'Low Quality, 240p, FLV, 400x240';
                    break;
                case 17:
                    quality = 'Low Quality, 144p, 3GP, 0x0';
                    break;
                case 18:
                    quality = 'Medium Quality, 360p, MP4, 480x360';
                    break;
                case 22:
                    quality = 'High Quality, 720p, MP4, 1280x720';
                    break;
                case 34:
                    quality = 'Medium Quality, 360p, FLV, 640x360';
                    break;
                case 35:
                    quality = 'Standard Definition, 480p, FLV, 854x480';
                    break;
                case 36:
                    quality = 'Low Quality, 240p, 3GP, 0x0';
                    break;
                case 37:
                    quality = 'Full High Quality, 1080p, MP4, 1920x1080';
                    break;
                case 38:
                    quality = 'Original Definition, MP4, 4096x3072';
                    break;
                case 43:
                    quality = 'Medium Quality, 360p, WebM, 640x360';
                    break;
                case 44:
                    quality = 'Standard Definition, 480p, WebM, 854x480';
                    break;
                case 45:
                    quality = 'High Quality, 720p, WebM, 1280x720';
                    break;
                case 46:
                    quality = 'Full High Quality, 1080p, WebM, 1280x720';
                    break;
                case 82:
                    quality = 'Medium Quality 3D, 360p, MP4, 640x360';
                    break;
                case 84:
                    quality = 'High Quality 3D, 720p, MP4, 1280x720';
                    break;
                case 102:
                    quality = 'Medium Quality 3D, 360p, WebM, 640x360';
                    break;
                case 104:
                    quality =  'High Quality 3D, 720p, WebM, 1280x720';
                    break;
                default:
                    quality =  'transcoded (unknown) quality';
                    break;
                }
                ans[quality] = purl;
            }
             console.log(ans);
             $('#urls').html(JSON.stringify(ans));

             url  = ans[Object.keys(ans)[0]];
             build_player();

          },
          error: function(xhr) {
            //Do Something to handle error
          }
        });
      }



      function build_player(){
        var playerInstance = jwplayer("myElement");
        playerInstance.setup({
            file: url,
            type: "mp4",
            width: 800 , 
            height: 600,
        }); 
      }

      function getQueryVariable(query, variable) {
          var vars = query.split('&');
          for (var i = 0; i < vars.length; i++) {
              var pair = vars[i].split('=');
              if (decodeURIComponent(pair[0]) == variable) {
                  //return decodeURIComponent(pair[1]);
                  return pair[1];
              }
          }
          console.log('Query variable %s not found', variable);
          return "";
      }

   </script>
</html>

This code works basically, but doesn’t play in jwplayer component.

However, if you enter this URL, “https://docs.google.com/get_video_info?docid=0B4Mn0g4wWmQ1ZThycVhOcDJQc2c“, directly in chrome browser, get JSON file , parse it manually, use one of URLs directly in this code as jwplayer’s file url, it works perfectly, although it contains “app=explorer” tag in itself.

I’m not sure why this happens.
So I tried to compare 2 links and some parameters is different. The first one is from above code and not working, the 2nd JSON file directly and working.)

ei=hJ5yWaHCKYXb-wWona2YBA
ei=KZ5yWZSkK4aFqgXAwpoo

susci=o-AC34EOoA1Wst0Heh0U_bP9epqR8K9s4UBhwlqmsxKZKwAOA
susci=o-AH82qbGL8BcWQ3BPybbvZyuNBiDd2Uasz4J0ZNXJCZwobPje

expire=1500698308
expire=1500698217

cp=QVNFUkdfV1NOSVhOOnhwOWFybUloWXNX
cp=QVNFUkdfV1JPSFhOOmpURGRUeUt3eVpv

signature=3D306FD9D9ADA683D313AABDFE057B608A6F2A39.8BB3A9C321B6BEAC8D1D5AEED2F25511DF97CE2B
signature=2C2465BDFC4D9CCFD0D4A42F38BAEF44D55AFDF1.A916937113445ABB90D18B3AE89600729CFADDE6

Why first one is not working while 2nd is working?
Any idea of this?

Answer 4:

I’m pretty sure this was asked a long time ago, but I think I can get you on your path to what you want. So what you’re going to want to do is go to Google Photos Settings and check the option that allows your videos in drive to be shown in photos. Return to google photos and select the video you want a direct link to. Right-click on the thumbnail an copy the link. It should something like https://lh3.googleusercontent.com/[long string]=w1278-h719-k-no. The last part , =w1278-h719-k-no, give it a small change to a =m22. It will auto generate a link for you. Hope it goes well for you.

Edit: Sorry, not exactly a googlevideo redirector link, but it works!

Edit: After a bit more of experimentation, I figured out that setting it to =m15 gives you a longer link. It works equally as the first one. Changing the number after the m will give you different resolutions. So, you can experiment with that.

EditL Alright. After even more experimentation, I uploaded two different videos, one to drive and the other to photos. I got the lh3.googleusercontent.com link for both of them and got their direct video links. The one from drive was hosted on r3---something.googleusercontent.com and the one from photos was hosted on r5--something.googlevideo.com. And I thought, what if I replace the r5--something part of it with redirector? I went and did it, and well, what do you know! It worked! And that is how you get yourself a redirector.googlevideo.com link. BUT, I’m still unsure how api.getlinkdrive.com is able to get a redirector.googlevideo.com link. Since the links generated by google are IP specific, meaning it would work for api.getlinkdrive.com, since it requested it with its own IP, but not for another user, with a different IP.

Edit: Forgot to mention this, but I’m sure some people have noticed that some redirect links aren’t lh3.googleusercontent.com, but 3.bp.blogspot.com. Well, the following domains can take the place of lh3.googleusercontent.com;

  • lh3.googleusercontent.com
  • lh4.googleusercontent.com
  • lh5.googleusercontent.com
  • lh6.googleusercontent.com
  • 1.bp.blogspot.com
  • 2.bp.blogspot.com
  • 3.bp.blogspot.com

Our Awesome Free Tools

References