KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > freecs > core > RequestEvaluator


1 /**
2  * Copyright (C) 2003 Manfred Andres
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */

18 package freecs.core;
19
20 import freecs.*;
21 import freecs.auth.AuthManager;
22 import freecs.content.*;
23 import freecs.external.AccessForbiddenException;
24 import freecs.external.IRequestHandler;
25 import freecs.external.StateRequestHandler;
26 import freecs.external.StaticRequestHandler;
27 import freecs.external.UserlistRequestHandler;
28 import freecs.external.WebadminRequestHandler;
29 import freecs.interfaces.*;
30 import freecs.util.CookieGenerator;
31 import freecs.layout.TemplateSet;
32 import java.nio.channels.SelectionKey JavaDoc;
33 import java.util.HashMap JavaDoc;
34
35 /**
36  * parses the request
37  * has a static parse function, which automatically decides which
38  * RequestEvaluator has available resources and suplies the Request to
39  * this RequestEvaluator. If it fails more than MAX_THREADSEARCHES times,
40  * it creates a new RequestEvaluator-Thread.
41  */

42 public class RequestEvaluator {
43    private MessageParser mp;
44    private short parserID;
45    private RequestReader req;
46    private HashMap JavaDoc requestHandlers;
47
48    public RequestEvaluator (RequestReader r) {
49       parserID = r.getID();
50       mp = new MessageParser (r);
51       req=r;
52       requestHandlers = new HashMap JavaDoc();
53       requestHandlers.put("/userlist", new UserlistRequestHandler("/USERLIST"));
54       requestHandlers.put("/state", new StateRequestHandler("/STATE"));
55       requestHandlers.put("/admin", new WebadminRequestHandler("/ADMIN"));
56       requestHandlers.put("/static", new StaticRequestHandler("/static"));
57    }
58
59     /**
60      * this decides what to do with the requst and how to answere it
61      * @param cReq The IRequest-Object containing the requestparameters
62      */

63     public void evaluate(IRequest cReq) {
64         if (cReq==null)
65             return;
66         SelectionKey JavaDoc key = cReq.getKey ();
67         if (!CentralSelector.isSkValid(key)) {
68             Server.log(this, "evaluate: request has invalid key", Server.MSG_STATE, Server.LVL_VERBOSE);
69             return;
70         }
71         ConnectionBuffer rb = cReq.getConnectionBuffer ();
72         // every key must have a ConnectionBuffer
73
if (rb == null) {
74             Server.log (this, "ConnectionBuffer was empty", Server.MSG_ERROR, Server.LVL_MAJOR);
75             CentralSelector.dropKey(key);
76             return;
77         }
78         req.currPosition = RequestReader.EVALUATING;
79       try {
80          String JavaDoc action = cReq.getAction ();
81          byte method = cReq.getMethod ();
82          String JavaDoc cookie = cReq.getCookie ();
83          
84          // init logging-message
85
rb.addLog (method == IRequest.METHOD_GET ? "GET" : "POST");
86          rb.addLog (action);
87          rb.addLog (((HTTPRequest) cReq).isHTTP11 () ? "HTTP/1.1" : "HTTP/1.0");
88          if (cookie == null)
89             rb.addLog ("NO-COOKIE");
90          else
91             rb.addLog (cookie);
92          rb.addLog (" ");
93          rb.addLog (cReq.getUserAgent());
94          
95          // get the user identified by the given cookie
96
User u = (cookie == null ? null : UserManager.mgr.getUserByCookie (cookie));
97          boolean isHTTP11 = ((HTTPRequest) cReq).isHTTP11 ();
98
99          // Check for templateset
100
TemplateSet ts = null;
101          String JavaDoc templateset = cReq.getValue ("templateset");
102          if (templateset != null) {
103             ts = Server.srv.templatemanager.getTemplateSet (templateset);
104          } else if (u != null) {
105             ts = u.getTemplateSet ();
106          }
107
108          ContentContainer c = new ContentContainer ();
109          ((ContentContainer) c).setHTTP11 (isHTTP11);
110          if (ts != null) {
111             c.useTemplateSet (ts);
112          }
113          if (cookie == null) {
114             c.setCookie (CookieGenerator.generateCookie ());
115          }
116          if (cookie != null && "/SEND".equals(action)) {
117              RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
118              if (!handleSend(u, rb, key, cReq, isHTTP11))
119                  return;
120              c.wrap ("dummy");
121          } else if (action.toLowerCase().startsWith("/static/")) {
122              RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
123              try {
124                  IRequestHandler reqHandler = (IRequestHandler) requestHandlers.get("/static");
125                  reqHandler.handle(cReq, c);
126              } catch (AccessForbiddenException noAccess) {
127                  if (noAccess.hidePage() == true) {
128                      c.setTemplate("not_found");
129                  }
130              }
131          } else if (requestHandlers.containsKey(action.toLowerCase())) {
132             // pass request to a registered request handler
133
RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
134             try {
135                 IRequestHandler reqHandler = ((IRequestHandler)requestHandlers.get(action.toLowerCase()));
136                 reqHandler.handle(cReq, c);
137             } catch (AccessForbiddenException noAccess) {
138                 if (noAccess.hidePage() == true) {
139                      c.setTemplate("not_found");
140                 }
141             }
142          } else if (method==IRequest.METHOD_GET) {
143             req.currPosition=RequestReader.EVAL_GET;
144             if ("/".equals(action)) {
145                RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
146                c.setTemplate ("start");
147             } else if (cookie != null && "/LOGIN".equals (action)) {
148                 RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.LOGIN_TIMEOUT);
149                 if (u!=null) {
150                     softCloseMessagesConnection(u, u.getKey());
151                 }
152                 if (UserManager.mgr.tryLogin(null,null,null,ts,req,u) == UserManager.LOGIN_RELOAD) {
153                     c.setTemplate ("frameset");
154                     if (ts != null) {
155                         u.setTemplateSet (ts);
156                     }
157                 } else {
158                     AuthManager.instance.doLogin(cReq, key, cookie, c, ts, u, isHTTP11, req);
159                 }
160             } else if ("/INPUT".equals(action)) {
161                RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
162                c.setTemplate ("input");
163             } else if ("/MESSAGES".equals(action)) {
164                 RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
165                 handleMessagesConnection(c, u, cReq, key, isHTTP11, rb);
166                 return;
167             } else if ("/DUMMY".equals(action)) {
168                c.wrap ("dummy");
169                // c.setKeepAlive (false);
170
} else {
171                RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
172                if (ts == null) ts = Server.srv.templatemanager.getTemplateSet("default");
173                String JavaDoc tname = action.substring (1).toLowerCase ();
174                if (tname != null && tname.length () > 1) {
175                   c.setTemplate (tname);
176                } else {
177                   c.setTemplate ("not_found");
178                }
179             }
180          } else if (method==IRequest.METHOD_POST) {
181             RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.LOGIN_TIMEOUT);
182             req.currPosition=RequestReader.EVAL_POST;
183             if (cookie != null && "/LOGIN".equals (action)) {
184                 req.currPosition=RequestReader.EVAL_POST_LOGIN;
185                 if (u!=null) {
186                     softCloseMessagesConnection(u, u.getKey());
187                 }
188                 AuthManager.instance.doLogin(cReq, key, cookie, c, ts, u, isHTTP11, req);
189             } else {
190                 c.setTemplate ("not_found");
191             }
192          } else {
193             c.setTemplate ("not_found");
194          }
195          req.currPosition=RequestReader.EVAL_PREP4SEND;
196          if (c.prepareForSending (cReq)) {
197             if (!rb.isValid()) {
198                 rb.logError("ConnectionBuffer was invalidated");
199                 CentralSelector.dropKey (key);
200                 return;
201             }
202             req.currPosition=RequestReader.EVAL_SENDFINAL;
203             rb.addToWrite (c.getByteBuffer());
204             if (c.closeSocket())
205                 rb.addToWrite(Responder.CLOSE_CONNECTION);
206          } else Server.log (this, "evaluate: prepareForSending failed", Server.MSG_ERROR, Server.LVL_VERY_VERBOSE);
207       } catch (Exception JavaDoc e) {
208          CentralSelector.dropKey (key);
209          Server.debug (this, "evaluate: drop key", e, Server.MSG_ERROR, Server.LVL_MAJOR);
210          rb.logError(e.getMessage());
211       }
212    }
213
214     /**
215      * @param c
216      * @param u
217      * @param req2
218      * @param key
219      * @param isHTTP11
220      */

221     private void handleMessagesConnection(ContentContainer c, User u, IRequest cReq, SelectionKey JavaDoc key, boolean isHTTP11, ConnectionBuffer rb) {
222         req.currPosition=RequestReader.EVAL_GET_MESSAGES;
223         if (u != null
224                 && (u.isJoining()
225                     || u.isLoggedIn()
226                     || u.isRemoving())) {
227                 Connection conn = cReq.getConnectionObject();
228                 if (!u.wasActive ()) {
229                     rb.logError("flooded");
230                     return;
231                 }
232                 if (!rb.isValid()) {
233                     CentralSelector.dropKey(key);
234                     rb.logError("ConnectionBuffer was invalidated");
235                     return;
236                 }
237                 synchronized (rb) {
238                     rb.conn = conn;
239                     rb.setIsMessageFrame(true);
240                 }
241                 SelectionKey JavaDoc oldKey;
242                 synchronized (u) {
243                     oldKey = u.getKey();
244                     u.setKey(key);
245                 }
246                 if (oldKey != null) {
247                     // we do have an open connection for the /messages-frame
248
softCloseMessagesConnection(u, oldKey);
249                 }
250                 u.setHTTP11 (isHTTP11);
251                 c.setNoCache ();
252                 c.setNoStore ();
253                 c.setIsMessages ();
254                 c.setTemplate ("welcome");
255                 if (!c.prepareForSending (cReq)) {
256                     Server.log (this, "evaluate: unable to init /MESSAGES: prepareForSending failed", Server.MSG_TRAFFIC, Server.LVL_MAJOR);
257                     rb.logError("/MESSAGE prepare for sending failed");
258                     CentralSelector.dropKey(key);
259                     return;
260                 }
261                 req.currPosition=RequestReader.EVAL_GET_MESSAGES_APND2WRITE;
262                 rb.addToWrite (c.getByteBuffer());
263                 if (c.closeSocket())
264                     rb.addToWrite(Responder.CLOSE_CONNECTION);
265                 req.currPosition=RequestReader.EVAL_GET_MESSAGES_SND_MSGS;
266                 u.sendScheduledMessages();
267                 return;
268            } else {
269               Server.log (this, "evaluate: bogous cookie or expired", Server.MSG_STATE, Server.LVL_MINOR);
270               if (u==null)
271                   c.setTemplate ("no_cookie");
272               else
273                   c.setTemplate("login_missing");
274            }
275     }
276
277     /**
278      * Handle /SEND
279      * @param u
280      * @param rb
281      * @param key
282      * @param cReq
283      * @param isHTTP11
284      */

285     private boolean handleSend(User u, ConnectionBuffer rb, SelectionKey JavaDoc key, IRequest cReq, boolean isHTTP11) {
286         req.currPosition=RequestReader.EVAL_SEND;
287         if (u == null) {
288            CentralSelector.dropKey (key);
289            rb.logError("/send without user");
290            return false;
291         } else if (!u.isLoggedIn()) {
292             CentralSelector.dropKey (key);
293             rb.logError("/send from logged-out user");
294             return false;
295         }
296         if (!u.wasActive ()) {
297             rb.logError("flooded");
298             return false;
299         }
300         if (Server.srv.isBanned (u.conn)) {
301             rb.logError("User Ip isBanned");
302             mp.setSender(u);
303             mp.getSender().sendQuitMessage (false);
304             return false;
305         }
306         String JavaDoc msg = cReq.getValue ("message");
307         if (msg == null || msg.length () < 1) {
308            Server.log (this, "evaluate: message too short", Server.MSG_TRAFFIC, Server.LVL_MINOR);
309            rb.logError("message too short");
310            return false;
311         }
312         mp.clear ();
313         mp.setConnectionBuffer (rb);
314         mp.setRawMessage (msg);
315         mp.setHTTP11 (isHTTP11);
316         mp.setSender (u);
317         mp.parseAndSendMessage ();
318         return true;
319     }
320
321     /**
322      *
323      */

324     private void softCloseMessagesConnection(User u, SelectionKey JavaDoc sk) {
325         // TODO Auto-generated method stub
326
try {
327             if (!CentralSelector.isSkValid(sk))
328                 return;
329             ConnectionBuffer cb = (ConnectionBuffer) sk.attachment();
330             cb.setUser(null);
331             String JavaDoc msgTpl = u.getTemplateSet().getMessageTemplate("message.softClose");
332             StringBuffer JavaDoc sb = new StringBuffer JavaDoc(
333                     MessageRenderer.renderTemplate(new MessageState(null), msgTpl));
334             sb.append ("<body></html>");
335             cb.addToWrite(MessageRenderer.encode(sb.toString()));
336             cb.addToWrite(Responder.CLOSE_CONNECTION_IGNORE);
337         } catch (Exception JavaDoc e) {
338             // ignore
339
}
340     }
341
342     public String JavaDoc toString () {
343       StringBuffer JavaDoc tsb = new StringBuffer JavaDoc ("[RequestEvaluator ").append (parserID).append ("]");
344       return (tsb.toString ());
345    }
346
347    public int hashCode () { return (int) parserID; }
348    public short getID () { return (short) parserID; }
349    public boolean equals (RequestEvaluator rp) { return (parserID == rp.getID ()); }
350
351 }
Popular Tags