Morphy2k/broadcast-notification-system

View on GitHub
lib/middleware/static-serve.js

Summary

Maintainability
A
3 hrs
Test Coverage
'use strict';

const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
const stream = require('stream');

const config = require('./../../config');
const server = require('./../server');
const app = server.app;


class StaticServe {
  constructor(route, mount) {

    this.route = route;
    this.mount = mount;

    this.extensions = [
      'json',
      'css',
      'js',
      'svg',
      'png',
      'jpg',
      'gif',
      'apng',
      'ttf',
      'otf',
      'woff',
      'woff2',
      'mp3'
    ];

    this.mimes = {

      // application
      json: 'application/json',
      js: 'application/javascript',

      // text
      css: 'text/css',

      // image
      svg: 'image/svg+xml',
      png: 'image/png',
      jpg: 'image/jpeg',
      gif: 'image/gif',
      apng: 'image/apng',

      // font
      ttf: 'font/ttf',
      otf: 'font/oft',
      woff: 'font/woff',
      woff2: 'font/woff2',

      // audio
      mp3: 'audio/mpeg',
      ogg: 'audio/ogg',
      webm: 'audio/webm'

    };

  }

  serve() {
    return async (ctx, next) => {

      let url = ctx.url;

      if ((ctx.method === 'HEAD' || ctx.method === 'GET') && (url.startsWith(this.route))) {

        const parse = () => {
          for (let el of this.extensions) {

            let ext = `.${el}`,
              query = `.${el}?`;

            if (url.indexOf(ext) !== -1) {

              if (url.indexOf(query) !== -1) url = url.substring(0, url.indexOf(query) + query.length - 1);

              url = url.replace(this.route, '');
              ctx.type = `${this.mimes[el]}`;

              return path.join(`${this.mount}${url}`);
            }
          }

          return;
        };

        const file = parse();

        if (file) {

          const data = fs.createReadStream(file);

          ctx.set('Cache-Control', `private, max-age=${24 * 60 * 60}`);

          data.on('error', err => {
            app.emit('error', err, this);
            ctx.status = 404;
            ctx.res.end();
          });

          if (config.server.compression && ctx.acceptsEncodings('gzip')) {
            ctx.set('Content-Encoding', 'gzip');
            ctx.body = data.pipe(zlib.createGzip()).pipe(stream.PassThrough());
          } else {
            ctx.body = data.pipe(stream.PassThrough());
          }

        }

      }

      await next();

    };
  }

}

module.exports = StaticServe;