// express.js
let http = require("http");
let url = require("url");
let fs = require("fs");
let path = require("path");
let methods = require("methods");
function Application() {
let app = (req, res) => {
let index = 0;
let { pathname } = url.parse(req.url, true);
let requestMethod = req.method.toLowerCase();
function next(err) {
if (index === app.routes.length) {
res.statusCode = 404;
return res.end(`Cannot ${requestMethod} ${pathname}`);
}
let { path, method, handler } = app.routes[index++];
if (err) {
if (method === "middleware" && handler.length === 4) {
return handler(err, req, res, next);
} else {
next(err);
}
} else {
if (method === "middleware") {
//路径相同可以匹配 路径是/可以匹配 路径开头也可以匹配
if (
pathname === path ||
path === "/" ||
pathname.startsWith(path + "/")
) {
return handler(req, res, next); // 将next的执行权交给用户,用户来决定是否向下执行
} else {
next();
}
} else {
if (path.params) {
let matches = pathname.match(path);
if (matches) {
let [, ...list] = matches;
req.params = path.params.reduce(
(acc, cur, idx) => ((acc[cur] = list[idx]), acc),
{}
);
return handler(req, res);
}
}
if (
((path === pathname || path === "*") && method === requestMethod) ||
method === "all"
) {
return handler(req, res);
}
}
next();
}
}
next();
};
app.routes = [];
[...methods, "all"].forEach(method => {
app[method] = (path, handler) => {
let params = [];
if (path.includes(":")) {
path = path.replace(/:([^/]+)/g, (...[, $1]) => {
params.push($1);
return "([^/]+)";
});
path = new RegExp(path);
path.params = params;
}
let layer = {
path,
method,
handler
};
app.routes.push(layer);
};
});
app.use = (path, handler) => {
if (typeof handler != "function") {
handler = path;
path = "/";
}
let layer = {
path,
method: "middleware",
handler
};
app.routes.push(layer);
};
app.listen = function() {
let server = http.createServer(app);
server.listen(...arguments);
};
// 内置中间件,每次请求时,都会先走这个中间件处理一下
app.use((req, res, next) => {
let url = require("url");
let { query, pathname } = url.parse(req.url, true);
req.query = query; // 格式化获取path和query
req.path = pathname;
res.send = value => {
//增强了res.end
if (typeof value === "object") {
res.setHeader("Content-Type", "application/json;charset=utf-8");
res.end(JSON.stringify(value));
} else if (typeof value === "number") {
res.statusCode = value;
let status = require("_http_server").STATUS_CODES;
res.end(status[value]);
} else if (typeof value === "string" || Buffer.isBuffer(value)) {
res.setHeader("Content-Type", "text/html;charset=utf-8");
res.end(value);
}
};
res.sendFile = p => {
// mime,处理文件类型
fs.createReadStream(p).pipe(res);
};
next();
});
return app;
}
//静态服务中间件 中间件的写法:高阶函数(函数返回一个函数)
Application.static = root => {
return (req, res, next) => {
let p = req.path;
let absPath = path.join(root, p);
fs.stat(absPath, (err, statObj) => {
if (err) {
return next();
}
if (statObj.isFile()) {
fs.createReadStream(absPath).pipe(res);
}
});
};
};
module.exports = Application;
网友评论