Package org.snova.framework.proxy.hosts

Source Code of org.snova.framework.proxy.hosts.HostsService

/**
*
*/
package org.snova.framework.proxy.hosts;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.arch.config.IniProperties;
import org.arch.dns.ResolveOptions;
import org.arch.dns.Resolver;
import org.arch.dns.exception.NamingException;
import org.arch.misc.crypto.base64.Base64;
import org.arch.util.ListSelector;
import org.arch.util.StringHelper;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.snova.framework.config.SnovaConfiguration;
import org.snova.framework.util.FileManager;
import org.snova.framework.util.MiscHelper;
import org.snova.framework.util.SharedObjectHelper;

/**
* @author yinqiwen
*
*/
public class HostsService
{
  private static Map<String, ListSelector<String>>  hostsMappingTable  = new HashMap<String, ListSelector<String>>();
  private static int                               enable                = 1;
  private static String[]                           trustedDNS            = new String[] {
          "8.8.8.8", "208.67.222.222", "8.8.4.4", "208.67.220.220"    };
  private static Map<String, Boolean>               reachableCache        = new ConcurrentHashMap<String, Boolean>();
 
  private static void loadHostFile(String file)
  {
    InputStream is = HostsService.class.getResourceAsStream("/" + file);
    Properties props = new Properties();
    try
    {
      props.load(is);
      Set<Entry<Object, Object>> entries = props.entrySet();
      for (Entry<Object, Object> entry : entries)
      {
        String key = (String) entry.getKey();
        String value = (String) entry.getValue();
        key = key.trim();
        value = value.trim();
        String[] splits = value.split("[,|;|\\|]");
        List<String> mappings = Arrays.asList(splits);
        hostsMappingTable.put(key, new ListSelector<String>(mappings));
       
      }
      is.close();
    }
    catch (IOException e)
    {
      //
    }
  }
 
  public static boolean isDirectReachable(HttpRequest req)
  {
    if (enable == 0)
    {
      return false;
    }
    if (enable == 1 && !req.getMethod().equals(HttpMethod.CONNECT))
    {
      return false;
    }
    String host = HttpHeaders.getHost(req);
    String[] ss = host.split(":");
    int port = 80;
    if (ss.length == 2)
    {
      port = Integer.parseInt(ss[1]);
      host = ss[0];
    }
    else
    {
      if (req.getMethod().equals(HttpMethod.CONNECT))
      {
        port = 443;
      }
    }
    String ret = getRealHost(host, port);
    if (ret.equals(host))
    {
      return false;
    }
    return true;
  }
 
  private static boolean isReachable(String host, int port)
  {
    synchronized (reachableCache)
    {
      Boolean v = reachableCache.get(host + port);
      if (null != v)
      {
        return v;
      }
     
    }
    Socket s = new Socket();
    try
    {
      s.connect(new InetSocketAddress(host, port), 5000);
      s.close();
      reachableCache.put(host + port, true);
      return true;
    }
    catch (IOException e)
    {
     
    }
    reachableCache.put(host + port, false);
    return false;
  }
 
  public static String getMappingHost(String host)
  {
    ListSelector<String> selector = hostsMappingTable.get(host);
   
    if (null == selector)
    {
      return host;
    }
    String addr = selector.select().trim();
    if (hostsMappingTable.containsKey(addr))
    {
      return getMappingHost(addr);
    }
    return addr;
  }
 
  public static void removeMapping(String host, String mapping)
  {
    ListSelector<String> selector = hostsMappingTable.get(host);
    if (null != selector)
    {
      selector.remove(mapping);
    }
  }
 
  public static String getRealHost(String host, int port)
  {
    if (enable > 0)
    {
      ResolveOptions option = new ResolveOptions();
      option.cacheTtl = ResolveOptions.DNS_CACHE_TTL_SELF;
      try
      {
        String[] hosts = Resolver.resolveIPv4(trustedDNS, host, option);
        for (String h : hosts)
        {
          if (isReachable(h, port))
          {
            // System.out.println("#####Get real host:" + h +
            // " for " + host);
            return h;
          }
        }
      }
      catch (NamingException e)
      {
        return host;
      }
    }
    return host;
  }
 
  public static boolean init()
  {
    IniProperties cfg = SnovaConfiguration.getInstance().getIniProperties();
    enable = cfg.getIntProperty("Hosts", "Enable", 1);
    String dns = cfg.getProperty("Hosts", "TrustedDNS");
    if (null != dns)
    {
      trustedDNS = dns.split("\\|");
    }
    loadHostFile("cloud_hosts.conf");
    loadHostFile("user_hosts.conf");
    SharedObjectHelper.getGlobalThreadPool().submit(new Runnable()
    {
      public void run()
      {
        IniProperties cfg = SnovaConfiguration.getInstance()
                .getIniProperties();
        String content = MiscHelper.fetchContent(cfg.getProperty(
                "Hosts", "CloudHosts"));
        if (!StringHelper.isEmptyString(content))
        {
          FileManager.writeFile(content, "conf/cloud_hosts.conf");
        }
        loadHostFile("cloud_hosts.conf");
        loadHostFile("user_hosts.conf");
      }
    });
    return true;
  }
}
TOP

Related Classes of org.snova.framework.proxy.hosts.HostsService

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.