Package org.snova.framework.proxy.spac.filter

Source Code of org.snova.framework.proxy.spac.filter.GFWList

/**
*
*/
package org.snova.framework.proxy.spac.filter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;

import org.arch.config.IniProperties;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snova.framework.config.SnovaConfiguration;
import org.snova.framework.proxy.spac.filter.gfwlist.GFWListRule;
import org.snova.framework.proxy.spac.filter.gfwlist.HostUrlWildcardRule;
import org.snova.framework.proxy.spac.filter.gfwlist.UrlRegexRule;
import org.snova.framework.proxy.spac.filter.gfwlist.UrlWildcardRule;
import org.snova.framework.util.FileManager;

/**
* @author yinqiwen
*
*/
public class GFWList extends SpacFilter
{
  protected static Logger         logger    = LoggerFactory
                                                    .getLogger(GFWList.class);
  private static GFWList         instance    = new GFWList();
 
  private ArrayList<GFWListRule>  whiteList  = new ArrayList<GFWListRule>();
  private ArrayList<GFWListRule>  blackList  = new ArrayList<GFWListRule>();
 
  private GFWList()
  {
  }
 
  static GFWList getInstacne()
  {
    return instance;
  }
 
  @Override
  public boolean filter(HttpRequest req)
  {
    for (GFWListRule rule : whiteList)
    {
      if (rule.match(req))
      {
        return false;
      }
    }
    for (GFWListRule rule : blackList)
    {
      if (rule.match(req))
      {
        return true;
      }
    }
    return whiteList.isEmpty() && blackList.isEmpty();
  }
 
  public static void loadRules(String rules) throws IOException
  {
    ArrayList<GFWListRule> w = new ArrayList<GFWListRule>();
    ArrayList<GFWListRule> b = new ArrayList<GFWListRule>();
    BufferedReader reader = new BufferedReader(new StringReader(rules));
    int i = 0;
    while (true)
    {
      String line = reader.readLine();
      i++;
      if (i == 1)
      {
        continue;
      }
      if (null == line)
      {
        break;
      }
      line = line.trim();
      if(line.length() == 0)
      {
        continue;
      }
      if (line.startsWith("!"))
      {
        continue;
      }
      if (line.startsWith("@@||"))
      {
        HostUrlWildcardRule rule = new HostUrlWildcardRule();
        rule.init(line.substring(4));
        w.add(rule);
      }
      else if (line.startsWith("||"))
      {
        HostUrlWildcardRule rule = new HostUrlWildcardRule();
        rule.init(line.substring(2));
        b.add(rule);
      }
      else if (line.startsWith("|http"))
      {
        UrlWildcardRule rule = new UrlWildcardRule();
        rule.init(line.substring(1));
        b.add(rule);
      }
      else if (line.startsWith("/") && line.endsWith("/"))
      {
        UrlRegexRule rule = new UrlRegexRule();
        rule.init(line.substring(1, line.length() - 1));
        b.add(rule);
      }
      else
      {
        HostUrlWildcardRule rule = new HostUrlWildcardRule();
        rule.onlyHttp = true;
        rule.init(line);
        b.add(rule);
      }
    }
    instance.blackList = b;
    instance.whiteList = w;
  }
 
  public static void generatePAC(String url, String content)
          throws IOException
  {
    String template = "/*\r\n"
            + "* Proxy Auto-Config file generated by autoproxy2pac\r\n"
            + "*  Rule source: ${RuleListUrl}\r\n"
            + "*  Last update: ${RuleListDate}\r\n" + "*/\r\n"
            + "function FindProxyForURL(url, host) {\r\n"
            + "  var ${ProxyVar} = \"${ProxyString}\";\r\n"
            + "  var ${DefaultVar} = \"${DefaultString}\";\r\n"
            + "  ${CustomCodePre}\r\n" + "   ${RulesBegin}\r\n"
            + "  ${RuleListCode}\r\n" + "   ${RulesEnd}\r\n"
            + "  ${CustomCodePost}\r\n" + "  return ${DefaultVar};\r\n" + "}";
   
    IniProperties cfg = SnovaConfiguration.getInstance().getIniProperties();
    String rulesBegin = "//-- AUTO-GENERATED RULES, DO NOT MODIFY!";
    String rulesEnd = "//-- END OF AUTO-GENERATED RULES";
    String proxyVar = "PROXY";
    String ruleListUrl = url;
    String ruleListDate = "";
    String proxyString = "PROXY " + cfg.getProperty("SPAC", "PACProxy");
    String defaultVar = "DEFAULT";
    String defaultString = "DIRECT";
   
    StringBuilder jsCode = new StringBuilder();
   
    BufferedReader reader = new BufferedReader(new StringReader(content));
    int i = 0;
    while (true)
    {
      String line = reader.readLine();
      i++;
     
      if (i == 1)
      {
        continue;
      }
      if (null == line)
      {
        break;
      }
      line = line.trim();
      // comment
      if (line.length() == 0 || line.startsWith("!"))
      {
        continue;
      }
      String proxy_var = "PROXY";
      if (line.startsWith("@@"))
      {
        line = line.substring(2);
        proxy_var = "DEFAULT";
      }
      String jsRegexp = "";
      if (line.startsWith("/") && line.endsWith("/"))
      {
        jsRegexp = line.substring(1, line.length() - 1);
      }
      else
      {
        jsRegexp = line.replaceAll("\\*+", "*");
       
        jsRegexp = jsRegexp.replaceFirst("\\^\\|$", "^");
        jsRegexp = jsRegexp.replaceAll("(\\W)", "\\\\$1");
       
        jsRegexp = jsRegexp.replaceAll("\\\\\\*", ".*");
        jsRegexp = jsRegexp.replaceAll("\\\\^",
                "(?:[^\\w\\-.%\u0080-\uFFFF]|$)");
       
        jsRegexp = jsRegexp.replaceFirst("^\\\\\\|\\\\\\|",
                "^[\\\\w\\\\-]+:\\\\/+(?!\\\\/)(?:[^\\\\/]+\\\\.)?");
       
        jsRegexp = jsRegexp.replaceFirst("^\\\\\\|", "^");
        jsRegexp = jsRegexp.replaceFirst("\\\\\\|$", "$");
       
        jsRegexp = jsRegexp.replaceFirst("^(\\.\\*)", "");
        jsRegexp = jsRegexp.replaceFirst("(\\.\\*)$", "");
      }
      if (jsRegexp.length() == 0)
      {
        logger.error("There is one rule that matches all URL, which is highly *NOT* recommended: "
                + line);
      }
      String jsLine = String.format("if(/%s/i.test(url)) return %s;",
              jsRegexp, proxy_var);
      if (proxy_var.equals("DEFAULT"))
      {
        StringBuilder tmp = new StringBuilder();
        tmp.append(jsLine).append("\r\n\t");
        tmp.append(jsCode);
        jsCode = tmp;
      }
      else
      {
        jsCode.append(jsLine).append("\r\n\t");
      }
    }
   
    try
    {
      template = template.replace("${RulesBegin}", rulesBegin);
      template = template.replace("${RulesEnd}", rulesEnd);     
      template = template.replace("${RuleListUrl}", ruleListUrl);
      template = template.replace("${RuleListDate}", ruleListDate);
      template = template.replace("${ProxyVar}", proxyVar);
      template = template.replace("${ProxyString}", proxyString);
      template = template.replace("${DefaultVar}", defaultVar);
      template = template.replace("${DefaultString}", defaultString);
      template = template.replace("${CustomCodePre}", "");
      template = template.replace("${RuleListCode}", jsCode.toString());
      template = template.replace("${CustomCodePost}", "");
    }
    catch (Exception e)
    {
      logger.error("Failed to generate PAC.", e);
    }
    FileManager.writeFile(template, "spac/snova-gfwlist.pac");
  }
}
TOP

Related Classes of org.snova.framework.proxy.spac.filter.GFWList

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.