/* * Compare.java * * Created on 18 May 2005, 05:33 */ package org.owasp.webscarab.plugin.compare; import org.owasp.webscarab.model.ConversationID; import org.owasp.webscarab.model.ConversationModel; import org.owasp.webscarab.model.HttpUrl; import org.owasp.webscarab.model.Request; import org.owasp.webscarab.model.Response; import org.owasp.webscarab.model.StoreException; import org.owasp.webscarab.plugin.Framework; import org.owasp.webscarab.plugin.Plugin; import org.owasp.webscarab.plugin.Hook; import org.owasp.webscarab.util.LevenshteinDistance; import java.util.List; import java.util.Arrays; import java.util.ArrayList; import java.util.logging.Logger; /** * * @author rogan */ public class Compare implements Plugin { private CompareModel _model; private ConversationID _selected = null; private Thread _runThread = null; private Object _lock = new Object(); private LevenshteinDistance<String> _diff = null; private Logger _logger = Logger.getLogger(getClass().getName()); /** Creates a new instance of Compare */ public Compare(Framework framework) { _model = new CompareModel(framework.getModel()); } public CompareModel getModel() { return _model; } public void setBaseConversation(HttpUrl url, ConversationID id) { _model.clearConversations(); _selected = id; if (_model.isBusy()) _runThread.interrupt(); synchronized(_lock) { _lock.notifyAll(); } } public void analyse(ConversationID id, Request request, Response response, String origin) { } public void flush() throws StoreException { } public String getPluginName() { return "Compare"; } public Object getScriptableObject() { return null; } public Hook[] getScriptingHooks() { return new Hook[0]; } public String getStatus() { return _model.getStatus(); } public boolean isBusy() { return _model.isBusy(); } public boolean isModified() { return _model.isModified(); } public boolean isRunning() { return _model.isRunning(); } public void run() { _runThread = Thread.currentThread(); _model.setRunning(true); int count = 0; ConversationID id = null; ConversationModel cmodel = _model.getConversationModel(); while (!_model.isStopping()) { try { synchronized(_lock) { _lock.wait(); } if (id != _selected) { id = _selected; _model.setBusy(true); HttpUrl baseUrl = cmodel.getRequestUrl(id); if (baseUrl.getQuery() != null) baseUrl = baseUrl.getParentUrl(); Response baseResponse = cmodel.getResponse(id); byte[] baseBytes = baseResponse.getContent(); String type = baseResponse.getHeader("Content-Type"); if (type == null || !type.startsWith("text")) { _logger.warning("Base response is not text, skipping!"); return; } List<String> baseline = tokenize(baseBytes); _diff = new LevenshteinDistance<String>(baseline); count = cmodel.getConversationCount(); _logger.info("Checking " + count + " conversaitons"); for (int i=0; i<count; i++) { ConversationID cid = cmodel.getConversationAt(i); HttpUrl curl = cmodel.getRequestUrl(cid); if (curl.getQuery() != null) curl = curl.getParentUrl(); if (!curl.equals(baseUrl)) continue; _logger.info("Checking conversation " + i + " == " + cid); if (cid.equals(id)) { _model.setDistance(cid, 0); } else { Response response = cmodel.getResponse(cid); String ctype = response.getHeader("Content-Type"); _logger.info("Content-type is " + ctype); if (ctype != null && ctype.startsWith("text")) { byte[] bytes = response.getContent(); List<String> target = tokenize(bytes); _model.setDistance(cid, _diff.getDistance(target)); } } } _model.setBusy(false); } Thread.sleep(100); } catch (InterruptedException ie) {} } _model.setRunning(false); _model.setStopping(false); } public void setSession(String type, Object store, String session) throws StoreException { } public boolean stop() { _model.setStopping(true); _runThread.interrupt(); try { Thread.sleep(50); } catch (InterruptedException ie) {} return ! _model.isRunning(); } private List<String> tokenize(byte[] bytes) { if (bytes == null) return new ArrayList<String>(); // List byteList = new ArrayList(); // for (int i=0; i<bytes.length; i++) { // byteList.add(new Byte(bytes[i])); // } // return byteList; // String[] words = new String(bytes).split("\\s"); List<String> tokens = Arrays.asList(words); return tokens; } }