KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > servlet > servscan


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.servlet;
11
12 import java.util.*;
13 import java.io.*;
14 import javax.servlet.*;
15 import javax.servlet.http.*;
16
17
18 import org.mmbase.util.*;
19 import org.mmbase.module.*;
20 import org.mmbase.module.core.*;
21 import org.mmbase.module.gui.html.*;
22
23 import org.mmbase.util.logging.Logger;
24 import org.mmbase.util.logging.Logging;
25
26 /**
27  * servscan is the 'extended html language' (parsing *.shtml) provided for MMbase its a system like
28  * php3, asp or jsp but has its roots providing a simpler toolset for Interaction
29  * designers and gfx designers. It is provided as an option but not demanded, you can
30  * also use JSP for a more traditional parser system.
31  *
32  * @rename Servscan
33  * @version $Id: servscan.java,v 1.45 2006/03/09 16:39:20 michiel Exp $
34  * @author Daniel Ockeloen
35  * @author Rico Jansen
36  * @author Jan van Oosterom
37  * @author Rob Vermeulen
38  */

39 public class servscan extends JamesServlet {
40     private static Logger log;
41
42     // modules used in servscan
43
private static sessionsInterface sessions=null;
44     private scanparser parser;
45
46     public static final String JavaDoc SHTML_CONTENTTYPE = "text/html";
47     public static final String JavaDoc DEFAULT_CHARSET = "UTF-8"; // can be overriden by parameter 'encoding' (in web.xml)
48

49     protected String JavaDoc charSet = DEFAULT_CHARSET;
50
51     /**
52      * Initialize this servlet
53      */

54     public void init() throws ServletException {
55         super.init();
56         String JavaDoc encodingParameter = getInitParameter("encoding");
57         if (encodingParameter != null) {
58             charSet = encodingParameter;
59         }
60     }
61
62
63     public void setMMBase(MMBase mmb) {
64         super.setMMBase(mmb);
65
66         // bugfix #6648: scan.init() is not called, this will sometimes result in a crash of mmbase
67
log = Logging.getLoggerInstance(servscan.class);
68
69         try {
70             MMBaseContext.initHtmlRoot();
71         } catch (Exception JavaDoc e){
72             log.error(e);
73         }
74         log.info("Getting scan parser");
75         parser = (scanparser)getModule("SCANPARSER");
76         if(parser == null) {
77             String JavaDoc msg = "Module with name 'scanparser' should be active";
78             log.error(msg);
79             throw new RuntimeException JavaDoc(msg);
80         }
81         sessions = (sessionsInterface)getModule("SESSION");
82         if(sessions == null) {
83             String JavaDoc msg = "module with name 'sessions' is not active";
84             log.warn(msg);
85         }
86     }
87
88     /**
89      * Adds charSet to mimetype given by SHTML_CONTENTTYPE for handling
90      * of the charset used by the database
91      */

92     private String JavaDoc addCharSet(String JavaDoc mimetype) {
93         if (mimetype.equals(SHTML_CONTENTTYPE)) {
94             return mimetype + "; charset=\"" + charSet + "\"";
95         } else {
96             return mimetype;
97         }
98     }
99
100     /**
101      * handle_line is called by service to parse the SHTML in body.
102      * It can be used by children to do their own parsing. The default
103      * implementation calls parser.handle_line (from module scanparser)
104      * to do the parsing.
105      */

106     protected String JavaDoc handle_line(String JavaDoc body, sessionInfo session, scanpage sp) throws ParseException {
107         return parser.handle_line(body, session, sp);
108     }
109
110     /**
111      * Servlet request service.
112      * This processes the the page and sends it back
113      */

114     public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
115         if (!checkInited(res)) {
116             return;
117         }
118         if (parser == null) {
119             throw new ServletException("No scan parser for request " + req.getRequestURI());
120         }
121
122
123         incRefCount(req);
124         try {
125
126             // pageLog.service("Parsing SCAN page: " + req.getRequestURI());
127

128             scanpage sp = new scanpage(this, req, res, sessions);
129
130             // POST
131
if (req.getMethod().equals("POST")) {
132                 handlePost(sp, res);
133             }
134
135             // Generate page
136
PrintWriter out = null;
137
138             do {
139                 sp.rstatus = 0;
140                 sp.body = parser.getfile(sp.req_line);
141
142                 if (log.isDebugEnabled()) {
143                     log.trace("body :" + sp.body);
144                 }
145                 if (!doCrcCheck(sp,res)) {
146                     throw new PageCRCException("invalid crc");
147                 }
148                 doSecure(sp, res); // name=doSecure(sp,res); but name not used here
149
long stime = handleTime(sp);
150                 try {
151                     if (handleCache(sp, res, out)) return;
152                 } catch (Exception JavaDoc e) {
153                     log.error("servscan - something is wrong with scancache: " + e.getClass().getName() + " " + e.getMessage());
154                     log.service(Logging.stackTrace(e));
155                 }
156
157                 if (log.isDebugEnabled()) {
158                     log.trace("body " + sp.body);
159                 }
160
161                 if (sp.body != null && !sp.body.equals("")) {
162                     // Process HTML
163
sp.body = handle_line(sp.body, sp.session, sp);
164                     // Send data back
165
if (sp.body != null) {
166                         if (sp.rstatus == 0) { // ok
167
sp.mimetype = addCharSet(sp.mimetype);
168                             //res.reset();
169
res.setContentType(sp.mimetype);
170                             if (out == null) {
171                                 out = res.getWriter();
172                             }
173                             out.print(sp.body);
174                             handleCacheSave(sp, res);
175                         } else if (sp.rstatus == 1) {
176                             res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); // 302, "OK" ??
177
res.setContentType(addCharSet(sp.mimetype));
178                             if (out == null) {
179                                 out = res.getWriter();
180                             }
181                             res.setHeader("Location", sp.body);
182                         } else if (sp.rstatus == 2) { // 'new page'
183
sp.req_line = sp.body;
184                             if (sp.req_line.indexOf('\n') !=- 1) {
185                                 sp.req_line = sp.req_line.substring(0 ,sp.req_line.indexOf('\n'));
186                             }
187                         } else if (sp.rstatus == 4) {
188                             String JavaDoc tmp = req.getHeader("If-Modified-Since:");
189                             if (tmp != null && sp.processor != null) {
190                                 res.setStatus(HttpServletResponse.SC_NOT_MODIFIED); // 304, "Not Modified"
191
res.reset();
192                                 res.setContentType(addCharSet(sp.mimetype));
193                                 if (out == null) {
194                                     out = res.getWriter();
195                                 }
196                             } else {
197                                 // last-modification date and expire will be set to default
198
setHeaders(sp, res, sp.body,0,0);
199                                 if (out == null) {
200                                     out = res.getWriter();
201                                 }
202                                 out.print(sp.body);
203                             }
204                         }
205                     } else {
206                         sp.body = "<TITLE>Servscan</TITLE>handle_line returned null<BR>";
207                         // last-modification date and expire will be set to default
208
setHeaders(sp, res, sp.body,0,0);
209                         if (out == null) {
210                             out = res.getWriter();
211                         }
212                         out.print(sp.body);
213                     }
214                 } else {
215                     break;
216                 }
217
218                 if (out == null) {
219                     out = res.getWriter();
220                 }
221
222                 if (stime != -1) {
223                     stime = System.currentTimeMillis()-stime;
224                     if (log.isDebugEnabled()) {
225                         log.debug("service(" + getRequestURL(req) + "): STIME " + stime + "ms " + (stime/1000) + "sec");
226                     }
227                 }
228             } while (sp.rstatus == 2);
229             // End of page parser
230
// pageLog.debug("END parsing SCAN page");
231
out.flush();
232             //out.close();
233
} catch(NotLoggedInException e) {
234             log.debug("service(): page(" + getRequestURL(req) + "): NotLoggedInException: ");
235         } catch(PageCRCException e) {
236             log.warn("service(): page(" + getRequestURL(req) + "): Invalid CRC");
237         } catch(Exception JavaDoc a) {
238             log.debug("service(): exception on page: " + getRequestURL(req));
239             a.printStackTrace();
240         } finally {
241             decRefCount(req);
242         }
243
244     }
245
246     /**
247      * Set some generic headers for the response based on the scanpage
248      * This method is 3 times as large as it could be, this should be cleaned!
249      * @param len String which will be used to determin the length of the response
250      */

251     private final void setHeaders(scanpage sp, HttpServletResponse res, String JavaDoc len, long lastModDate, long expireDate) {
252         res.reset();
253
254         res.setContentType(addCharSet(sp.mimetype));
255
256
257         // Guess this will be set by the app server if we don't set it.
258
// mm: guessed wrong.
259
if (sp.mimetype.equals(SHTML_CONTENTTYPE)) {
260             try {
261                 res.setContentLength(len.getBytes(charSet).length);
262             } catch (java.io.UnsupportedEncodingException JavaDoc uee) {
263                 // could not happen
264
}
265         } else {
266             res.setContentLength(len.getBytes().length);
267         }
268
269
270
271         Date lastmod = null;
272         if (lastModDate > 0) {
273             lastmod = new Date(lastModDate);
274         } else {
275             lastmod = new Date(); //current time
276
}
277         Date expire = null;
278         if (expireDate > 0) {
279             expire = new Date(expireDate);
280         } else {
281             // 2 hours back in time. So it will expire at once?
282
expire = new Date(System.currentTimeMillis() - 7200000);
283         }
284
285         // String dateStr = RFC1123.makeDate(new Date());
286
String JavaDoc lastmodStr = RFC1123.makeDate(lastmod);
287         String JavaDoc expireStr = RFC1123.makeDate(expire);
288
289         if (log.isDebugEnabled()) {
290             log.debug("Set headers for URL: " + sp.req_line + "\nExpires: " + expireStr + "\nLast-Modified: " + lastmodStr );
291         }
292
293         res.setHeader("Expires", expireStr);
294         res.setHeader("Last-Modified", lastmodStr);
295         // res.setHeader("Date", dateStr);
296

297         // You shouldn't set the no-cache headers
298
// when you want the browser and proxies to cache the page until it is expired
299
// otherwise it will go through the proxies to MMBase.
300

301         // res.setHeader("Cache-Control"," no-cache");
302
// res.setHeader("Pragma", "no-cache");
303
}
304
305     public String JavaDoc getServletInfo() {
306         return "extended html parser that adds extra html commands and a interface to modules.";
307     }
308
309     void handlePost(scanpage sp, HttpServletResponse res) throws Exception JavaDoc {
310         String JavaDoc rtn, part, part2, finals, tokje, header;
311         Hashtable proc_cmd = new Hashtable();
312         Hashtable proc_var = new Hashtable();
313         Object JavaDoc obj;
314         HttpServletRequest req = sp.req;
315         HttpPost poster = new HttpPost(req);
316         sp.poster = poster;
317         String JavaDoc name=null;
318
319         // first check if it has a secure tag.
320
String JavaDoc sec = poster.getPostParameter("SECURE");
321
322         if (sec != null) {
323             if (log.isDebugEnabled()) log.debug("handlePost(" + sp.getUrl() + "): Secure tag found, displaying username/password window at client-side.");
324             name = getAuthorization(req, res);
325             if (log.isDebugEnabled()) log.debug("handlePost(" + sp.getUrl() + "): getting cookie to check name");
326             String JavaDoc sname = getCookie(req, res);
327             if (name == null) {
328                 log.debug("handlePost(): Warning Username is null");
329                 return;
330             }
331         }
332
333         // Process method=post information
334
for (Enumeration t = poster.getPostParameters().keys(); t.hasMoreElements(); ) {
335             obj = t.nextElement();
336             part = (String JavaDoc)obj;
337             if (part.indexOf("SESSION-") == 0) {
338                 if (sp.session != null) {
339                     if (poster.checkPostMultiParameter((String JavaDoc)obj)) {
340                         // MULTIPLE SUPPORT
341
sessions.addSetValues(sp.session, part.substring(8), poster.getPostMultiParameter((String JavaDoc)obj));
342                     } else {
343                         sessions.setValue(sp.session, part.substring(8), poster.getPostParameter((String JavaDoc)obj));
344                     }
345                 }
346                 // Personal objects
347
} else if (part.indexOf("ID-") == 0) {
348                 //SESSION HACK getAuthorization(req.getAcceptor(),"Basic");
349
//aaaa name=getRemoteUser();
350
//name check
351
if (name == null) {
352                     log.debug("handlePost(): Warning Username is null");
353                     return;
354                 }
355                 if (name != null && name.length() > 1) {
356                     // setUserServletProperty(part.substring(3),poster.getPostParameter((String)obj),0);
357

358                     if (poster.checkPostMultiParameter((String JavaDoc)obj)) {
359                         // MULTIPLE SUPPORT
360
// id.setValue(name,part.substring(3),req.getPostMultiParameter((String)obj));
361
} else {
362                         // id.setValue(name,part.substring(3),poster.getPostParameter((String)obj));
363
}
364                 }
365                 // PRC-CMD- commands
366
} else if (part.indexOf("PRC-CMD-") == 0) {
367                 if (poster.checkPostMultiParameter((String JavaDoc)obj)) {
368                     proc_cmd.put(part.substring(8), poster.getPostMultiParameter((String JavaDoc)obj));
369                 } else {
370                     proc_cmd.put(part.substring(8), poster.getPostParameter((String JavaDoc)obj));
371                 }
372                 // PRC-VAR- vars
373
} else if (part.indexOf("PRC-VAR-") == 0) {
374                 if (poster.checkPostMultiParameter((String JavaDoc)obj)) {
375                     proc_var.put(part.substring(8), poster.getPostMultiParameter((String JavaDoc)obj));
376                 } else {
377                     proc_var.put(part.substring(8), poster.getPostParameter((String JavaDoc)obj));
378                 }
379             }
380         }
381         // If there are cmds process them
382
if (!proc_cmd.isEmpty()) parser.do_proc_input(sp.req_line, poster,proc_var, proc_cmd,sp);
383     }
384
385
386     boolean handleCacheSave(scanpage sp, HttpServletResponse res) {
387         if (sp.wantCache != null) {
388             String JavaDoc req_line = sp.req_line;
389             if (sp.querystring != null) req_line += "?" + sp.querystring;
390             try {
391                 parser.scancache.newput(sp.wantCache, res, req_line, sp.body, sp.mimetype);
392             } catch (Exception JavaDoc e) {
393                 log.error("servscan - something is wrong with scancache");
394             }
395         }
396         return true;
397     }
398
399     boolean handleCache(scanpage sp,HttpServletResponse res, PrintWriter out) {
400         String JavaDoc req_line = sp.req_line;
401         if (sp.querystring != null) req_line += "?" + sp.querystring;
402
403         // new new new scancache setup, needs to be moved
404
// ----------------------------------------------
405

406         // This depends on the PRAGMA: no-cache header
407
// Which Internet Explorer does not send.
408

409         if (sp.body != null) {
410
411             int start = sp.body.indexOf("<CACHE HENK");
412             if (start >= 0) {
413                 start += 11;
414                 int end = sp.body.indexOf(">", start);
415                 sp.wantCache ="HENK";
416
417                 String JavaDoc rst = parser.scancache.get(sp.wantCache, req_line, sp.body.substring(start, end + 1), sp);
418                 if (log.isDebugEnabled()) {
419                     log.debug("handleCache: sp.reload: " + sp.reload);
420                 }
421
422                 if (rst != null && !sp.reload) {
423                     long lastModDate = parser.scancache.getLastModDate(sp.wantCache, req_line);
424                     long expireDate = parser.scancache.getExpireDate(sp.wantCache, req_line, sp.body.substring(start, end).trim());
425
426                     setHeaders(sp, res, rst, lastModDate, expireDate);
427                     // org.mmbase res.writeHeaders();
428
try {
429                         if (out == null) {
430                             out = res.getWriter();
431                         }
432                         out.print(rst);
433                         out.flush();
434                         out.close();
435                     } catch (IOException io) {
436                         log.error(io);
437                     }
438                     if (log.isDebugEnabled()) {
439                         log.debug("handleCache(): cache.hit(" + req_line + ")");
440                     }
441                     return(true);
442                 } else {
443                     if (log.isDebugEnabled()) {
444                         log.debug("handleCache(): cache.miss(" + req_line + ")");
445                     }
446                 }
447             }
448
449             if (sp.body.indexOf("<CACHE PAGE>") !=- 1) {
450
451                 sp.wantCache="PAGE";
452                 String JavaDoc rst=parser.scancache.get(sp.wantCache, req_line, sp);
453
454                 if (log.isDebugEnabled()) {
455                     log.debug("handleCache: sp.reload: " + sp.reload);
456                 }
457                 if (rst != null && !sp.reload) {
458                     long lastModDate = parser.scancache.getLastModDate(sp.wantCache, req_line);
459
460                     setHeaders(sp, res,rst,lastModDate,0);
461                     // org.mmbase res.writeHeaders();
462
try {
463
464                         if (out == null) {
465                             out = res.getWriter();
466                         }
467                         out.print(rst);
468                         out.flush();
469                         out.close();
470                     } catch (IOException io) {
471                         log.error(io);
472                     }
473
474                     if (log.isDebugEnabled()) {
475                         log.debug("handleCache(): cache.hit(" + req_line + ")");
476                     }
477                     return true;
478                 } else {
479                     log.debug("handleCache(): cache.miss(" + req_line + ")");
480                 }
481             }
482         }
483
484         return false;
485     }
486
487
488     private long handleTime(scanpage sp) {
489         if (sp.body != null && sp.body.indexOf("<TIME>") != -1) {
490             return System.currentTimeMillis();
491         }
492         return -1;
493     }
494
495
496     private boolean doCrcCheck(scanpage sp, HttpServletResponse res) {
497         if (sp.body != null && sp.body.indexOf("<CRC>") != -1) {
498             Vector p = sp.getParamsVector();
499             String JavaDoc value = null;
500             String JavaDoc checker = null;
501             for (Enumeration t= p.elements(); t.hasMoreElements();) {
502                 String JavaDoc part = (String JavaDoc)t.nextElement();
503                 if (!((String JavaDoc)p.lastElement()).equals(part)) {
504                     if (value == null) {
505                         value = part;
506                     } else {
507                         value += "+" + part;
508                     }
509                 } else {
510                     checker = part;
511                 }
512             }
513             value = sp.req.getRequestURI() + "?" + value;
514             int crc = scanparser.calccrc32(value);
515             String JavaDoc thiscrc = "CRC" + crc;
516             System.out.println("CRC = " + crc);
517             if (checker != null && checker.equals(thiscrc)) {
518                 return true;
519             }
520             return false;
521         }
522         return true;
523     }
524
525     private String JavaDoc doSecure(scanpage sp, HttpServletResponse res) throws Exception JavaDoc {
526         String JavaDoc name = null;
527         if (sp.body != null && sp.body.indexOf("<SECURE>") != -1) {
528             if (log.isDebugEnabled()) {
529                 log.debug("doSecure(" + sp.getUrl() + "): Secure tag found, calling getAuthorization()...");
530             }
531             name = getAuthorization(sp.req, res);
532             if (log.isDebugEnabled()) {
533                 log.debug("doSecure(" + sp.getUrl() + "): getting cookie from user...");
534             }
535             String JavaDoc sname = getCookie(sp.req, res);
536
537             // check name
538
if (name == null) {
539                 log.warn("doSecure(" + sp.getUrl() + "): WARNING: no username found!");
540                 return null;
541             }
542         }
543         return name;
544     }
545 }
546
Popular Tags