npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dx-proxy-cache

v0.0.3

Published

Programmable reverse caching proxy. Use as a stand-alone app or an express middleware. Comes with TTL and MongoDB adapters.

Downloads

5

Readme

Build Status Code Climate

Proxy Cache

Programmable reverse caching proxy. Use as a stand-alone app or an express middleware. Comes with TTL and MongoDB adapters.

Features

  • Request pooling: multiple requests with a cache miss will be pooled, i.e. only one request will be made upstream
  • Fast in memory caching -- adapter cache are used as a second layer
  • Extensible Adapter API
  • Express middleware compatible
  • Gzip compression when using the stand-alone server
  • Stale-caching: serve stale cache while updating the cache object asynchronously in the background
  • Remove cache objects (largest and least hit ones first) after a set memory threshold (defaults to 2GiB)

Install

npm install rn-proxy-cache

Usage

Stand-alone server with simple global-TTL caching

Note the --spoof-host-header option rewrites your "Host" header value to match the target host value. You probably won't use this in a normal proxy-cache setup unless you're running some sort of mirror site.

npm start \
--target-host="highscalability.com:80" \
--proxy-port=8080 \
--spoof-host-header \
--ttl=30000
  • --target-host="www.google.com:80": your upstream host.
  • --proxy-port=8080: the port for this proxy server.
  • --spoof-host-header: use this to rewrite Host header value to the --target-host value. Only useful if your upstream application needs to use the domain specified by the --target-host value.
  • --ttl=30000: TTL caching in milliseconds, defaults to 600000ms (10 minutes)

Stand-alone server using MongoDB as a global cache expire schedule and persistent cache storage

npm start \
--target-host="www.apple.com:80" \
--proxy-port=8080 \
--spoof-host-header \
--mongodb-url="mongodb://localhost:27017/test" \
--use-external-cache \
--watch-interval=60000 \
  • --mongodb-url: Supply this to use the MongoDB adapter. Will watch the PublishSchedule collection that contains documents with the publish_date ISO Date string field and clears cache accordingly.
  • --use-external-cache: Enables storing cached objects in the external storage interface provided by the adapter, useful if you run multiple instances of the proxy or surviving restarts
  • --watch-interval: How long between each time it checks the PublishSchedule collection. Defaults to 30sec.

Additional parameters when running as a stand-alone server

  • --mem-usage: Shows memory usage info every 30sec.
  • --verbose-log: Verbose logging for debugging.

Express middleware

var ProxyCache = require('rn-proxy-cache'),
    express = require('express'),
    app = express();

var proxyCache = new ProxyCache({
    targetHost: "highscalability.com:80",
    spoofHostHeader: true // again, doubt you need to enable this if you're running your own site
});

app.use(proxyCache.createMiddleware());

proxyCache.ready.then(function() {
    app.listen(8181, function () {
        console.log("ProxyCache server is ready");
    });
});

Use new ProxyCache(options) to create a new instance of the proxy cache. options are:

  • targetHost: the upstream host to proxy to. Defaults to "localhost:80"
  • httpProtocol: "http" or "https", defaults to "http".
  • Adapter: the cache adapter module to use, see lib/adapters for examples. Defaults to the TTL adapter.
  • adapterOptions: adapters are passed these options when constructed, i.e. new Adapter(proxyCacheInstance, options)
  • httpProxyOptions: upstream proxy requests are made using http-proxy, these options are passed to the httpProxy.createProxyServer() method.
  • allowStaleCache: allow stale cache to be served while asynchronously making a request upstream to update the cache object.
  • spoofHostHeader: rewrite the upstream request header Host value to match targetHost
  • memGiBThreshold: the maximum memory threshold before cleaning up some less hit cache objects to free memory

Optionally set req.shouldCache to let ProxyCache know if a request should be cached.

Creating a custom Adapter

To implement a custom Adapter, create a node module with the following constructor interface: CacheAdapter(proxyCache, options){ ... }.

There are 2 things you can do with a custom adapter:

  1. Decide when to invalidate the memory cache by calling proxyCache.clearAll()
  2. Implement external cache storage with the following interfaces as CacheAdapter's prototype methods: setCache(key, value), getCache(key), clearCache(), all returning a promise that resolves when the task is completed.

Finally if you need to init the adapter asynchronously, you can set a .ready promise property on the adapter instance and resolve when ready.

Notes

  • "host-rewrite" option is disabled for redirects.
  • Response status codes from upstream that's greater than 200 are not cached.
  • Empty response bodies are not cached.
  • mobile-detect is used to generate part of the cache key prefix: phone or not_phone. This should be the most common case of upstream response variations. Ideally, we should use Vary headers provided by upstream responses.

TODOs

Pull requests are welcome :)

  • [ ] Expose ProxyCache instance in express routes -- http.ClientRequest#proxyCache
  • [ ] Express middleware API, e.g. proxyCache.createMiddleware(app, /\/api\/.*/, { targetProtocol: 'https', targetHost: 'localhost:8081', rewriteUrl: rewriteUrlMethod })
  • [ ] When targetHost is not provided, set upstream to the local response stream (aka http.ServerResponse object in the express route), instead of the proxy response generate with http-proxy
  • [ ] Support ETag for browsers and Vary for upstream response variations. See RFC2616 for more.
  • [ ] Dockerfile, systemd unitfile templates, and other proc management files
  • [ ] Add feature to regenerate cache (precache), generating the ones with the most cache hits first
  • [ ] Add option to override ProxyCache.prototype.getCacheKey method
  • [ ] Handle very large responses?