예제 #1
0
  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;
    }
  }
예제 #2
0
/* 自サーバの/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) {}
}
예제 #3
0
 private static Config getConfig() {
   if (config == null) {
     config = Config.getConfig();
   }
   return config;
 }
예제 #4
0
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);
  }
}