1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | var fs = require('fs');
|
24 | var trainjs = require('../lib/train.js');
|
25 | var http = require('http');
|
26 | var url = require('url');
|
27 | var exec = require('child_process').exec;
|
28 | var Fiber = require('fibers');
|
29 | var path = require('path');
|
30 |
|
31 |
|
32 | var global_v_init = trainjs.initServer();
|
33 |
|
34 | var pre_run_path = ROOT_APP + '/config/pre_run.js';
|
35 | var pre_run = fs.existsSync( pre_run_path );
|
36 |
|
37 | var app_config = require( ROOT_APP + '/config/application.js' );
|
38 | var ApplicationController = require( ROOT_APP + '/app/controllers/application_controller.js' );
|
39 |
|
40 |
|
41 | var app = require( ROOT_APP + '/app.js' );
|
42 |
|
43 | var beforeAction = function(req, res, next, class_object, action, before_action_i) {
|
44 | if (class_object['before_action']) {
|
45 | var before_action = class_object['before_action'][before_action_i];
|
46 | if (!before_action.only || before_action.only && before_action.only.indexOf(action) > -1) {
|
47 | if (class_object[before_action.action](req, res, next)) {
|
48 | return;
|
49 | }
|
50 |
|
51 | if (before_action_i < class_object['before_action'].length - 1) {
|
52 | before_action_i = before_action_i + 1;
|
53 | beforeAction(req, res, next, class_object, action, before_action_i);
|
54 | } else {
|
55 | class_object[action](req, res, next);
|
56 | }
|
57 | } else {
|
58 | class_object[action](req, res, next);
|
59 | }
|
60 | } else {
|
61 | class_object[action](req, res, next);
|
62 | }
|
63 | };
|
64 |
|
65 | function runServer() {
|
66 | app.use(function (req, res, next) {
|
67 | Fiber(function() {
|
68 | var url_parts = url.parse(req.url, true);
|
69 | req.query = url_parts.query;
|
70 |
|
71 | if ( app_config.cors ) {
|
72 | res.setHeader("Access-Control-Allow-Origin", "*");
|
73 | res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
|
74 | if (req.headers['access-control-request-headers'])
|
75 | res.setHeader("Access-Control-Allow-Headers", req.headers['access-control-request-headers']);
|
76 | }
|
77 |
|
78 | if ( req.method === 'OPTIONS' ) {
|
79 | res.end();
|
80 | } else {
|
81 | res.setHeader("Content-Type", "application/json");
|
82 | next();
|
83 | }
|
84 | }).run();
|
85 | });
|
86 |
|
87 | var application = new ApplicationController();
|
88 | app.use(application.before);
|
89 | trainjs.newServer(app, global_v_init);
|
90 |
|
91 | app.use(function (req, res, next) {
|
92 | var assets = ['image/', 'text/html', 'application/javascript', 'text/css', 'application/font'];
|
93 | var content_type = 'text/plain';
|
94 |
|
95 | if (req.headers.accept) {
|
96 | var headers_accept = req.headers.accept.split(',');
|
97 | content_type = headers_accept[0];
|
98 |
|
99 | for (var i in headers_accept) {
|
100 | if ( headers_accept[i].indexOf('text/plain') > -1 ) {
|
101 | content_type = 'text/html';
|
102 | }
|
103 | }
|
104 |
|
105 | if (req.headers['content-type'])
|
106 | content_type = req.headers['content-type'];
|
107 |
|
108 | if (content_type == '*/*' && /\.js$/.test(req.url)) {
|
109 | content_type = 'application/javascript';
|
110 | }
|
111 |
|
112 | if (/\.png$/.test(req.url)) {
|
113 | content_type = 'image/png';
|
114 | }
|
115 |
|
116 | if (content_type == '*/*' && /\.jpg$/.test(req.url)) {
|
117 | content_type = 'image/jpeg';
|
118 | }
|
119 | }
|
120 |
|
121 | var url_path = req.url.split('?')[0];
|
122 |
|
123 | var is_asset = false;
|
124 | for (var k in assets) {
|
125 | if ( content_type.indexOf(assets[k]) > -1 ) {
|
126 | is_asset = true;
|
127 | break;
|
128 | }
|
129 | }
|
130 |
|
131 | if ( url_path.indexOf('/node_modules/') > -1 && url_path.indexOf('../') < 0 ) {
|
132 | url_path = '..' + url_path;
|
133 | }
|
134 |
|
135 | var file_path = path.join(ROOT_APP, '/public', url_path);
|
136 | if (is_asset && fs.existsSync(file_path)) {
|
137 | if (url_path == '/') {
|
138 | fs.readFile(ROOT_APP + '/public/index.html', function(err, page) {
|
139 | res.writeHead(200, {'Content-Type': 'text/html'});
|
140 | res.write(page);
|
141 | res.end();
|
142 | });
|
143 | } else {
|
144 | fs.readFile(file_path, function(err, page) {
|
145 | res.writeHead(200, {'Content-Type': content_type});
|
146 | res.write(page);
|
147 | res.end();
|
148 | });
|
149 | }
|
150 | } else {
|
151 | file_path = path.join(ROOT_APP, '', url_path);
|
152 | if (fs.existsSync(file_path)) {
|
153 | try {
|
154 | var stats = fs.lstatSync(file_path);
|
155 | if (stats.isDirectory()) {
|
156 | var index_file = file_path + '/index.html';
|
157 | if (fs.existsSync(index_file)) {
|
158 | if (url_path[url_path.length - 1] != '/') {
|
159 | res.writeHead(301, {'Location': url_path + '/'});
|
160 | res.end();
|
161 | } else {
|
162 | fs.readFile(index_file, function(err, page) {
|
163 | res.writeHead(200, {'Content-Type': 'text/html'});
|
164 | res.write(page);
|
165 | res.end();
|
166 | });
|
167 | }
|
168 | } else {
|
169 | res.end();
|
170 | }
|
171 | } else {
|
172 | if (is_asset) {
|
173 | fs.readFile(file_path, function(err, page) {
|
174 | res.writeHead(200, {'Content-Type': content_type});
|
175 | res.write(page);
|
176 | res.end();
|
177 | });
|
178 | } else {
|
179 | res.end();
|
180 | }
|
181 | }
|
182 | }
|
183 | catch (e) {
|
184 | console.log(e);
|
185 | }
|
186 | } else {
|
187 | var routes = global_v_init.routes;
|
188 | var controllers = global_v_init.controllers;
|
189 | var is_route = false;
|
190 |
|
191 | for (var k in ROUTE_PATTERNS) {
|
192 | var pattern = ROUTE_PATTERNS[k].pattern;
|
193 | var method = ROUTE_PATTERNS[k].method;
|
194 | var resource = ROUTE_PATTERNS[k].resource;
|
195 | var action = ROUTE_PATTERNS[k].action;
|
196 |
|
197 | if (pattern.matches(req.url) && method.toLowerCase() == req.method.toLowerCase()) {
|
198 | var params = pattern.match(req.url);
|
199 | req.params = params.namedParams;
|
200 | try {
|
201 | var class_object = new controllers[resource]();
|
202 | beforeAction(req, res, next, class_object, action, 0);
|
203 | is_route = true;
|
204 | break;
|
205 | } catch(e) {
|
206 | console.log( 'Error: '.bold.red + e );
|
207 | res.end();
|
208 | }
|
209 | }
|
210 | }
|
211 |
|
212 | if (!is_route)
|
213 | next();
|
214 | }
|
215 | }
|
216 | });
|
217 |
|
218 | var port = '1337';
|
219 | if (process.env.PORT) {
|
220 | port = process.env.PORT;
|
221 | } else {
|
222 | var port_param_index = process.argv.indexOf("-p");
|
223 | var isNormalInteger = function (str) {
|
224 | var n = ~~Number(str);
|
225 | return String(n) === str && n >= 0;
|
226 | };
|
227 | if ( port_param_index > -1 && process.argv[ port_param_index + 1 ] && isNormalInteger( process.argv[ port_param_index + 1 ] ) ) {
|
228 | port = process.argv[ port_param_index + 1 ];
|
229 | }
|
230 | }
|
231 |
|
232 | http.createServer(app).listen(port);
|
233 | console.log('=> Server running at http://0.0.0.0:' + port + '\n=> Ctrl-C to shutdown server');
|
234 | }
|
235 |
|
236 | if ( pre_run ) {
|
237 | var cmd = require( pre_run_path );
|
238 | console.log('=> Run config/pre_run.js');
|
239 | exec(cmd, function (error, stdout, stderr) {
|
240 | if (error) console.log(error);
|
241 | else {
|
242 | PRE_RUN_STDOUT = stdout;
|
243 | runServer();
|
244 | }
|
245 | });
|
246 | } else {
|
247 | runServer();
|
248 | }
|