📄 msession.java.20040219
字号:
package net.jumperz.app.MGuardian;
import net.jumperz.util.*;
import net.jumperz.net.*;
import net.jumperz.net.exception.*;
import java.io.*;
import java.net.*;
import java.util.*;
import net.jumperz.app.MGuardian.rule.*;
import net.jumperz.app.MGuardian.plugin.*;
public final class MSession
//extends MSubject
implements MCommand, MObserver
{
private static final String SEC_LOG_PREFIX = "Alert:";
private static final int LOG_BUFSIZE = 300;
private static final int LOGFILENAME_BUFSIZE = 40;
private static final String DECODE_CHARSET = "ISO-8859-1";
private static final String HTTP = "HTTP";
private static final String HTTPS = "HTTPS";
private static String targetHost;
private static int targetPort;
private static boolean replaceHostField;
private static boolean replaceLocationField;
private static MHttpFilter requestFilter;
private static MHttpFilter responseFilter;
private static String targetPeer;
private static Map additionalResponseHeaderMap;
private static Map additionalRequestHeaderMap;
private static List requestRuleList;
private static List responseRuleList;
private static MTimer timer;
private static int requestHeaderTimeOut;
private static int requestBodyTimeOut;
private static int connectTimeOut;
private Socket clientSocket;
private Socket serverSocket;
private BufferedInputStream clientInputStream;
private OutputStream clientOutputStream;
private BufferedInputStream serverInputStream;
private OutputStream serverOutputStream;
private boolean keepAlive = true;
private String clientAddr;
private int clientPort;
private boolean timedOut = false;
private boolean isHttpsFlag = false;
private String protocol;
//loop
private boolean pass = false;
private int time;
private MResultCache resultCache;
private MHttpRequest request;
private MHttpResponse response;
private String sessionResult;
//-----------------------------------------------------------------------------------
public MSession( Socket in_socket )
throws Exception
{
clientSocket = in_socket;
clientAddr = clientSocket.getInetAddress().getHostAddress();
clientPort = clientSocket.getPort();
clientInputStream = new BufferedInputStream( clientSocket.getInputStream() );
clientOutputStream = clientSocket.getOutputStream();
isHttpsFlag = ( clientSocket instanceof javax.net.ssl.SSLSocket );
if( isHttpsFlag == true )
{
protocol = HTTPS;
}
else
{
protocol = HTTP;
}
}
//-----------------------------------------------------------------------------------
private void setup()
{
timer.regist( this );
MAddressManager.getInstance().add( clientAddr );
}
//-----------------------------------------------------------------------------------
private void cleanup()
{
timer.removeObserver( this );
MAddressManager.getInstance().remove( clientAddr );
}
//-----------------------------------------------------------------------------------
public void execute()
{
try
{
setup();
while( keepAlive )
{
resetLoopParameters();
recvRequest();
if( checkRequest() )
{
filterRequest();
modifyRequest();
connect();
sendRequest();
recvResponse();
if( checkResponse() )
{
filterResponse();
modifyResponse();
sendResponse();
}
else
{
keepAlive = false;
}
}
else
{
keepAlive = false;
}
getAccessLog();
clearHttpData();
}
}
catch( Exception e )
{
if( timedOut == false )
{
//e.printStackTrace();
MLogger.getInstance().Log( clientSocket + e.toString() );
}
}
finally
{
clearHttpData();
cleanup();
closeConnection();
}
}
//-----------------------------------------------------------------------------------
private void clearHttpData()
{
if( request != null )
{
request.clearBuffer();
}
if( response != null )
{
response.clearBuffer();
}
request = null;
response = null;
}
//-----------------------------------------------------------------------------------
private void resetLoopParameters()
{
time = 0;
pass = false;
resultCache = new MResultCache();
sessionResult = null;
}
//-----------------------------------------------------------------------------------
private void getAccessLog()
{
String hostField = request.getHeaderValue( "Host" );
if( hostField == null )
{
hostField = "-";
}
StringBuffer strBuf = new StringBuffer( LOG_BUFSIZE );
strBuf.append( clientSocket.getInetAddress().getHostAddress() );
strBuf.append( ":" );
strBuf.append( clientSocket.getPort() );
strBuf.append( " " );
strBuf.append( clientSocket.getLocalAddress().getHostAddress() );
strBuf.append( ":" );
strBuf.append( clientSocket.getLocalPort() );
strBuf.append( " " );
strBuf.append( hostField );
strBuf.append( " " );
strBuf.append( protocol );
strBuf.append( " " );
strBuf.append( request.getRequestLine() );
strBuf.append( " " );
if( response != null )
{
sessionResult = String.valueOf( response.getStatusCode() );
}
strBuf.append( sessionResult );
MLogger.getInstance().Log( strBuf.toString() );
}
//-----------------------------------------------------------------------------------
private boolean checkResponse()
throws IOException
{
if( responseRuleList == null
|| pass == true
)
{
return true;
}
String logId = null;
boolean logged = false;
int count = responseRuleList.size();
for( int i = 0; i < count; ++i )
{
MAbstractResponseRule rule = ( MAbstractResponseRule )responseRuleList.get( i );
if( rule.matches( response, resultCache ) )
{
logId = getLogId();
String command = rule.getCommand();
int action = rule.getAction();
// log
if( rule.getLogFlag() )
{
if( logged == false )
{
saveRequest( logId );
saveResponse( logId );
logged = true;
}
MLogger.getInstance().Log( MSession.SEC_LOG_PREFIX + rule.getName() + ":" + clientAddr + ":" + logId );
}
// command
if( rule.hasCommand() )
{
execCommand( command, rule.getName(), logId );
}
// plugin
List pluginList = rule.getPluginList();
if( pluginList != null )
{
int pluginCount = pluginList.size();
for( int j = 0; j < pluginCount; ++j )
{
MGuardianPlugin plugin = ( MGuardianPlugin )pluginList.get( j );
boolean doBlock = plugin.execute( request, response );
if( doBlock == true )
{
sessionResult = "blocked_by_plugin/" + plugin.getClass().getName();
return false;
}
}
}
// action
if( action == MAbstractRule.ACTION_BLOCK )
{
sessionResult = "blocked_by_rule/" + rule.getName();
return false;
}
else if( action == MAbstractRule.ACTION_PASS )
{
return true;
}
}
}
return true;
}
//-----------------------------------------------------------------------------------
private boolean checkRequest()
throws IOException
{
if( checkUrlEncoding() == false
|| checkRequestBodyEncoding() == false
)
{
return false;
}
if( requestRuleList == null )
{
return true;
}
String logId = null;
boolean logged = false;
int count = requestRuleList.size();
for( int i = 0; i < count; ++i )
{
MAbstractRequestRule rule = ( MAbstractRequestRule )requestRuleList.get( i );
if( rule.matches( request , resultCache ) )
{
if( logId == null )
{
logId = getLogId();
}
String command = rule.getCommand();
int action = rule.getAction();
// log
if( rule.getLogFlag() )
{
if( logged == false )
{
saveRequest( logId );
logged = true;
}
MLogger.getInstance().Log( MSession.SEC_LOG_PREFIX + rule.getName() + ":" + clientAddr + ":" + logId );
}
// command
if( rule.hasCommand() )
{
execCommand( command, rule.getName(), logId );
}
// plugin
List pluginList = rule.getPluginList();
if( pluginList != null )
{
int pluginCount = pluginList.size();
for( int j = 0; j < pluginCount; ++j )
{
MGuardianPlugin plugin = ( MGuardianPlugin )pluginList.get( j );
boolean doBlock = plugin.execute( request, response );
if( doBlock == true )
{
sessionResult = "blocked_by_plugin/" + plugin.getClass().getName();
return false;
}
}
}
// action
if( action == MAbstractRule.ACTION_BLOCK )
{
sessionResult = "blocked_by_rule/" + rule.getName();
return false;
}
else if( action == MAbstractRule.ACTION_PASS )
{
pass = true;
return true;
}
}
}
return true;
}
//--------------------------------------------------------------------------------
private boolean checkRequestBodyEncoding()
throws IOException
{
boolean b = true;
if( !request.hasBody() )
{
return true;
}
String contentType = request.getHeaderValue( "Content-Type" );
if( contentType == null
|| !contentType.equalsIgnoreCase( "application/x-www-form-urlencoded" )
)
{
return true;
}
try
{
InputStream bodyInputStream = request.getBodyInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream( bodyInputStream.available() );
MStreamUtil.connectStream( bodyInputStream, buffer );
String requestBodyStr = buffer.toString( MCharset.CS_ISO_8859_1 );
if( MUnicodeUrlDecoder.isUrlDecoded( requestBodyStr ) )
{
MUnicodeUrlDecoder.decode( requestBodyStr );
}
else
{
URLDecoder.decode( requestBodyStr, DECODE_CHARSET );
}
}
catch( UnsupportedEncodingException e )
{
// ignore :p
}
catch( IllegalArgumentException e )
{
e.printStackTrace();
sessionResult = "blocked_by_illegalArgument_on_request_body/" + e.getMessage();
b = false;
}
return b;
}
//-----------------------------------------------------------------------------------
private boolean checkUrlEncoding()
{
boolean b = true;
try
{
String uri = request.getUri();
if( MUnicodeUrlDecoder.isUrlDecoded( uri ) )
{
MUnicodeUrlDecoder.decode( uri );
}
else
{
URLDecoder.decode( uri, DECODE_CHARSET );
}
}
catch( UnsupportedEncodingException e )
{
// ignore :p
}
catch( IllegalArgumentException e )
{
e.printStackTrace();
sessionResult = "blocked_by_illegalArgument_on_url/" + e.getMessage();
b = false;
}
return b;
}
//-----------------------------------------------------------------------------------
private void saveResponse( String logId )
throws IOException
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -