Nitrogen Peroxide Monoxide


    0.1.41 • Public • Published


    A simple web server, implement with filter and handler.


    • Filter (Middleware): A request will try to match all the filters first.
    • Handler: When a request matched a handler, it will returned, only one handler will be executed.
    • Session: By config sessionDir, you can store session in files, with JSON format
    • File: Support uploading files
    • Cache: Cahce template in release mode


    npm install websvr


    It's simple to start the websvr.

    //import WebSvr module
    var WebSvr = require("websvr");
    //Start the WebSvr, runnting at parent folder, default port is 8054, directory browser enabled;
    //Trying at: http://localhost:8054
    var webSvr = WebSvr({
        home: "./web"
      , listDir:  true
      , debug:    true
      , sessionTimeout: 60 * 1000

    Filter (HttpModule)

    Session based authentication, basically useage:

    Session support; 
    webSvr.filter(function(req, res) {
      //Link to next filter;
    }, {session:true});
    * filter equal to use
    webSvr.use('/home', function(req, res) {
      //do sth.;

    Filter all the requests that begin with "test/", check the user permission in session, except the "index.htm" and "".

    Session Filter: protect web/* folder => (validation by session);
    webSvr.filter(function(req, res) {
      //It's not index.htm/, do the session validation
      if (req.url.indexOf("login.htm") < 0 && req.url.indexOf("") < 0 && req.url !== '/') {
        var val = req.session.get("username");
        console.log("session username:", val);
        !val && res.end("You must login, first!");
        //Link to next filter;
      } else {;
    }, { session: true });

    Handler (HttpHandler, Servlet)

    Handle Login and put the username in session

    Handler: => (validate the username & password)
      username: admin
      password: 12345678
    webSvr.url equal to webSvr.get/
    webSvr.url("", function(req, res) {
      var qs = req.body;
      if (qs.username == "admin" && qs.password == "12345678") {
        //Add username in session
        var session = req.session.set("username", qs.username);
      } else {
        res.end("Wrong username/password");
    }, 'qs');


    Filter and Handler doesn't have the same match rules when you sending a request

    Filter : Match any section in the request url, for example

    websvr.filter(".svr", cb);

    The result is

    request: ""   match: true

    Handler : Match from the begining (ignore the first '/'), etc:

    websvr.handle("root/login", cb)   //equal to
    websvr.handle("/root/login", cb)


    request: ""         match: true
    request: ""   match: false

    You can use regular expression to match any part of url in Handler.


    //get cookie value by key


    Render template with params, using doT template engine

    res.render([view, model]);

    View is optional, it will get the location of template from req.url

    res.render({json: true});

    View is a relative path, relative to web home

    //means related to Setting.home
    res.render("list.tmpl", {json: true});

    View is a absolute path, relative to web root

    //means related to Setting.root
    res.render("/list.tmpl", {json: true});

    Render raw HTML views

    res.renderRaw(viewContent, model);

    You can change template engine,


    for example:


    You can define some default properties in model, for example header/footer, this parameters will be overridden if they have the same key in your custom model.

        title   : "WebSvr Page"
      , username: "WebSvr"

    You can use template and render it by using websvr.render(tmplPath, model, callback), tmplPath relative to webSvr.home;

    //pre-defined model
    var model = {};
    //render a template using model, callbak argument is result html
    webSvr.render("header.tmpl", {categoryList: category.categoryList}, function(html) {
      //store rendered html to header
      model.header = html;

    Include file, you can using "#include" to include a file during rendering a template, in order to make the process easier, the file will fetched from the cache pool so the first refresh will not work when you first start the server;

    Be ware: include file: relative to web home, not the template file itself.###

    <div id="articles" class="container home">

    Cache templates, by default, server will cache the templates(include the "include file" in the templates), turn it off via:

    var webSvr = WebSvr({
      templateCache: false

    Clear the cached templates


    Enable template engine and '', using: res.render()/res.render(model)/res.render(tmplPath, model), etc

    webSvr.url(['login.htm', 'setting.htm'], function(req, res) { res.render(); });

    It also support include file in include files, but you need to refresh more times after the first running.


    Return configuration of current WebSvr instance


    Settings API:

    var Settings = {
      //home folder of web
      home: "../"
      //http start
      //default port of http
      , port: 8054
      //default port of https
      , httpsPort:  8443
      , httpsKey:   ""
      , httpsCert:  ""
      //list files in directory
      , listDir: false
      //enable client-side cache(304)
      , cache: true
      //enable debug information output
      , debug: true
      //enable cache of template/include file (when enabled templates will not be refreshed before restart)
      , templateCache: true
      //default pages, only one is supported
      , defaultPage: "index.html"
      //404 template/static file
      , 404:         "404.tmpl"
      //show errors to user(displayed in response)
      , showError: true
      Session timeout, in milliseconds.
      , sessionTimeout: 1440000
      //session file stored here
      , sessionDir: os.tmpDir()
      //session domain, e.g. ""
      , sessionDomain: ""
      //tempary upload file stored here
      , uploadDir:  os.tmpDir()


    Extension on reponse object

    Ouput file, filepath relative to the root

    res.sendRootFile(filePath, [callback]);

    Ouput file, filepath relative to the home (web dir)


    Reidrect request


    Return request object


    Set Content-Type


    Set/Remove Cookie

    //Set Cookie
    res.cookie(name, value [, {domain: string, path: string, expires: date, secure, httponly }])
    //Remove Cookie
    res.cookie(name, null);

    Change default charset

    res.charset = 'utf-8'

    WebSvr APIs

    Mapping url to file, webSvr.url equal to webSvr.handle

    webSvr.url("sitetest", ["svr/sitetest.js"]);

    Mapping url to string

    webSvr.url("hello", "Hello WebSvr!")

    Handle post"post.htm", function(req, res) {
        res.end('Received : ' + req.body);
    //Equal to
    webSvr.handle("post.htm", function(req, res) {
        res.end('Received : ' + req.body);
    }, {post: true});

    Post type

    post: true/"json"/"qs"

    Handle session

    webSvr.session("session required url", function(req, res) {

    Handle upload file, it's a specfic filter

    webSvr.file("", function(req, res) {
      res.writeHead(200, {"Content-Type": "text/plain"});
      //Upload file is stored in req.files
      //form fields is stored in req.body

    Valid File beofre receing it

    * Valid request before receiving
    webSvr.file("", function(req, res) {
      res.writeHead(200, {"Content-Type": "text/plain"});
    }).before(function(req, res) {
      if ((req.headers['content-length'] || 0) > 245760) {
        res.send('Posting is too large, should less than 240K')
      } else {
        return true

    Multi-Mapping in Handler or Filter

    webSvr.handle(["about", "help", "welcome"], function(req, res) {
        res.writeFile(req.url + ".shtml");
    }, {post: true});

    Pickup parameters from url expression

    webSvr.handle("/verify/:id", function(req, res) {
      var id =;

    Parse parameters in url

    * expression = /home/:key/:pager
    *   /home/JavaScript => { id: 'JavaScript', pager: '' }
    *   /key/JavaScript  => false 
    var params = webSvr.parseUrl(expression, reqUrl);

    Send API

    webSvr.send([type or statusCode, ] content);

    Send JSON

    webSvr.send('json', { a: 1, b: 2 });

    Send String

    webSvr.send(401, 'No permission');

    Multi-instance support

    Start a https server, make sure that the port will no conflict with others.

    var httpsSvr = new WebSvr({
        home: "./"
      //disable http server
      , port:      null
      //enable https server
      , httpsPort: 8443
      , httpsKey:  require("fs").readFileSync("svr/cert/privatekey.pem")
      , httpsCert: require("fs").readFileSync("svr/cert/certificate.pem")

    Do you want to re-use the filters & handlers?

    httpsSvr.filters   = webSvr.filters;
    httpsSvr.handlers  = webSvr.handlers;

    Store session in redis

    Install: npm install websvr-redis

    var RedisStore = require('websvr-redis');
        port: 6379
      , host: ''
      , auth: 'your-password-if-needed'
      , select: 0
    httpsSvr.sessionStore = RedisStore;

    Clear expired sessions, only 1 refresh timer is needed

    setInterval(RedisStore.clear, 1000000);


    MIT, see our license file

    Demo Sites

    1. ourjs: url
    2. icalc: url, source code github


    基于NodeJS的一个极简Web服务器, 专为ARM设计。 假设嵌入式设备需要保持长时间稳定运行,当遇到问题时也可自动重启并恢复此前用户的Session会话。


    npm i websvr

    DownloadsWeekly Downloads






    Last publish


    • newghost