📄 requestevaluator.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 + -