Name: js-handler/node_modules/restify/lib/plugins/static.js 
1:
// Copyright 2012 Mark Cavage, Inc.  All rights reserved.
2:
 
3:
var fs = require('fs');
4:
var path = require('path');
5:
var escapeRE = require('escape-regexp-component');
6:
 
7:
var assert = require('assert-plus');
8:
var mime = require('mime');
9:
var errors = require('../errors');
10:
 
11:
 
12:
///--- Globals
13:
 
14:
var MethodNotAllowedError = errors.MethodNotAllowedError;
15:
var NotAuthorizedError = errors.NotAuthorizedError;
16:
var ResourceNotFoundError = errors.ResourceNotFoundError;
17:
 
18:
 
19:
 
20:
///--- Functions
21:
 
22:
function serveStatic(opts) {
23:
        opts = opts || {};
24:
        assert.object(opts, 'options');
25:
        assert.string(opts.directory, 'options.directory');
26:
        assert.optionalNumber(opts.maxAge, 'options.maxAge');
27:
        assert.optionalObject(opts.match, 'options.match');
28:
        assert.optionalString(opts.charSet, 'options.charSet');
29:
 
30:
        var p = path.normalize(opts.directory).replace(/\\/g, '/');
31:
        var re = new RegExp('^' + escapeRE(p) + '/?.*');
32:
 
33:
        function serveFileFromStats(file, err, stats, isGzip, req, res, next) {
34:
                if (err) {
35:
                        next(new ResourceNotFoundError(err,
36:
                                                req.path()));
37:
                        return;
38:
                } else if (!stats.isFile()) {
39:
                        next(new ResourceNotFoundError(req.path()));
40:
                        return;
41:
                }
42:
 
43:
                if (res.handledGzip && isGzip) {
44:
                    res.handledGzip();
45:
                }
46:
 
47:
                var fstream = fs.createReadStream(file + (isGzip ? '.gz' : ''));
48:
                var maxAge = opts.maxAge === undefined ? 3600 : opts.maxAge;
49:
                fstream.once('open', function (fd) {
50:
                        res.cache({maxAge: maxAge});
51:
                        res.set('Content-Length', stats.size);
52:
                        res.set('Content-Type', mime.lookup(file));
53:
                        res.set('Last-Modified', stats.mtime);
54:
                        if (opts.charSet) {
55:
                                var type = res.getHeader('Content-Type') +
56:
                                        '; charset=' + opts.charSet;
57:
                                res.setHeader('Content-Type', type);
58:
                        }
59:
                        if (opts.etag) {
60:
                                res.set('ETag', opts.etag(stats, opts));
61:
                        }
62:
                        res.writeHead(200);
63:
                        fstream.pipe(res);
64:
                        fstream.once('end', function () {
65:
                                next(false);
66:
                        });
67:
                });
68:
        }
69:
 
70:
        function serveNormal(file, req, res, next) {
71:
                fs.stat(file, function (err, stats) {
72:
                        if (!err && stats.isDirectory() && opts.default) {
73:
                                // Serve an index.html page or similar
74:
                                file = path.join(opts.directory, opts.default);
75:
                                fs.stat(file, function (dirErr, dirStats) {
76:
                                        serveFileFromStats(file,
77:
                                                           dirErr,
78:
                                                           dirStats,
79:
                                                           false,
80:
                                                           req,
81:
                                                           res,
82:
                                                           next);
83:
                                });
84:
                        } else {
85:
                                serveFileFromStats(file,
86:
                                                   err,
87:
                                                   stats,
88:
                                                   false,
89:
                                                   req,
90:
                                                   res,
91:
                                                   next);
92:
                        }
93:
                });
94:
        }
95:
 
96:
        function serve(req, res, next) {
97:
                var file = path.join(opts.directory,
98:
                                     decodeURIComponent(req.path()));
99:
 
100:
                if (req.method !== 'GET' && req.method !== 'HEAD') {
101:
                        next(new MethodNotAllowedError(req.method));
102:
                        return;
103:
                }
104:
 
105:
                if (!re.test(file.replace(/\\/g, '/'))) {
106:
                        next(new NotAuthorizedError(req.path()));
107:
                        return;
108:
                }
109:
 
110:
                if (opts.match && !opts.match.test(file)) {
111:
                        next(new NotAuthorizedError(req.path()));
112:
                        return;
113:
                }
114:
 
115:
                if (opts.gzip && req.acceptsEncoding('gzip')) {
116:
                    fs.stat(file + '.gz', function (err, stats) {
117:
                        if (!err) {
118:
                            res.setHeader('Content-Encoding', 'gzip');
119:
                            serveFileFromStats(file,
120:
                                                   err,
121:
                                                   stats,
122:
                                                   true,
123:
                                                   req,
124:
                                                   res,
125:
                                                   next);
126:
                        } else {
127:
                            serveNormal(file, req, res, next);
128:
                        }
129:
                    });
130:
                } else {
131:
                   serveNormal(file, req, res, next);
132:
                }
133:
 
134:
        }
135:
 
136:
        return (serve);
137:
}
138:
 
139:
module.exports = serveStatic;