Exemple #1
0
 private void setupAuthUrl(Mapping mapping) {
   authMapping = mapping;
   Authorizer authorizer = config.getAuthorizer();
   String selfDomain = config.getString("selfDomain");
   String realHostName = mapping.getRealHostName();
   RealHost realHost = RealHost.getRealHost(realHostName);
   if (realHost == null) {
     logger.warn("not found auth mapping realHost.realHostName:" + realHostName);
     return;
   }
   authorizer.setupAuthUrl(
       (mapping.getSecureType() == SecureType.SSL),
       mapping.getSourcePath(),
       selfDomain,
       realHost.getBindPort());
 }
 public long getInjectLength() {
   if (injectContext != null) {
     InjectionHelper helper = config.getInjectionHelper();
     return helper.getInjectContentsLength(injectContext);
   }
   return 0;
 }
 private synchronized void addWsClient() {
   if (stat != Stat.INC) {
     return;
   }
   int size = clients.size();
   if ((size % 100) == 0 || size == count) {
     publish(size, failCount, false);
   }
   if (size >= count) {
     if (timerId == TimerManager.INVALID_ID) {
       stop();
     } else {
       stat = Stat.KEEP;
     }
     return;
   }
   WsClientHandler wsClientHandler =
       WsClientHandler.create(false, config.getSelfDomain(), config.getInt(Config.SELF_PORT));
   wsClientHandler.ref();
   wsClientHandler.startRequest(
       this, wsClientHandler, 10000, "/connect", "connect", config.getAdminUrl());
   clients.add(wsClientHandler);
 }
  public void startResponseReqBody() {
    MappingResult mapping = getRequestMapping();
    if (Boolean.TRUE.equals(mapping.getOption("replay"))) {
      ReplayHelper helper = Config.getConfig().getReplayHelper();
      //			ByteBuffer[] body=bodyPage.getBuffer();
      if (helper.doReplay(this, null)) {
        return; // replayできた,bodyは消費されている
      }
    }

    if (response()) {
      responseEnd(); // TODO必要ないと思う
      return;
    }
  }
  // 存在確認済みのディレクトリを一覧レスポンスする。
  private boolean snedFileList(MappingResult mapping, String uri, File dir, boolean isBase) {
    if (!uri.endsWith("/")) {
      uri = uri + "/";
    }
    setRequestAttribute("isBase", isBase);
    setRequestAttribute("base", uri);
    try {
      setRequestAttribute("source", dir.getCanonicalFile());
    } catch (IOException e) {
      setRequestAttribute("source", null);
    }
    setRequestAttribute("fileList", dir.listFiles());

    setRequestAttribute(ATTRIBUTE_VELOCITY_ENGINE, config.getVelocityEngine());
    setRequestAttribute(ATTRIBUTE_VELOCITY_TEMPLATE, LISTING_TEMPLATE);
    forwardHandler(Mapping.VELOCITY_PAGE_HANDLER);
    return false; // 委譲
  }
/* 自サーバの/connection WebScoketに接続する */
public class ConnectChecker implements Timer, WsClient {
  private static Logger logger = Logger.getLogger(ConnectChecker.class);
  private static Config config = Config.getConfig();
  private static ConnectChecker instance = new ConnectChecker();

  private enum Stat {
    READY,
    STARTING,
    INC, // connection増加中
    KEEP, // 保持中
    DEC, // connection切断中
  }

  private List<WsClientHandler> clients = new ArrayList<WsClientHandler>();
  private int failCount;
  private PaPeer peer;
  private int count;
  private int maxFailCount;
  private Stat stat = Stat.READY;
  private long timerId;
  private long startTime;

  public static boolean start(int count, int maxFailCount, long timeout, PaPeer peer) {
    if (instance.init(count, maxFailCount, peer) == false) {
      return false;
    }
    instance.run(timeout);
    return true;
  }

  public static void end() {
    instance.stop();
  }

  private synchronized boolean init(int count, int maxFailCount, PaPeer peer) {
    if (stat != Stat.READY) {
      logger.error("aleady start." + stat);
      //			queueManager.complete(chId, null);
      return false;
    }
    if (this.peer != null) {
      this.peer.unref();
    }
    if (peer != null) {
      peer.ref();
    }
    this.peer = peer;
    this.count = count;
    this.maxFailCount = maxFailCount;
    this.failCount = 0;
    // this.paManager=config.getAdminPaManager();
    if (count > 0) {
      stat = Stat.INC;
    } else {
      stat = Stat.KEEP;
    }
    return true;
  }

  private static Runtime runtime = Runtime.getRuntime();

  private void publish(int count, int failCount, boolean isComplete) {
    JSONObject eventObj = new JSONObject();
    eventObj.put("kind", "checkConnectProgress");
    eventObj.put("time", (System.currentTimeMillis() - startTime));
    eventObj.put("connectCount", count);
    eventObj.put("failCount", failCount);
    eventObj.put("useMemory", (runtime.totalMemory() - runtime.freeMemory()));
    eventObj.put("stat", stat);
    peer.message(eventObj);
    if (isComplete) {
      peer.unref();
      peer = null;
    }
  }

  private synchronized void addWsClient() {
    if (stat != Stat.INC) {
      return;
    }
    int size = clients.size();
    if ((size % 100) == 0 || size == count) {
      publish(size, failCount, false);
    }
    if (size >= count) {
      if (timerId == TimerManager.INVALID_ID) {
        stop();
      } else {
        stat = Stat.KEEP;
      }
      return;
    }
    WsClientHandler wsClientHandler =
        WsClientHandler.create(false, config.getSelfDomain(), config.getInt(Config.SELF_PORT));
    wsClientHandler.ref();
    wsClientHandler.startRequest(
        this, wsClientHandler, 10000, "/connect", "connect", config.getAdminUrl());
    clients.add(wsClientHandler);
  }

  private synchronized void delWsClient(WsClientHandler wsClientHandler, boolean isFail) {
    clients.remove(wsClientHandler);
    wsClientHandler.unref();
    int size = clients.size();
    if (isFail) {
      failCount++;
      if (failCount >= maxFailCount) {
        publish(size, failCount, false);
        stop();
        return;
      }
    }
    switch (stat) {
      case INC:
        addWsClient();
        break;
      case DEC:
        if ((size % 100) == 0) {
          publish(size, failCount, false);
        }
        sendStop();
        break;
    }
  }

  private void sendStop() {
    Iterator<WsClientHandler> itr = clients.iterator();
    if (itr.hasNext()) {
      WsClientHandler client = itr.next();
      client.postMessage("doClose");
    } else { // clientsが空
      stat = Stat.READY;
      publish(0, failCount, true);
    }
  }

  private void run(long timeout) {
    startTime = System.currentTimeMillis();
    if (timeout > 0) {
      timerId = TimerManager.setTimeout(timeout, this, null);
    } else {
      timerId = TimerManager.INVALID_ID;
    }
    addWsClient();
  }

  private synchronized void stop() {
    if (stat == Stat.DEC || stat == Stat.READY) {
      logger.warn("aleady stoped");
      return;
    }
    stat = Stat.DEC;
    sendStop();
  }

  /*
  public void postAll(){
  	String now=Long.toString(System.currentTimeMillis());
  	synchronized(this){
  		if(isStop){
  			logger.warn("ConnectChecker was stoped");
  			return;
  		}
  		isStop=true;
  		for(WsClientHandler client:clients){
  			client.postMessage(now);
  		}
  	}
  }
  */

  public void onTimer(Object userContext) {
    timerId = TimerManager.INVALID_ID;
    int curCount;
    synchronized (this) {
      curCount = clients.size();
    }
    publish(curCount, failCount, false);
    stop();
  }

  @Override
  public void onWcClose(Object userContext, int stat, short closeCode, String closeReason) {
    WsClientHandler wsClientHandler = (WsClientHandler) userContext;
    delWsClient(wsClientHandler, false);
  }

  @Override
  public void onWcConnected(Object userContext) {}

  @Override
  public void onWcFailure(Object userContext, int stat, Throwable t) {
    logger.info("#wcFailure", t);
    WsClientHandler wsClientHandler = (WsClientHandler) userContext;
    delWsClient(wsClientHandler, true);
  }

  @Override
  public void onWcHandshaked(Object userContext, String subprotocol) {}

  @Override
  public void onWcMessage(Object userContext, String message) {
    if ("OK".equals(message)) {
      addWsClient();
      return;
    }
    long sendTime = Long.parseLong(message);
    long now = System.currentTimeMillis();
  }

  @Override
  public void onWcMessage(Object userContext, CacheBuffer message) {}

  @Override
  public void onWcProxyConnected(Object userContext) {}

  @Override
  public void onWcResponseHeader(Object userContext, HeaderParser responseHeader) {}

  @Override
  public void onWcSslHandshaked(Object userContext) {}

  @Override
  public void onWcWrittenHeader(Object userContext) {}
}
 private static Config getConfig() {
   if (config == null) {
     config = Config.getConfig();
   }
   return config;
 }
Exemple #8
0
  private void loadMapping(Mapping mapping) {
    entryMappings.add(mapping);
    if (!mapping.isEnabled()) {
      return;
    }
    if (Boolean.FALSE.equals(mapping.getOption(OPTION_PEEK))) {
      synchronized (activeSslProxyMappings) { // ssl proxyは特殊なため別管理
        activeSslProxyMappings.add(mapping);
      }
    } else {
      synchronized (activeMappings) {
        activeMappings.add(mapping);
      }
    }
    String selfDomain = config.getSelfDomain();
    RealHost realHost = RealHost.getRealHost(mapping.getRealHostName());
    if (Boolean.TRUE.equals(mapping.getOption(OPTION_ADMIN_HANDLER))) {
      StringBuilder sb = new StringBuilder();
      String sourceServer = mapping.getSourceServer();
      if (sourceServer == null || "".equals(sourceServer)) {
        sourceServer = selfDomain;
      }
      if (mapping.getSecureType() == SecureType.SSL) {
        sb.append("https://");
      } else {
        sb.append("http://");
      }
      sb.append(sourceServer);
      sb.append(":");
      sb.append(realHost.getBindPort());
      sb.append(mapping.getSourcePath());
      adminUrl = sb.toString();
      System.out.println("adminUrl:" + adminUrl);
    }

    Object publicWeb = mapping.getOption(OPTION_PUBLIC_WEB); // publicWebのportとプロトコルを知るため
    if (Boolean.TRUE.equals(publicWeb)) {
      StringBuilder sb = new StringBuilder();
      String sourceServer = mapping.getSourceServer();
      if (sourceServer == null || "".equals(sourceServer)) {
        sourceServer = selfDomain;
      }
      if (mapping.getSecureType() == SecureType.SSL) {
        sb.append("https://");
      } else {
        sb.append("http://");
      }
      sb.append(sourceServer);
      sb.append(":");
      sb.append(realHost.getBindPort());
      sb.append(mapping.getSourcePath());
      publicWebUrl = sb.toString();
    }
    // pacは複数のmappingにあってよいが、そのrealHostは同一である事
    //		Object authHandler=mapping.getOption(OPTION_AUTH_HANDLER);
    if (AuthHandler.class.getName().equals(mapping.getDestinationServer())) {
      setupAuthUrl(mapping); // authorizerにauthマッピング定義を教える
    }

    // mapping auth定義
    Object auth = mapping.getOption(OPTION_AUTH);
    if (auth != null && auth instanceof JSONObject) {
      MappingAuth mappingAuth = new MappingAuth(config.getAuthenticator());
      if (mappingAuth.init((JSONObject) auth, mapping.getSourceType() == SourceType.PROXY)) {
        mapping.setMappingAuth(mappingAuth);
      }
    }

    Object pac = mapping.getOption(OPTION_PAC); // pacに反映するか否か
    if (!Boolean.TRUE.equals(pac)) {
      return;
    }
    switch (mapping.getSourceType()) {
      case PROXY:
        switch (mapping.getSecureType()) {
          case PLAIN:
            httpPhantomDomains.add(mapping.getSourceServerHost());
            pacProxyPort = realHost.getBindPort();
            break;
          case SSL:
            securePhantomDomains.add(mapping.getSourceServerHost());
            pacProxyPort = realHost.getBindPort();
            break;
        }
        break;
      case WEB:
    }
  }
  public void onResponseHeader(HeaderParser responseHeader) {
    InjectionHelper helper = config.getInjectionHelper();

    MappingResult mapping = proxyHandler.getRequestMapping();
    HeaderParser requestHeader = proxyHandler.getRequestHeader();
    String WebAuthReplaceMark = requestHeader.getHeader(REPLACE_MARK_HEADER);
    String resolveUrl = mapping.getResolveUrl();
    if (WebAuthReplaceMark == null) {
      portalSession.endBasicProcess(resolveUrl);
    }
    String statusCode = responseHeader.getStatusCode();
    if ("401".equals(statusCode) /*&&injectContext==null*/) {
      mapping.getResolveDomain();
      String authentication = responseHeader.getHeader(HeaderParser.WWW_AUTHENTICATE_HEADER);
      if (authentication == null) {
        return;
      }
      Matcher matcher;
      synchronized (authenticationPattern) {
        matcher = authenticationPattern.matcher(authentication);
      }
      if (!matcher.find()) {
        return; // Digestはここでチェックあうと
      }
      String realm = matcher.group(1);

      // 自分の持っている代理ログイン情報で、domain,realmに合致するものはないか?
      String resolveDomain = mapping.getResolveDomain();
      CommissionAuth basicCommissionAuth = portalSession.getBasicAuth(resolveDomain, realm);
      if (WebAuthReplaceMark == null
          && !portalSession.startBasicProcess(resolveUrl, basicCommissionAuth)) {
        return;
      }
      if (basicCommissionAuth == null || basicCommissionAuth.isEnabled()) {
        String authrization = requestHeader.getHeader(HeaderParser.WWW_AUTHORIZATION_HEADER);
        if (WebAuthReplaceMark == null) { // ブラウザから直接出されたリクエスト
          responseHeader.setStatusCode("200");
          proxyHandler.removeResponseHeader(HeaderParser.WWW_AUTHENTICATE_HEADER);
          portalSession.putRealm(resolveUrl, realm);
          proxyHandler.setReplace(true);
          injectContext = helper.getReplaceContext("WebAuthReplace.html");
          proxyHandler.addResponseHeader(
              HeaderParser.CONTENT_TYPE_HEADER, "text/html; charset=utf-8");
          proxyHandler.addResponseHeader("Pragma", "no-cache");
          proxyHandler.addResponseHeader("Cache-Control", "no-cache");
          proxyHandler.addResponseHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
        } else if (authrization != null) { // ajaxからuser/passをつけているのに401が返却された=>認証情報が無効
          responseHeader.setStatusCode("200");
          proxyHandler.removeResponseHeader(HeaderParser.WWW_AUTHENTICATE_HEADER);
          proxyHandler.addResponseHeader("WebAuthRealm", realm);
          proxyHandler.setReplace(true);
          injectContext = helper.getReplaceContext("WebAuthFail.html");
          proxyHandler.addResponseHeader(HeaderParser.CONTENT_TYPE_HEADER, "text/plain");
          proxyHandler.addResponseHeader("Pragma", "no-cache");
          proxyHandler.addResponseHeader("Cache-Control", "no-cache");
          proxyHandler.addResponseHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
        }
      }
    } else if ("200".equals(statusCode) || "404".equals(statusCode)) {
      String contentType = responseHeader.getContentType();
      if (contentType != null && contentType.startsWith("text/html")) {
        injectContext = helper.getInsertContext("PortalInject.txt");
      }
    }
  }
public class PortalInjector extends PoolBase implements ProxyInjector {
  private static Pattern portalPathInfoPattern = Pattern.compile(";phportal=([^\\s;/?]*)");
  public static final String PORTAL_PATHINFO_KEY = "portalPathInfo";
  public static final String REPLACE_MARK_HEADER = "X-PH-WebAuthReplaceMark";
  private static Config config = Config.getConfig();

  private ProxyHandler proxyHandler;
  private PortalSession portalSession;
  private Object injectContext = null;

  public void init(ProxyHandler proxyHandler) {
    this.proxyHandler = proxyHandler;
    this.portalSession = PortalSession.getPortalSession(proxyHandler);
    injectContext = null;
  }

  public void onRequestHeader(HeaderParser requestHeader) {
    /* portal機能の場合path情報にportal機能用の情報が着いている場合がある。
     * この情報は削除してproxy対象サーバにリクエスト
     */
    MappingResult mapping = proxyHandler.getRequestMapping();
    String path = mapping.getResolvePath();
    Matcher matcher = null;
    synchronized (portalPathInfoPattern) {
      matcher = portalPathInfoPattern.matcher(path);
    }
    StringBuffer sb = null;
    String portalPathInfo = null;
    if (matcher.find()) {
      sb = new StringBuffer();
      matcher.appendReplacement(sb, "");
      portalPathInfo = matcher.group(1);
      matcher.appendTail(sb);
      path = sb.toString();
      mapping.setResolvePath(path);
      requestHeader.setRequestUri(mapping.getResolvePath());
      proxyHandler.setRequestAttribute(PORTAL_PATHINFO_KEY, portalPathInfo);
    }
    /*
     * proxyでAuthrizationヘッダを付加する作戦の場合
    String basicAuthHeader = getBasicAuthHeader(mapping.isResolvedHttps(),mapping.getResolveServer());
    if (basicAuthHeader != null) {
    	requestHeader.addHeader(HeaderParser.WWW_AUTHRIZATION_HEADER, basicAuthHeader);
    	proxyHandler.setRequestAttribute(HeaderParser.WWW_AUTHRIZATION_HEADER, basicAuthHeader);
    }
     */
  }

  private static Pattern authenticationPattern =
      Pattern.compile("\\s*Basic\\s+realm\\s*=\\s*\"(.[^\"]*)\"", Pattern.CASE_INSENSITIVE);

  public void onResponseHeader(HeaderParser responseHeader) {
    InjectionHelper helper = config.getInjectionHelper();

    MappingResult mapping = proxyHandler.getRequestMapping();
    HeaderParser requestHeader = proxyHandler.getRequestHeader();
    String WebAuthReplaceMark = requestHeader.getHeader(REPLACE_MARK_HEADER);
    String resolveUrl = mapping.getResolveUrl();
    if (WebAuthReplaceMark == null) {
      portalSession.endBasicProcess(resolveUrl);
    }
    String statusCode = responseHeader.getStatusCode();
    if ("401".equals(statusCode) /*&&injectContext==null*/) {
      mapping.getResolveDomain();
      String authentication = responseHeader.getHeader(HeaderParser.WWW_AUTHENTICATE_HEADER);
      if (authentication == null) {
        return;
      }
      Matcher matcher;
      synchronized (authenticationPattern) {
        matcher = authenticationPattern.matcher(authentication);
      }
      if (!matcher.find()) {
        return; // Digestはここでチェックあうと
      }
      String realm = matcher.group(1);

      // 自分の持っている代理ログイン情報で、domain,realmに合致するものはないか?
      String resolveDomain = mapping.getResolveDomain();
      CommissionAuth basicCommissionAuth = portalSession.getBasicAuth(resolveDomain, realm);
      if (WebAuthReplaceMark == null
          && !portalSession.startBasicProcess(resolveUrl, basicCommissionAuth)) {
        return;
      }
      if (basicCommissionAuth == null || basicCommissionAuth.isEnabled()) {
        String authrization = requestHeader.getHeader(HeaderParser.WWW_AUTHORIZATION_HEADER);
        if (WebAuthReplaceMark == null) { // ブラウザから直接出されたリクエスト
          responseHeader.setStatusCode("200");
          proxyHandler.removeResponseHeader(HeaderParser.WWW_AUTHENTICATE_HEADER);
          portalSession.putRealm(resolveUrl, realm);
          proxyHandler.setReplace(true);
          injectContext = helper.getReplaceContext("WebAuthReplace.html");
          proxyHandler.addResponseHeader(
              HeaderParser.CONTENT_TYPE_HEADER, "text/html; charset=utf-8");
          proxyHandler.addResponseHeader("Pragma", "no-cache");
          proxyHandler.addResponseHeader("Cache-Control", "no-cache");
          proxyHandler.addResponseHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
        } else if (authrization != null) { // ajaxからuser/passをつけているのに401が返却された=>認証情報が無効
          responseHeader.setStatusCode("200");
          proxyHandler.removeResponseHeader(HeaderParser.WWW_AUTHENTICATE_HEADER);
          proxyHandler.addResponseHeader("WebAuthRealm", realm);
          proxyHandler.setReplace(true);
          injectContext = helper.getReplaceContext("WebAuthFail.html");
          proxyHandler.addResponseHeader(HeaderParser.CONTENT_TYPE_HEADER, "text/plain");
          proxyHandler.addResponseHeader("Pragma", "no-cache");
          proxyHandler.addResponseHeader("Cache-Control", "no-cache");
          proxyHandler.addResponseHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
        }
      }
    } else if ("200".equals(statusCode) || "404".equals(statusCode)) {
      String contentType = responseHeader.getContentType();
      if (contentType != null && contentType.startsWith("text/html")) {
        injectContext = helper.getInsertContext("PortalInject.txt");
      }
    }
  }

  public ByteBuffer[] onResponseBody(ByteBuffer[] body) {
    InjectionHelper helper = config.getInjectionHelper();
    return helper.inject(injectContext, body);
  }

  public void term() {
    unref();
  }

  public long getInjectLength() {
    if (injectContext != null) {
      InjectionHelper helper = config.getInjectionHelper();
      return helper.getInjectContentsLength(injectContext);
    }
    return 0;
  }

  public boolean isInject() {
    return (injectContext != null);
  }
}
 public ByteBuffer[] onResponseBody(ByteBuffer[] body) {
   InjectionHelper helper = config.getInjectionHelper();
   return helper.inject(injectContext, body);
 }