nginx njs Upload Implementation

· 1 min read

Recently had nginx requirement to implement upload feature, pleasantly discovered it already supports js, so trying to use js to implement upload.

nginx Configuration

  1. To support njs need module loading

  2. For specific js business module usage, need to use js related directives

  3. load_module directive needs to be placed globally in default.conf

Example as follows

load_module modules/ngx_http_js_module.so;

events { }


http {

    # No longer restricting here, nginx default is 1MB
    client_max_body_size 0;

    js_path "/etc/nginx/njs/";

    js_import main from upload.js;

server {

   ...
    location /upload-cert {
        js_content main.resolve;
    }
   ...
}

njs Module Business Code

  • njs is just js subset, so syntax and functionality are also limited
const fs = require('fs');
const crypto = require('crypto');
const dest = `/var/www/ssl`;

function writeFile(fileContent, fileSuffix) {
  let fileName = `${crypto.createHash('md5').update(fileContent).digest("hex")}.${fileSuffix || 'crt'}`;
  fs.writeFileSync(`${dest}/${fileName}`, fileContent);
  return fileName;
}

function upload(r) {
  let body = JSON.parse(r.requestBody);
  r.return(200, JSON.stringify({
    crtFileName: writeFile(body.crtFile), keyFileName: writeFile(body.keyFile, 'key'),
  }));
}

function main(r) {
    upload(r);
}

export default {resolve: main}