⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 requestevaluator.java

📁 使用工具jublider开发的一个聊天室实现基本功能,
💻 JAVA
字号:
/**
 * Copyright (C) 2003  Manfred Andres
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package freecs.core;

import freecs.*;
import freecs.auth.AuthManager;
import freecs.content.*;
import freecs.external.AccessForbiddenException;
import freecs.external.IRequestHandler;
import freecs.external.StateRequestHandler;
import freecs.external.StaticRequestHandler;
import freecs.external.UserlistRequestHandler;
import freecs.external.WebadminRequestHandler;
import freecs.interfaces.*;
import freecs.util.CookieGenerator;
import freecs.layout.TemplateSet;
import java.nio.channels.SelectionKey;
import java.util.HashMap;

/**
 * parses the request
 * has a static parse function, which automatically decides which
 * RequestEvaluator has available resources and suplies the Request to
 * this RequestEvaluator. If it fails more than MAX_THREADSEARCHES times,
 * it creates a new RequestEvaluator-Thread.
 */
public class RequestEvaluator {
   private MessageParser mp;
   private short parserID;
   private RequestReader req;
   private HashMap requestHandlers;

   public RequestEvaluator (RequestReader r) {
      parserID = r.getID();
      mp = new MessageParser (r);
      req=r;
      requestHandlers = new HashMap();
      requestHandlers.put("/userlist", new UserlistRequestHandler("/USERLIST"));
      requestHandlers.put("/state", new StateRequestHandler("/STATE"));
      requestHandlers.put("/admin", new WebadminRequestHandler("/ADMIN"));
      requestHandlers.put("/static", new StaticRequestHandler("/static"));
   }

	/**
	 * this decides what to do with the requst and how to answere it
	 * @param cReq The IRequest-Object containing the requestparameters
	 */
    public void evaluate(IRequest cReq) {
        if (cReq==null)
            return;
        SelectionKey key = cReq.getKey ();
        if (!CentralSelector.isSkValid(key)) {
            Server.log(this, "evaluate: request has invalid key", Server.MSG_STATE, Server.LVL_VERBOSE);
            return;
        }
        ConnectionBuffer rb = cReq.getConnectionBuffer ();
        // every key must have a ConnectionBuffer
        if (rb == null) {
            Server.log (this, "ConnectionBuffer was empty", Server.MSG_ERROR, Server.LVL_MAJOR);
            CentralSelector.dropKey(key);
            return;
        }
        req.currPosition = RequestReader.EVALUATING;
      try {
         String action = cReq.getAction ();
         byte method = cReq.getMethod ();
         String cookie = cReq.getCookie ();
         
         // init logging-message
         rb.addLog (method == IRequest.METHOD_GET ? "GET" : "POST");
         rb.addLog (action);
         rb.addLog (((HTTPRequest) cReq).isHTTP11 () ? "HTTP/1.1" : "HTTP/1.0");
         if (cookie == null)
            rb.addLog ("NO-COOKIE");
         else
            rb.addLog (cookie);
         rb.addLog (" ");
         rb.addLog (cReq.getUserAgent());
         
         // get the user identified by the given cookie
         User u = (cookie == null ? null : UserManager.mgr.getUserByCookie (cookie));
         boolean isHTTP11 = ((HTTPRequest) cReq).isHTTP11 ();

         // Check for templateset
         TemplateSet ts = null;
         String templateset = cReq.getValue ("templateset");
         if (templateset != null) {
            ts = Server.srv.templatemanager.getTemplateSet (templateset);
         } else if (u != null) {
            ts = u.getTemplateSet ();
         }

         ContentContainer c = new ContentContainer ();
         ((ContentContainer) c).setHTTP11 (isHTTP11);
         if (ts != null) {
            c.useTemplateSet (ts);
         }
         if (cookie == null) {
            c.setCookie (CookieGenerator.generateCookie ());
         }
         if (cookie != null && "/SEND".equals(action)) {
             RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
             if (!handleSend(u, rb, key, cReq, isHTTP11))
                 return;
             c.wrap ("dummy");
         } else if (action.toLowerCase().startsWith("/static/")) {
             RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
             try {
                 IRequestHandler reqHandler = (IRequestHandler) requestHandlers.get("/static");
                 reqHandler.handle(cReq, c);
             } catch (AccessForbiddenException noAccess) {
                 if (noAccess.hidePage() == true) {
                     c.setTemplate("not_found");
                 }
             }
         } else if (requestHandlers.containsKey(action.toLowerCase())) {
            // pass request to a registered request handler
            RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
            try {
                IRequestHandler reqHandler = ((IRequestHandler)requestHandlers.get(action.toLowerCase()));
                reqHandler.handle(cReq, c);
            } catch (AccessForbiddenException noAccess) {
                if (noAccess.hidePage() == true) {
                     c.setTemplate("not_found");
                }
            }
         } else if (method==IRequest.METHOD_GET) {
			req.currPosition=RequestReader.EVAL_GET;
            if ("/".equals(action)) {
               RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
               c.setTemplate ("start");
            } else if (cookie != null && "/LOGIN".equals (action)) {
                RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.LOGIN_TIMEOUT);
                if (u!=null) {
                    softCloseMessagesConnection(u, u.getKey());
                }
                if (UserManager.mgr.tryLogin(null,null,null,ts,req,u) == UserManager.LOGIN_RELOAD) {
                    c.setTemplate ("frameset");
                    if (ts != null) { 
                        u.setTemplateSet (ts);
                    }
                } else {
                	AuthManager.instance.doLogin(cReq, key, cookie, c, ts, u, isHTTP11, req);
                }
            } else if ("/INPUT".equals(action)) {
               RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
               c.setTemplate ("input");
            } else if ("/MESSAGES".equals(action)) {
                RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
                handleMessagesConnection(c, u, cReq, key, isHTTP11, rb);
                return;
            } else if ("/DUMMY".equals(action)) {
               c.wrap ("dummy");
               // c.setKeepAlive (false);
            } else {
               RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.READER_TIMEOUT);
               if (ts == null) ts = Server.srv.templatemanager.getTemplateSet("default");
               String tname = action.substring (1).toLowerCase ();
               if (tname != null && tname.length () > 1) {
                  c.setTemplate (tname);
               } else {
                  c.setTemplate ("not_found");
               }
            }
         } else if (method==IRequest.METHOD_POST) {
            RequestMonitor.instance.addMonitor(Thread.currentThread(), System.currentTimeMillis() + Server.srv.LOGIN_TIMEOUT);
			req.currPosition=RequestReader.EVAL_POST;
            if (cookie != null && "/LOGIN".equals (action)) {
            	req.currPosition=RequestReader.EVAL_POST_LOGIN;
                if (u!=null) {
                    softCloseMessagesConnection(u, u.getKey());
                }
                AuthManager.instance.doLogin(cReq, key, cookie, c, ts, u, isHTTP11, req);
            } else {
            	c.setTemplate ("not_found");
            }
         } else {
         	c.setTemplate ("not_found");
         }
		 req.currPosition=RequestReader.EVAL_PREP4SEND;
         if (c.prepareForSending (cReq)) {
            if (!rb.isValid()) {
				rb.logError("ConnectionBuffer was invalidated");
				CentralSelector.dropKey (key);
				return;
			}
			req.currPosition=RequestReader.EVAL_SENDFINAL;
			rb.addToWrite (c.getByteBuffer());
            if (c.closeSocket())
                rb.addToWrite(Responder.CLOSE_CONNECTION);
         } else Server.log (this, "evaluate: prepareForSending failed", Server.MSG_ERROR, Server.LVL_VERY_VERBOSE);
      } catch (Exception e) {
         CentralSelector.dropKey (key);
         Server.debug (this, "evaluate: drop key", e, Server.MSG_ERROR, Server.LVL_MAJOR);
         rb.logError(e.getMessage());
      }
   }

    /**
     * @param c
     * @param u
     * @param req2
     * @param key
     * @param isHTTP11
     */
    private void handleMessagesConnection(ContentContainer c, User u, IRequest cReq, SelectionKey key, boolean isHTTP11, ConnectionBuffer rb) {
        req.currPosition=RequestReader.EVAL_GET_MESSAGES;
        if (u != null 
                && (u.isJoining()
                    || u.isLoggedIn()
                    || u.isRemoving())) {
                Connection conn = cReq.getConnectionObject();
                if (!u.wasActive ()) {
                    rb.logError("flooded");
                    return;
                }
                if (!rb.isValid()) {
                    CentralSelector.dropKey(key);
                    rb.logError("ConnectionBuffer was invalidated");
                    return;
                }
                synchronized (rb) {
                    rb.conn = conn;
                    rb.setIsMessageFrame(true);
                }
                SelectionKey oldKey;
                synchronized (u) {
                    oldKey = u.getKey();
                    u.setKey(key);
                }
                if (oldKey != null) {
                    // we do have an open connection for the /messages-frame
                    softCloseMessagesConnection(u, oldKey);
                }
                u.setHTTP11 (isHTTP11);
                c.setNoCache ();
                c.setNoStore ();
                c.setIsMessages ();
                c.setTemplate ("welcome");
                if (!c.prepareForSending (cReq)) {
                    Server.log (this, "evaluate: unable to init /MESSAGES: prepareForSending failed", Server.MSG_TRAFFIC, Server.LVL_MAJOR);
                    rb.logError("/MESSAGE prepare for sending failed");
                    CentralSelector.dropKey(key);
                    return;
                }
                req.currPosition=RequestReader.EVAL_GET_MESSAGES_APND2WRITE;
                rb.addToWrite (c.getByteBuffer());
                if (c.closeSocket())
                    rb.addToWrite(Responder.CLOSE_CONNECTION);
                req.currPosition=RequestReader.EVAL_GET_MESSAGES_SND_MSGS;
                u.sendScheduledMessages();
                return;
           } else {
              Server.log (this, "evaluate: bogous cookie or expired", Server.MSG_STATE, Server.LVL_MINOR);
              if (u==null)
                  c.setTemplate ("no_cookie");
              else
                  c.setTemplate("login_missing");
           }
    }

    /**
     * Handle /SEND
     * @param u
     * @param rb
     * @param key
     * @param cReq
     * @param isHTTP11
     */
    private boolean handleSend(User u, ConnectionBuffer rb, SelectionKey key, IRequest cReq, boolean isHTTP11) {
        req.currPosition=RequestReader.EVAL_SEND;
        if (u == null) {
           CentralSelector.dropKey (key);
           rb.logError("/send without user");
           return false;
        } else if (!u.isLoggedIn()) {
            CentralSelector.dropKey (key);
            rb.logError("/send from logged-out user");
            return false;
        }
        if (!u.wasActive ()) {
            rb.logError("flooded"); 
            return false;
        }
        if (Server.srv.isBanned (u.conn)) {
	       	rb.logError("User Ip isBanned"); 
     	    mp.setSender(u);
		    mp.getSender().sendQuitMessage (false);
    	    return false;
        } 
        String msg = cReq.getValue ("message");
        if (msg == null || msg.length () < 1) {
           Server.log (this, "evaluate: message too short", Server.MSG_TRAFFIC, Server.LVL_MINOR);
           rb.logError("message too short");
           return false;
        }
        mp.clear ();
        mp.setConnectionBuffer (rb);
        mp.setRawMessage (msg);
        mp.setHTTP11 (isHTTP11);
        mp.setSender (u);
        mp.parseAndSendMessage ();
        return true;
    }

    /**
     * 
     */
    private void softCloseMessagesConnection(User u, SelectionKey sk) {
        // TODO Auto-generated method stub
        try {
            if (!CentralSelector.isSkValid(sk))
                return;
            ConnectionBuffer cb = (ConnectionBuffer) sk.attachment();
            cb.setUser(null);
            String msgTpl = u.getTemplateSet().getMessageTemplate("message.softClose");
            StringBuffer sb = new StringBuffer(
                    MessageRenderer.renderTemplate(new MessageState(null), msgTpl));
            sb.append ("<body></html>");
            cb.addToWrite(MessageRenderer.encode(sb.toString()));
            cb.addToWrite(Responder.CLOSE_CONNECTION_IGNORE);
        } catch (Exception e) {
            // ignore
        }
    }

    public String  toString () {
      StringBuffer tsb = new StringBuffer ("[RequestEvaluator ").append (parserID).append ("]");
      return (tsb.toString ());
   }

   public int     hashCode () { return (int) parserID; }
   public short   getID    () { return (short) parserID; }
   public boolean equals (RequestEvaluator rp) { return (parserID == rp.getID ()); }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -