1 | var fs = require('fs'),
|
2 | path = require('path'),
|
3 | union = require('union'),
|
4 | ecstatic = require('ecstatic'),
|
5 | httpProxy = require('http-proxy'),
|
6 | corser = require('corser'),
|
7 | colors = require('colors'),
|
8 | logger = require('../util/logger'),
|
9 | util = require('../util/util'),
|
10 | php_fpm = require('./lib/php-fpm'),
|
11 | contentTypesMap = require('./lib/contentType'),
|
12 | findSimilarFile = require('./lib/findSimilarFile');
|
13 |
|
14 | exports.HttpServer = exports.HTTPServer = HttpServer;
|
15 |
|
16 | exports.createServer = function (options) {
|
17 | return new HttpServer(options);
|
18 | }
|
19 |
|
20 | function HttpServer(options) {
|
21 | options = options || {};
|
22 | this.root = options['root']
|
23 | this.headers = options.headers || {}
|
24 | this.contentType = options.contentType || 'application/octet-stream'
|
25 |
|
26 | this.headers['Access-Control-Allow-Origin'] = '*';
|
27 | this.headers['Access-Control-Allow-Credentials'] = true;
|
28 | this.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Range';
|
29 |
|
30 | var before = options.before ? options.before.slice() : []
|
31 |
|
32 |
|
33 | before.push(function (req, res, next) {
|
34 | var err
|
35 | try {
|
36 | logger.http(req, res);
|
37 | } catch(ex) {
|
38 | ex.status = 503
|
39 | err = ex
|
40 | }
|
41 | next(err)
|
42 | })
|
43 |
|
44 |
|
45 | if(options['php']){
|
46 | var php = new php_fpm({
|
47 | documentRoot: path.resolve(process.cwd(), this.root)
|
48 | });
|
49 | before.push(function (req, res, next) {
|
50 | var err;
|
51 | if(util.getFileExtension(req.url) == 'php') {
|
52 | try {
|
53 | php.run(req, function(phpParseErr, output){
|
54 | if(output && output.indexOf('<b>Parse error</b>') > -1){
|
55 | if(!phpParseErr){
|
56 | phpParseErr = {}
|
57 | }
|
58 | if(!phpParseErr['stack']){
|
59 | phpParseErr['stack'] = output
|
60 | }
|
61 | }
|
62 | if(!phpParseErr){
|
63 | res.setHeader('Content-Type', 'text/html');
|
64 | res.write(output, "utf-8");
|
65 | return res.end()
|
66 | } else {
|
67 | phpParseErr.status = 503
|
68 | next(phpParseErr)
|
69 | }
|
70 | })
|
71 | } catch(ex) {
|
72 | ex.status = 503
|
73 | err = ex
|
74 | next(err)
|
75 | }
|
76 | } else {
|
77 | next(err)
|
78 | }
|
79 | })
|
80 | }
|
81 |
|
82 |
|
83 | before.push(function (req, res) {
|
84 | if (req.url === '/favicon.ico') {
|
85 | var icoPath = path.resolve( __dirname, './assets/images/favicon.ico' )
|
86 | res.setHeader('Content-Type', 'image/x-icon');
|
87 | res.write(fs.readFileSync(icoPath, "binary"), "binary");
|
88 | return res.end()
|
89 | }
|
90 | res.emit('next');
|
91 | });
|
92 |
|
93 |
|
94 | before.push(ecstatic({
|
95 | root: this.root,
|
96 | cache: 1,
|
97 | showDir: true,
|
98 | autoIndex: true,
|
99 | gzip: false,
|
100 | contentType: this.contentType,
|
101 | handleError: typeof options.proxy !== 'string'
|
102 | }));
|
103 |
|
104 |
|
105 | if (options.proxy && typeof options.proxy === 'string') {
|
106 | var proxy = httpProxy.createProxyServer({});
|
107 | proxy.on('error', function (err, req, res){})
|
108 | proxy.on('proxyRes', function (proxyRes, req, res) {
|
109 | console.log('proxy ', res['statusCode'], req.url)
|
110 | })
|
111 | before.push(function (req, res) {
|
112 | proxy.web(req, res, {
|
113 | target: options.proxy,
|
114 | changeOrigin: true
|
115 | })
|
116 | })
|
117 | }
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 | var unionOptions = {
|
131 | before: before,
|
132 | headers: this.headers,
|
133 | onError: function (err, req, res) {
|
134 | if(err.status == 404){
|
135 | var cwd = process.cwd()
|
136 | var filePath = cwd + req.url;
|
137 | var similarFile = findSimilarFile(filePath)
|
138 | if(similarFile){
|
139 | res.writeHead(200, {})
|
140 | let fileContent = fs.readFileSync(similarFile['pathName'], 'utf-8');
|
141 | res.write(fileContent, "utf-8");
|
142 | err['transfer-url'] = similarFile['pathName'].replace(cwd, '')
|
143 | logger.http(req, res, err)
|
144 | return res.end()
|
145 | } else {
|
146 | logger.http(req, res, err)
|
147 | return require('./lib/page/index.js')(404, req, res, err);
|
148 | }
|
149 | }
|
150 | logger.http(req, res, err)
|
151 | return require('./lib/page/index.js')(503, req, res, err);
|
152 | }
|
153 | }
|
154 | if (options.ssl) {
|
155 | unionOptions.https = {
|
156 | cert: path.resolve(__dirname, './assets/pem/cert.pem'),
|
157 | key: path.resolve(__dirname, './assets/pem/key.pem')
|
158 | }
|
159 | }
|
160 | this.server = union.createServer(unionOptions)
|
161 | }
|
162 |
|
163 | HttpServer.prototype.listen = function () {
|
164 | this.server.listen.apply(this.server, arguments)
|
165 | }
|
166 |
|
167 | HttpServer.prototype.close = function () {
|
168 | return this.server.close()
|
169 | }
|