1 4 package org.roller.util; 5 6 import org.roller.util.StringUtils; 7 import org.apache.commons.logging.Log; 8 import org.apache.commons.logging.LogFactory; 9 10 import java.io.BufferedReader ; 11 import java.io.FileInputStream ; 12 import java.io.FileWriter ; 13 import java.io.IOException ; 14 import java.io.InputStream ; 15 import java.io.InputStreamReader ; 16 import java.io.File ; 17 import java.io.FileNotFoundException ; 18 import java.net.HttpURLConnection ; 19 import java.net.MalformedURLException ; 20 import java.net.URL ; 21 import java.text.ParseException ; 22 import java.text.SimpleDateFormat ; 23 import java.util.Date ; 24 import java.util.Iterator ; 25 import java.util.LinkedList ; 26 import java.util.List ; 27 import java.util.regex.Matcher ; 28 import java.util.regex.Pattern ; 29 30 42 public class Blacklist 43 { 44 private static Log mLogger = LogFactory.getLog(Blacklist.class); 45 46 private static Blacklist blacklist; 47 48 public static final String blacklistFile = "blacklist.txt"; 49 private static final String blacklistURL = "http://www.jayallen.org/comment_spam/blacklist.txt"; 50 private static final String lastUpdateStr = "Last update:"; 51 52 private static final String DEFAULT_BLACKLIST_DIR = "resources"; 55 private String realPath; 56 private String uploadDir; 57 58 private List blacklistStr = new LinkedList (); 59 private List blacklistRegex = new LinkedList (); 60 61 private Date ifModifiedSince = null; 62 63 66 public static Blacklist getBlacklist(String realPath, String uploadDir) 67 { 68 if (blacklist == null) 69 { 70 Blacklist temp = new Blacklist(realPath, uploadDir); 71 temp.extractFromFile(); 72 blacklist = temp; 73 } 74 return blacklist; 75 } 76 77 85 public static void checkForUpdate() 86 { 87 blacklist = blacklist.extractFromURL(); 88 } 89 90 93 private Blacklist(String realPath, String uploadDir) 94 { 95 this.realPath = realPath; 96 this.uploadDir = uploadDir; 97 } 98 99 102 private void extractFromFile() 103 { 104 InputStream txtStream = getFileInputStream(); 105 if (txtStream != null) 106 { 107 readFromStream(txtStream, false); 108 } 109 else 110 { 111 throw new NullPointerException ("Unable to load blacklist.txt. " + 112 "Make sure blacklist.txt is in classpath."); 113 } 114 } 115 116 120 private String readFromStream(InputStream txtStream, boolean saveStream) 121 { 122 String line; 123 StringBuffer buf = new StringBuffer (); 124 BufferedReader in = null; 125 try 126 { 127 in = new BufferedReader ( 128 new InputStreamReader ( txtStream, "UTF-8" ) ); 129 while ((line = in.readLine()) != null) 130 { 131 if (line.startsWith("#")) 132 { 133 readComment(line); 134 } 135 else 136 { 137 readRule(line); 138 } 139 140 if (saveStream) buf.append(line).append("\n"); 141 } 142 } 143 catch (Exception e) 144 { 145 mLogger.error(e); 146 } 147 finally 148 { 149 try 150 { 151 if (in != null) in.close(); 152 } 153 catch (IOException e1) 154 { 155 mLogger.error(e1); 156 } 157 } 158 return buf.toString(); 159 } 160 161 165 private Blacklist extractFromURL() 166 { 167 Blacklist oldBlacklist = getBlacklist(realPath, uploadDir); 169 Blacklist newBlacklist = new Blacklist(realPath, uploadDir); 170 try 171 { 172 URL url = new URL (blacklistURL); 173 HttpURLConnection connection = (HttpURLConnection )url.openConnection(); 174 if (oldBlacklist.ifModifiedSince != null) 175 { 176 connection.setRequestProperty("If-Modified-Since", 177 DateUtil.formatRfc822(oldBlacklist.ifModifiedSince)); 178 } 179 180 if ( connection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) 182 { 183 return oldBlacklist; 185 } 186 187 long lastModifiedLong = connection.getHeaderFieldDate("Last-Modified", -1); 189 190 if (oldBlacklist.ifModifiedSince == null || 192 oldBlacklist.ifModifiedSince.getTime() < lastModifiedLong) 193 { 194 String results = newBlacklist.readFromStream( connection.getInputStream(), true ); 195 196 newBlacklist.writeToFile(results); 198 199 if (newBlacklist.ifModifiedSince == null && lastModifiedLong != -1) 200 { 201 newBlacklist.ifModifiedSince = new Date (lastModifiedLong); 202 } 203 204 return newBlacklist; 205 } 206 } 207 catch (Exception e) 208 { 209 mLogger.info("Roller Blacklist Update: Unable to update comment spam blacklist due to exception: " + e); 211 } 212 return oldBlacklist; 213 } 214 215 218 private void readRule(String str) 219 { 220 if (StringUtils.isEmpty(str)) return; 222 String rule = str.trim(); 223 224 if (str.indexOf("#") > 0) { 226 int commentLoc = str.indexOf("#"); 227 rule = str.substring(0, commentLoc-1).trim(); } 229 230 if (rule.indexOf( "(" ) > -1) { 232 blacklistRegex.add(Pattern.compile(rule)); 234 } 235 else if (StringUtils.isNotEmpty(rule)) 236 { 237 blacklistStr.add(rule); 238 } 239 } 240 241 245 private void readComment(String str) 246 { 247 int lastUpdatePos = str.indexOf(lastUpdateStr); 248 if (lastUpdatePos > -1) 249 { 250 str = str.substring(lastUpdatePos + lastUpdateStr.length()); 251 str = str.trim(); 252 try 253 { 254 SimpleDateFormat sdf = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); 255 ifModifiedSince = DateUtil.parse(str, sdf); 256 } 257 catch (ParseException e) 258 { 259 mLogger.debug("ParseException reading " + str); 260 } 261 } 262 } 263 264 270 public boolean isBlacklisted(String str) 271 { 272 if (str == null || StringUtils.isEmpty(str)) return false; 273 274 278 if( testStringRules(str) ) return true; 280 281 return testRegExRules(str); 283 } 284 285 291 private boolean testRegExRules(String str) 292 { 293 boolean hit = false; 294 Pattern testPattern = null; 295 Iterator iter = blacklistRegex.iterator(); 296 while (iter.hasNext()) 297 { 298 testPattern = (Pattern )iter.next(); 299 300 if (mLogger.isDebugEnabled()) 303 { 304 Matcher matcher = testPattern.matcher(str); 305 if (matcher.find()) 306 { 307 mLogger.debug(matcher.group() + " matched by " + testPattern.pattern()); 308 hit = true; 309 break; 310 } 311 } 312 else 313 { 314 if (testPattern.matcher(str).find()) 315 { 316 hit = true; 317 break; 318 } 319 } 320 } 321 return hit; 322 } 323 324 331 private boolean testStringRules(String str) 332 { 333 String test; 334 Iterator iter = blacklistStr.iterator(); 335 boolean hit = false; 336 while (iter.hasNext()) 337 { 338 test = (String )iter.next(); 339 if (str.indexOf(test) > -1) 341 { 342 if (mLogger.isDebugEnabled()) 344 { 345 mLogger.debug("matched:" + test + ":"); 346 } 347 hit = true; 348 break; 349 } 350 } 351 return hit; 352 } 353 354 358 private InputStream getFileInputStream() 359 { 360 try 361 { 362 String path = getBlacklistFilePath(); 367 if (path == null) 368 { 369 throw new FileNotFoundException ( 370 "null path (indexDir and realPath both null)"); 371 } 372 return new FileInputStream ( path ); 373 } 374 catch (Exception e) 375 { 376 return getClass().getResourceAsStream("/"+blacklistFile); 377 } 378 } 379 380 383 private void writeToFile(String results) 384 { 385 FileWriter out = null; 386 String path = getBlacklistFilePath(); 387 if (path == null) 388 { 389 mLogger.debug("Not writing blacklist file since directory paths were null."); 390 return; 391 } 392 try 393 { 394 out = new FileWriter (path); 396 out.write( results.toCharArray() ); 397 } 398 catch (Exception e) 399 { 400 mLogger.info("Unable to write new " + path); 401 } 402 finally 403 { 404 try 405 { 406 if (out != null) out.close(); 407 } 408 catch (IOException e) 409 { 410 mLogger.error("Unable to close stream to " + path); 411 } 412 } 413 } 414 415 private String getBlacklistFilePath() 417 { 418 if (uploadDir == null && realPath==null) 419 { 420 return null; 422 } 423 if (uploadDir == null || uploadDir.trim().length() == 0) 424 { 425 uploadDir = realPath + File.separator + DEFAULT_BLACKLIST_DIR; 426 } 427 return uploadDir + File.separator + blacklistFile; 428 } 429 430 433 public String toString() 434 { 435 StringBuffer buf = new StringBuffer ("blacklist "); 436 buf.append(blacklistStr).append("\n"); 437 buf.append("Regex blacklist ").append(blacklistRegex); 438 return buf.toString(); 439 } 440 } 441 | Popular Tags |