Novelty Promotes Magicians
    Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

    nodesipublic

    Build Status Coverage Status Dependency status

    What is this?

    It's a subset of Edge Side Include standard implemented with promise-based interface.

    What problem does it solve?

    Let's say you want to use ESI in your project, but also want to retain good developer experience. Rather than having to configure Varnish or Ngnix to take care of server-rendered ESI tags locally you can simply pass the server output through esi.process function right before pushing it out to the client.

        var response = obtainServerResponseWithEsiTags();
        return Promise.resolve()
            .then(function() {
                if(process.env.NODE_ENV !== 'production') {
                    return esi.process(response);
                }
                return response;
            });

    It also improves code mobility - if for whatever reason you decide to move from ESI-enabled environment into one that doesn't support it (yet?), all you have to do is to process the response directly on the server. This module should be performant enough for that use case.

    Features

    • Support for esi:include tags
    • Out of the box Express support
    • Custom logging
    • Lots of good stuff like caching, retires, request collapsing and such provided by Good Guy HTTP

    ...and more, take a look at test cases for complete list.

    Installation

    npm install nodesi

    Usage

    Basic:

        var ESI = require('nodesi');
     
        var esi = new ESI({
            allowedHosts: ['http://full-resource-path']
        });
        esi.process('<esi:include src="http://full-resource-path/stuff.html" />').then(function(result) {
            // result is a fetched html
        });

    As Express middleware:

        var esiMiddleware = require('nodesi').middleware;
        var app = require('express')();
     
        // inject the middleware before your route handlers
        app.use(esiMiddleware());

    All the ESI constructor options described below are also applicable for middleware function. Just pass them like that: esiMiddleWare({baseUrl: ..., allowedHosts: [...]});

    If you'd like to pass options like headers to ESI middleware, use req.esiOptions object:

    ...
        app.use(esiMiddleware());
     
        app.get('/example', function(req, res) {
            req.esiOptions = {
                headers: {
                    'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
                }
            };
            res.render('example');
        });

    With base URL for relative paths:

        var ESI = require('nodesi');
     
        var esi = new ESI({
            baseUrl: 'http://full-resource-path'
        });
        esi.process('<esi:include src="/stuff.html" />').then(function(result) {
            // result is a fetched html
        });

    With headers:

        var ESI = require('nodesi');
     
        var esi = new ESI({
            baseUrl: 'http://full-resource-path'
        });
        esi.process('<esi:include src="/stuff.html" />', {
            headers: {
                'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
            }
        }).then(function(result) {
            // result is a fetched html
        });

    Security

    Since this module performs HTTP calls to external services, it is possible for a malicious agent to exploit that, especially if content of a esi:include tag can be provided by user.

    In order to mitigate that risk you should use allowedHosts configuration option. It's supposed to be a list of trusted hosts (protocol + hostname + port), represented as strings or regular expressions.

    Example:

    var esi = new ESI({
        allowedHosts: ['https://exact-host:3000', /^http(s)?:\/\/other-host$/]
    });

    If you're using baseUrl option then it's host will automatically be added to allowedHosts.

    In case some url gets blocked you'll receive an error in your onError handler (see below) with blocked property set to true.

    Error handling

    You can provide onError callback to a ESI constructor. It will recieve two arguments: source URL and error object.

    It should return a string that will be put in place of errorous content.

    Example

        var esi = new ESI({
            onError: function(src, error) {
                if(error.statusCode === 404) {
                    return 'Not found';
                }
                return '';
            }
        });

    Logging

    It's a common anti-pattern that libraries write to stdout w/o users permission.

    We want to be nice so you can provide your own logging output with logTo configuration option.

    It's expected to be an object with "write" method on it that accepts a single string.

    Examples

    Logging to a custom object

        var esi = new ESI({
            logTo: {
                write: function(log) {
                    // do some stuff with log string here
                }
            }
        });

    Logging to a standard output (same as console.log):

        var esi = new ESI({
            logTo: process.stdout
        });

    Logging to a file (possible, but please don't do that):

        var logFile = require('fs').createWriteStream('./log.txt');
        var esi = new ESI({
            logTo: logFile
        });

    Performance testing

    You can run performance tests with npm run perf [args]

    This tool assumes you have Siege installed and added to your Path variable.

    [args] are list of arguments that will be passed to Siege.

    Keywords

    install

    npm i nodesi

    Downloadslast 7 days

    180

    version

    1.7.0

    license

    ISC

    repository

    github.com

    last publish

    collaborators

    • avatar
    • avatar