fixing a purl so it uses the start of the url for the pathname
[nodejsws.git] / lib / wsrequest.js
1 var url = require("url");
2 var path = require("path");
3 var fs = require("fs");
4 //var myparse = require("./myparse.js");
5 var webmain = require("./webmain.js");
6 var layouts = require("./layouts.js");
7
8 // global stuff
9 var extraCss = new Array();
10 var extraJs = new Array();
11 //var defaultLayout = null;
12 var defaultMainPurl = null;
13
14 //var staticExtensions = ["html", "gif", "jpg", "css", "js", "ico"];
15
16 function wsRequest(request, response) {
17         var isStatic = 0;
18         var purl = url.parse(request.url);
19         
20         /*staticExtensions.forEach(function testExtn(setest) {
21                 console.log("testing url: ", request.url);
22                 console.log("against: ", purl.pathname);
23                 var chk = purl.pathname.split(".");
24                 console.log("chk: ", chk);
25                 var chkid = staticExtensions.indexOf(chk[chk.length-1].toLowerCase());
26                 console.log("chkid is ", chkid);
27                 if(chkid != -1) {
28                         isStatic = 1;
29                 }
30         });*/
31         
32         // if the end of the pathname is something.something, we assume static
33         var lpath = purl.pathname.split("/").pop();
34         var idx = lpath.indexOf(".");
35         console.log("testing url: ", request.url);
36         console.log("against: ", purl.pathname);
37         console.log("lpath is: '%s'", lpath);
38         console.log("type is: '%s'", typeof lpath);
39         console.log("idx is: ", idx);
40         
41         if(idx > 0) isStatic = 1;
42         
43         if(isStatic == 1) {
44                 // do the static
45                 console.log("Service as static");
46                 serveStatic(lpath, response);
47                 return;
48         }
49         
50         //console.log("request: ", request);
51         console.log("purl: ", purl);
52
53         // now we need to find the extension used
54         // to serve the request based no the first purl
55         
56         
57         /*
58          * 
59         if(purl.pathname == "/") {
60                 console.log("Serv main");
61                 webmain.serveMain(request, response, function (request, response) {
62                         response.end();
63                 });
64                 return;
65         }
66
67         var thispurl = purl.pathname.split("/")[1];
68         fs.stat("./purls/web_"+thispurl+".js", function (err, stats) {
69                 console.log("get purl is "+thispurl+" and err "+err+" and "+stats);
70                 if(err) {
71                         response.writeHead(404, {"Content-Type": "text/plain"});
72                         response.write("404 Not Found\n");
73                         response.end();
74                         return;
75                 }
76                 var thiserv = require("../purls/web_"+thispurl+".js");
77                 if(thiserv.requireBody()) {
78                         console.log("yubber is true");
79                         webmain.serveBody(request, response, thiserv.process);
80                 } else {
81                         console.log("yubber is false");
82                         thiserv.process(request, response, function(request, response) {
83                                 response.end();
84                         });
85                 }
86                 return;
87         });
88         */
89         
90         urlServicer(request, response, purl);
91         
92         
93         return;
94 }
95
96 function urlServicer(request, response, purl) {
97         console.log("url servicer called for ", purl);
98         
99         // first resolve the module making the call and determine layout/purl
100         var purlClass = layouts;
101         var purlLayout = layouts.standard();
102         var mainPath = "";
103         
104         if(typeof global.njspurls.mainPath != "undefined") {
105                 mainPath = global.njspurls.mainPath;
106                 console.log("gettingmainpath from global: ", mainPath);
107         } else {
108                 mainPath = path.dirname(require.main.filename) + "/purls/";
109         }
110
111         console.log("main purl path is ", mainPath);
112         
113         if(purl.pathname == "/") {
114                 if(defaultMainPurl == null) {
115                         console.log("set purl class to layouts");
116
117                         var mainPurlClassPath = mainPath+"/main.js";
118                         console.log("attempting to load main.js as the main purl class");
119                         try {
120                                 var mainPurlClass = require(mainPurlClassPath);
121                                 purlClass = mainPurlClass;
122                                 console.log("main.js exists");
123                         } catch(err) {
124                                 console.log("main.js doesnt exist, using default");
125                         }
126                 } else {
127                         // find and load the purl, we'll use main.js
128                         var mainPurlClassPath = mainPath+"/"+defaultMainPurl+".js";
129                         
130                         console.log("attempting to load main.js as the main purl class");
131                         try {
132                                 var mainPurlClass = require(mainPurlClassPath);
133                                 purlClass = mainPurlClass;
134                                 console.log("main.js exists");
135                         } catch(err) {
136                                 console.log("main.js doesnt exist, using default");
137                         }
138                 }
139         } else {
140                 // handle the purls... we taje the pathname, drop the beginning "/", then drop every after the next "/"
141                 // so we end up with a purl of "abcd" from a url:
142                 // http://host/abcd/qewr/asdf/asdf/asdf/asdf/asdf/
143                 // and will load mainPath/abcd.js
144                 var newPurlPath = mainPath+"/"+path.basename(purl.pathname.replace(/^\//, "").replace(/\/.*$/, ""))+".js";
145                 console.log("attempting to require: ", newPurlPath);
146                 try {
147                         var newPurlClass = require(newPurlPath);
148                         purlClass = newPurlClass;
149                 } catch(err) {
150                         console.log("tried to load '%s' for request '%s', but this has failed, returning 302 to /", newPurlPath, purl.pathname);
151                         response.writeHead("302", { 'Location': '/' });
152                         response.end();
153                         return;
154                 }
155         }
156
157         if(typeof purlClass.layout == "undefined") {
158                 console.log("set via undefined");
159                 purlLayout = layouts.standard();
160         } else {
161                 // find and resolve the layout
162                 purlLayout = purlClass.layout();
163         }
164         
165         // now we should have a layout and a class
166         if(typeof purlClass.preResponse != "undefined") {
167                 purlClass.preResponse(request, response, function() {
168                         serviceLayout(request, response, purlClass, purlLayout);                        
169                 });
170         } else {
171                 serviceLayout(request, response, purlClass, purlLayout);
172         }
173         
174         return;
175 }
176
177 function serviceLayout(request, response, purlClass, purlLayout) {
178         var reallay = "start:"+purlLayout+":end";
179         var splitup = reallay.split("<?njs");
180         var offset=0;
181
182         console.log("inservicer: ", purlLayout);
183         
184         function processLayout() {
185                 var output = "";
186                 
187                 console.log("begin process layout");
188                 
189                 if(offset >= splitup.length) {
190                         //response.write("end of caller");
191                         response.end();
192                         return;
193                 } else if(offset == 0) {
194                         console.log("write for offset 0");
195                         output = splitup[0].replace(/^start:/g, "");
196                         if(splitup.length == 1) output = output.replace(/:end$/g, "");
197                         console.log("did write: ", output);
198                         response.write(output);
199                         offset++;
200                         processLayout();
201                 } else {
202                         var thispart = splitup[offset].split("?>");
203                         var caller = thispart[0].trim();
204                         
205                         console.log("in parts for bits: ", thispart);
206                         console.log("and caller is: ", caller);
207                         
208                         // here we resolve and call the caller....
209                         //response.write("calling: " + caller);
210                         resolveAndCall(request, response, caller, purlClass, function () {
211                                 output = thispart[1].replace(/:end$/g, "");
212                                 response.write(output);
213                                 offset++;
214                                 processLayout();
215                         });
216                 }
217         }
218         
219         processLayout();
220         
221         //response.write("servicer");
222         //response.end();
223 }
224
225 function resolveAndCall(request, response, caller, purlClass, callback) {
226         //response.write("resolving: \"" + caller + "\"");
227         
228         // TODO: do this properly.
229         if(typeof purlClass[caller] != "undefined") {
230                 purlClass[caller](request, response, callback);
231         } else if(typeof layouts[caller] != "undefined"){
232                 layouts[caller](request, response, callback);
233         } else {
234                 response.write("<!-- ERROR:Undefined layout section -->");
235                 callback();
236         }
237         //callback();
238         return;
239 }
240
241 function serveStatic(staticname, response) {
242         var pathName = "";
243         if(typeof global.njspurls.mainResPath != "undefined") {
244                 pathName = global.njspurls.mainResPath + "/" + staticname;
245         } else {
246                 pathName = "./res/"+staticname;
247         }
248         console.log("Pathname for check is ", pathName);
249         fs.exists(pathName, function(exists) {
250                 if(!exists) {
251                         response.writeHead(404, {"Content-Type": "text/plain"});
252                         response.write("404 Not Found\n");
253                         response.end();
254                         return;
255                 }
256                 
257                 fs.readFile(pathName, "binary", function(err, file) {
258                         if(err) {        
259                                 response.writeHead(500, {"Content-Type": "text/plain"});
260                                 response.write(err + "\n");
261                                 response.end();
262                                 return;
263                         }
264
265                         response.writeHead(200);
266                         response.write(file, "binary");
267                         response.end();                 
268                 });
269         });
270 }
271
272 exports.wsRequest = wsRequest;