Using NginScript as a file distribution service with permissions

Before, there was a CDN service with permission verification. It did not open overseas CDNs synchronously. It has always used a server in Hong Kong to provide file services. In order to implement the same authority algorithm as CDN, Node is used as the server. Of course, JS is very easy to do permission verification logic, but Node is a little weak in doing file service. I don't know how to read file stream, write http stream and zero copy. It seems that there are problems such as memory leakage that can't be located. The service will die inexplicably in a few days. I have to write a monitor to pull it up.

In fact, I always know that Nginx+Lua may be the best solution, but think about learning a language that seems useless in other occasions... Let the Node service restart.

Until the discovery of NginScript (NJS), it is very suitable to write in javascript. This stateless computing service is embedded in the file distribution process.

Install the latest Nginx+NJS. The server is CentOS 8.2. Select the corresponding rpm package:

rpm -Uvh https://nginx.org/packages/centos/8/x86_64/RPMS/nginx-1.20.1-1.el8.ngx.x86_64.rpm
rpm -Uvh https://nginx.org/packages/centos/8/x86_64/RPMS/nginx-module-njs-1.20.1%2B0.7.0-1.el8.ngx.x86_64.rpm

Files are always managed in COS and distributed to CDN through cos. The simplest way for Nginx to distribute COS is to mount the bucket in / mnt directory with COSFS. However, the CentOS system of 8.0 + is incompatible when installing COSFS with yum. To download and compile:

 yum install automake gcc-c++ git libcurl-devel libxml2-devel fuse-devel make openssl-devel fuse
git clone https://github.com.cnpmjs.org/tencentyun/cosfs /usr/cosfs
cd /usr/cosfs
./autogen.sh
./configure
make
sudo make install
cosfs --version

GitHub access is often not connected. It was successfully downloaded to the acceleration site github.com.cnpmjs.org.

Because the file access permission is required, the directory somewhere where where COS is mounted cannot be directly opened to the outside in Nginx, but to the inside. Only authenticated requests can be downloaded by internal redirection:

    load_module modules/ngx_http_js_module.so;
    ......
    http {
    ......
    js_import http.js;
    ......
    
    location /somewhere{
        internal;
        root /mnt/somewhere/;
    }
    
    location / {
        js_content http.redirect;
    }

In this way, external HTTP requests can be directly authenticated in http.js, and then they can access somewhere:

function redirect(r) {
	for(var i in headers){
		r.headersOut[i]=headers[i];
	}

	if(r.method == "OPTIONS"){
		r.return(200, "ok");
	}else{
		var pathname = r.uri;
		if(/\.((jpe?g)|(png)|(gif)|(ico)|(html?))$/.test(r.uri)){
			r.internalRedirect('/somewhere'+r.uri);
		}else if(r.args && r.args.data){
			var checkResult = checkAuth(decodeURIComponent(r.args.data));
			if(checkResult){
				r.internalRedirect('/somewhere'+checkResult);
			}else{
				r.internalRedirect('/somewhere/404.html');
			}
		}else{
			r.internalRedirect('/somewhere/404.html');
		}
	}
}

export default {redirect};

Authentication algorithm:

function checkAuth(fullpath){
	const crypto = require('crypto'),
	rFullPath = /https:\/\/www.myDomainName.com([^\.]*\.mp3)\?sign=([\d]+)\-([0-9a-z]+)\-([0-9]+)\-([0-9a-f]+)/ ;
	cdnkey = "my-cdn-key...................";
	if(!rFullPath.test(fullpath)){
		return false
	} ;
	var t=fullpath.match(rFullPath);
	var path=t[1],timestamp=t[2],rand=t[3],uid=t[4],md5=t[5]
	var timeDiff = Date.now()-timestamp;
	if(timeDiff>3600000){
		return false	
	}
	var data = path+"-"+timestamp+"-"+rand+"-"+uid+"-"+cdnkey;
	if (md5 == crypto.createHash('md5').update(data).digest("hex")){
		return decodeURI(path)
	};
	return false;
}

JS is a company in the world. Most of the code logic can be directly used after being picked out from the Node service program.

In this way, the static file distribution with verification of Tencent cloud CDN is simply reproduced with NginScript.

Keywords: Nginx

Added by mosizlak on Thu, 11 Nov 2021 10:12:39 +0200