UNPKG

thinknode

Version:

A fast, flexible and all-in-one web framework for node.js.

150 lines (119 loc) 4.93 kB
'use strict'; exports.__esModule = true; var _promise = require('babel-runtime/core-js/promise'); var _promise2 = _interopRequireDefault(_promise); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); var _path = require('path'); var _mime = require('mime'); var _mime2 = _interopRequireDefault(_mime); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _class = function (_THINK$Middleware) { (0, _inherits3.default)(_class, _THINK$Middleware); function _class() { (0, _classCallCheck3.default)(this, _class); return (0, _possibleConstructorReturn3.default)(this, _THINK$Middleware.apply(this, arguments)); } _class.prototype.init = function init(http) { this.http = http; this.options = { 'url_resource_on': THINK.config('url_resource_on'), 'url_resource_reg': THINK.config('url_resource_reg') }; }; _class.prototype.run = function run(data) { var pathname = this.http.pathname; if (!this.options.url_resource_on || !pathname || pathname === '/') { return _promise2.default.resolve(data); } try { pathname = decodeURIComponent(pathname).replace(/\\/g, '/'); } catch (e) { return _promise2.default.resolve(data); } pathname = (0, _path.normalize)(pathname); // replace \ to / on windows pathname = pathname.replace(/\\/g, '/'); //通过正则判断是否是静态资源请求 if (!this.options.url_resource_reg.test(pathname)) { return _promise2.default.resolve(data); } var file = (0, _path.normalize)(THINK.RESOURCE_PATH + '/' + pathname); if (file.indexOf(THINK.RESOURCE_PATH) !== 0) { return THINK.statusAction(this.http, 404); } //正则判断是否文件 //let urlReg = new RegExp(/[^\/]+\/([^\.]*)\/([^\/]+\.[^\/\.]+)$/); //if (!!file.match(urlReg)) { if (THINK.isFile(file)) { var contentType = _mime2.default.lookup(file); this.http.header('Content-Type', contentType + '; charset=' + THINK.config('encoding')); this.http.typesend = true; var range = this.http.header('range'); if (range) { return this.outputRange(file, range); } else { return this.outputNormal(file); } } else { return THINK.statusAction(this.http, 404); } }; /** * output normal file * @param {String} file [] * @return {Promise} [] */ _class.prototype.outputNormal = function outputNormal(file) { var _this2 = this; var fileStream = _fs2.default.createReadStream(file); fileStream.pipe(this.http.res); fileStream.on('end', function () { return THINK.statusAction(_this2.http, 200); }); fileStream.on('error', function (err) { return THINK.statusAction(_this2.http, 404, err); }); return THINK.prevent(); }; /** * output range file * @param {String} file [] * @param {String} range [] * @return {Promise} [] */ _class.prototype.outputRange = function outputRange(file, range) { //request has range header var size = _fs2.default.statSync(file).size; var match = range.match(/bytes=(\d+)\-(\d*)/); var slice = 1 * 1024 * 1024; var from = parseInt(match[1]) || 0; var to = parseInt(match[2]) || 0; if (!to) { to = from + slice - 1; } to = Math.min(to, size - 1); this.http.status(206); this.http.header('Accept-Ranges', 'bytes'); this.http.header('Content-Range', 'bytes ' + from + '-' + to + '/' + size); var fd = _fs2.default.openSync(file, 'r'); var buffer = new Buffer(to - from + 1); _fs2.default.readSync(fd, buffer, 0, to - from, from); _fs2.default.closeSync(fd); return this.http.end(buffer); }; return _class; }(THINK.Middleware); /** * 静态资源解析中间件 * @author richen * @copyright Copyright (c) 2015 - <richenlin(at)gmail.com> * @license MIT * @version 15/11/19 */ exports.default = _class;