1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | var fs = require('fs'),
|
9 | path = require('path'),
|
10 | http = require('http');
|
11 |
|
12 | function gsub(source, pattern, replacement) {
|
13 | var match, result;
|
14 | if (!((pattern !== null) && (replacement !== null))) {
|
15 | return source;
|
16 | }
|
17 | result = '';
|
18 | while (source.length > 0) {
|
19 | if ((match = source.match(pattern))) {
|
20 | result += source.slice(0, match.index);
|
21 | result += replacement;
|
22 | source = source.slice(match.index + match[0].length);
|
23 | } else {
|
24 | result += source;
|
25 | source = '';
|
26 | }
|
27 | }
|
28 | return result;
|
29 | }
|
30 |
|
31 | function replaceScSuperCalls(str) {
|
32 | return gsub(str, /sc_super\(\)/, "arguments.callee.base.apply(this, arguments)");
|
33 | }
|
34 |
|
35 | BT.LOG_SERVING = false;
|
36 |
|
37 | BT.Server = BT.Object.extend({
|
38 |
|
39 | hostname: '127.0.0.1',
|
40 | port: 4020,
|
41 | project: null,
|
42 | _bt_server: null,
|
43 |
|
44 | init: function() {
|
45 | arguments.callee.base.apply(this, arguments);
|
46 | var project = this.get('project'),
|
47 | hostname = this.get('hostname'),
|
48 | port = this.get('port');
|
49 |
|
50 | this._bt_server = http.createServer(function (req, res) {
|
51 | var url = path.normalize(req.url);
|
52 | var start = new Date().getTime();
|
53 |
|
54 |
|
55 | if (url === "/") {
|
56 | res.writeHead(200, {'Content-Type': 'text/html'});
|
57 | res.end(project.get('indexHTML'));
|
58 | } else {
|
59 | var ary = url.slice(1).split('/');
|
60 |
|
61 | if (ary.length === 1) {
|
62 |
|
63 | var appName = ary[0],
|
64 | app = project.findApp(appName);
|
65 |
|
66 | if (app) {
|
67 | res.writeHead(200, {'Content-Type': 'text/html'});
|
68 | res.end(app.get('indexHTML'));
|
69 | } else {
|
70 | res.writeHead(200, {'Content-Type': 'text/plain'});
|
71 | res.end("You asked to load '"+appName+"' which is not an app in this project.");
|
72 | }
|
73 |
|
74 | } else {
|
75 | var idx, len, node = project, part;
|
76 | for (idx=0, len=ary.length; idx<len; ++idx) {
|
77 | part = ary[idx];
|
78 |
|
79 | node = node.get(part);
|
80 | if (node) {
|
81 | if (idx !== (len-1) && node.get('isBuildNode')) continue;
|
82 | else if (idx === (len-1) && node.get('isFile')) continue;
|
83 | else {
|
84 | console.log("failed to get a valid node at "+part);
|
85 | node = undefined;
|
86 | break;
|
87 | }
|
88 | }
|
89 | else {
|
90 | console.log("failed to get a node at "+part);
|
91 | break;
|
92 | }
|
93 | }
|
94 |
|
95 | if (node) {
|
96 |
|
97 | var sourcePath = node.get('sourcePath'),
|
98 | mimeType = node.get('mimeType');
|
99 | if (!mimeType) {
|
100 | fs.readFile(sourcePath, "utf-8", function(error, content) {
|
101 | if (error) {
|
102 | res.writeHead(500);
|
103 | res.end(error.toString());
|
104 | } else {
|
105 | res.writeHead(200, {'Content-Type': 'application/javascript'});
|
106 | var superCalls = new Date().getTime();
|
107 | content = replaceScSuperCalls(content);
|
108 | var end = new Date().getTime();
|
109 | if (BT.LOG_SERVING) console.log(sourcePath, (end-start)+'ms read', '('+(end-superCalls)+'ms process)');
|
110 | res.end(content, 'utf-8');
|
111 | }
|
112 | });
|
113 | } else {
|
114 | fs.readFile(sourcePath, "binary", function(error, content) {
|
115 | if (error) {
|
116 | res.writeHead(500);
|
117 | res.end(error.toString());
|
118 | } else {
|
119 | res.writeHead(200, {'Content-Type': node.get('mimeType')});
|
120 | res.end(content, 'binary');
|
121 | }
|
122 | });
|
123 | }
|
124 | } else {
|
125 | res.writeHead(200, {'Content-Type': 'text/plain'});
|
126 | res.end("That file does not exist.");
|
127 | }
|
128 | }
|
129 | }
|
130 | }).listen(port, hostname);
|
131 | console.log('Server running at http://'+hostname+':'+port+'/');
|
132 | }
|
133 |
|
134 | });
|