hmuxdispatchrequest.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 478 行

JAVA
478
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.server.hmux;import com.caucho.log.Log;import com.caucho.server.cluster.Cluster;import com.caucho.server.cluster.ClusterPort;import com.caucho.server.cluster.ClusterServer;import com.caucho.server.cluster.Server;import com.caucho.server.host.Host;import com.caucho.server.webapp.WebApp;import com.caucho.server.webapp.WebAppController;import com.caucho.util.*;import com.caucho.vfs.ReadStream;import com.caucho.vfs.WriteStream;import java.io.IOException;import java.util.ArrayList;import java.util.logging.Level;import java.util.logging.Logger;/** * Handles the filter mapping (config) requests from a remote dispatcher. */public class HmuxDispatchRequest {  private static final Logger log = Log.open(HmuxDispatchRequest.class);  // other, specialized protocols  public static final int HMUX_HOST =      'h';  public static final int HMUX_QUERY_ALL = 'q';  public static final int HMUX_QUERY_URL = 'r';  public static final int HMUX_QUERY_SERVER = 's';  public static final int HMUX_WEB_APP =   'a';  public static final int HMUX_MATCH =     'm';  public static final int HMUX_IGNORE =    'i';  public static final int HMUX_ETAG =      'e';  public static final int HMUX_NO_CHANGE = 'n';  public static final int HMUX_CLUSTER =   'c';  public static final int HMUX_SRUN    =   's';  public static final int HMUX_SRUN_BACKUP = 'b';  public static final int HMUX_SRUN_SSL = 'e';  public static final int HMUX_UNAVAILABLE = 'u';  public static final int HMUX_WEB_APP_UNAVAILABLE = 'U';  private CharBuffer _cb = new CharBuffer();  private HmuxRequest _request;  private Server _server;  private int _srunIndex;  public HmuxDispatchRequest(HmuxRequest request)  {    _request = request;    _server = (Server) request.getDispatchServer();  }  /**   * Handles a new request.  Initializes the protocol handler and   * the request streams.   *   * <p>Note: ClientDisconnectException must be rethrown to   * the caller.   */  public boolean handleRequest(ReadStream is, WriteStream os)    throws IOException  {    CharBuffer cb = _cb;    boolean isLoggable = log.isLoggable(Level.FINE);    int code;    int len;    String host = "";    String etag = null;    while (true) {      code = is.read();      switch (code) {      case -1:        if (isLoggable)          log.fine(dbgId() + "end of file");        return false;      case HmuxRequest.HMUX_QUIT:        if (isLoggable)          log.fine(dbgId() + (char) code + ": end of request");        return true;      case HmuxRequest.HMUX_EXIT:        if (isLoggable)          log.fine(dbgId() + (char) code + ": end of socket");        return false;      case HMUX_ETAG:        len = (is.read() << 8) + is.read();	_cb.clear();	is.readAll(_cb, len);	etag = _cb.toString();	if (isLoggable)	  log.fine(dbgId() + "etag: " + etag);        break;      case HMUX_HOST:        len = (is.read() << 8) + is.read();	_cb.clear();	is.readAll(_cb, len);	host = _cb.toString();	if (isLoggable)	  log.fine(dbgId() + "host: " + host);        break;      case HMUX_QUERY_ALL:        len = (is.read() << 8) + is.read();	_cb.clear();	is.readAll(_cb, len);	if (isLoggable)	  log.fine(dbgId() + "query: " + _cb);        queryAll(os, host, _cb.toString(), etag);        break;	/*      case HMUX_QUERY_SERVER:        len = (is.read() << 8) + is.read();	_cb.clear();	is.readAll(_cb, len);	if (isLoggable)	  log.fine(dbgId() + "query-server: " + _cb);        queryCluster(os, host, _cb.toString());        break;	*/              default:        len = (is.read() << 8) + is.read();	if (isLoggable)	  log.fine(dbgId() + (char) code + " " + len + " (dispatch)");	is.skip(len);	break;      }    }    // _filter.setClientClosed(true);    // return false;  }    /**   * Returns the url.   */  private void queryAll(WriteStream os, String hostName,			String url, String etag)    throws IOException  {    int channel = 2;    boolean isLoggable = log.isLoggable(Level.FINE);        os.write(HmuxRequest.HMUX_CHANNEL);    os.write(channel >> 8);    os.write(channel);    Host host = _server.getHost(hostName, 80);    if (host == null) {      writeString(os, HmuxRequest.HMUX_HEADER, "check-interval");      writeString(os, HmuxRequest.HMUX_STRING,		  String.valueOf(_server.getDependencyCheckInterval() / 1000));      if (isLoggable)	log.fine(dbgId() + "host '" + host + "' not configured");      return;    }    else if (! host.isActive()) {      writeString(os, HMUX_UNAVAILABLE, "");      if (isLoggable)	log.fine(dbgId() + "host '" + host + "' not active");      return;    }    if (host.getConfigETag() == null)      sendQuery(null, host, hostName, url);    if (etag == null) {    }    else if (etag.equals(host.getConfigETag())) {      if (isLoggable)	log.fine(dbgId() + "host '" + host + "' no change");            writeString(os, HMUX_NO_CHANGE, "");      return;    }    else if (etag.equals("h-" + host.getHostName())) {      if (isLoggable) {	log.fine(dbgId() + "host alias '" + hostName + " -> '"		 + host + "' no change");      }            writeString(os, HMUX_NO_CHANGE, "");      return;    }    else {      if (isLoggable)	log.fine(dbgId() + "host '" + host + "' changed");    }        sendQuery(os, host, hostName, url);  }  /**   * Writes the host data, returning the crc   */  private void sendQuery(WriteStream os, Host host,			 String hostName, String url)    throws IOException  {    boolean isLoggable = log.isLoggable(Level.FINE);        long crc64 = 0;    if (! Alarm.isTest())      crc64 = Crc64.generate(crc64, com.caucho.Version.FULL_VERSION);        queryServer(os);        writeString(os, HMUX_HOST, host.getHostName());    if (hostName.equals(host.getHostName())) {      crc64 = queryCluster(os, host, crc64);            WebAppController controller = host.findByURI(url);      if (controller != null) {	try {	  controller.request();	} catch (Throwable e) {	  log.log(Level.WARNING, e.toString(), e);	}      }      ArrayList<WebAppController> appList = host.getWebAppList();      for (int i = 0; i < appList.size(); i++) {	WebAppController appEntry = appList.get(i);	if (appEntry.getParent() != null &&	    appEntry.getParent().isDynamicDeploy()) {	  continue;	}		writeString(os, HMUX_WEB_APP, appEntry.getContextPath());	if (isLoggable)	  log.fine(dbgId() + "web-app '" + appEntry.getContextPath() + "'");	crc64 = Crc64.generate(crc64, appEntry.getContextPath());	WebApp app = appEntry.getWebApp();	if (appEntry.isDynamicDeploy()) {	  writeString(os, HMUX_MATCH, "/*");		  crc64 = Crc64.generate(crc64, "/*");	  	  if (isLoggable)	    log.fine(dbgId() + "dynamic '" + appEntry.getContextPath() + "'");	}	else if (app == null || ! app.isActive()) {	  if (isLoggable)	    log.fine(dbgId() + "not active '" + appEntry.getContextPath() + "'");	  	  writeString(os, HMUX_WEB_APP_UNAVAILABLE, "");	}	else {	  if (isLoggable)	    log.fine(dbgId() + "active '" + appEntry.getContextPath() + "'");	  ArrayList<String> patternList = app.getServletMappingPatterns();	  for (int j = 0; patternList != null && j < patternList.size(); j++) {	    String pattern = patternList.get(j);	    writeString(os, HMUX_MATCH, pattern);	  	    crc64 = Crc64.generate(crc64, pattern);	  }	  	  patternList = app.getServletIgnoreMappingPatterns();	  for (int j = 0; patternList != null && j < patternList.size(); j++) {	    String pattern = patternList.get(j);	    writeString(os, HMUX_IGNORE, pattern);	  	    crc64 = Crc64.generate(crc64, "i");	    crc64 = Crc64.generate(crc64, pattern);	  }	}      }      CharBuffer cb = new CharBuffer();      Base64.encode(cb, crc64);      String newETag = cb.close();      host.setConfigETag(newETag);          writeString(os, HMUX_ETAG, host.getConfigETag());    }    else {      // aliased hosts use the host name as the etag      writeString(os, HMUX_ETAG, "h-" + host.getHostName());    }  }    /**   * Queries the cluster.   */  private long queryCluster(WriteStream os, Host host, long crc64)    throws IOException  {    /*    int channel = 2;        os.write(HmuxRequest.HMUX_CHANNEL);    os.write(channel >> 8);    os.write(channel);    */    Cluster cluster = host.getCluster();    if (cluster == null)      return 0;    writeString(os, HMUX_CLUSTER, cluster.getId());    crc64 = Crc64.generate(crc64, cluster.getId());    ClusterServer []servers = cluster.getServerList();    if (servers.length > 0) {      ClusterServer server = servers[0];      writeString(os, HmuxRequest.HMUX_HEADER, "live-time");      writeString(os, HmuxRequest.HMUX_STRING, "" + (server.getLoadBalanceIdleTime() / 1000));      writeString(os, HmuxRequest.HMUX_HEADER, "dead-time");      writeString(os, HmuxRequest.HMUX_STRING, "" + (server.getLoadBalanceRecoverTime() / 1000));          writeString(os, HmuxRequest.HMUX_HEADER, "read-timeout");      writeString(os, HmuxRequest.HMUX_STRING, "" + (server.getLoadBalanceSocketTimeout() / 1000));    }    for (int i = 0; i < servers.length; i++) {      ClusterServer server = servers[i];      if (server != null && server.getClusterPort() != null) {	ClusterPort port = server.getClusterPort();		String srunHost = port.getAddress() + ":" + port.getPort();	/*	if (server.isBackup())	  writeString(os, HMUX_SRUN_BACKUP, srunHost);	else	*/	if (server.isSSL())	  writeString(os, HMUX_SRUN_SSL, srunHost);	else	  writeString(os, HMUX_SRUN, srunHost);      	crc64 = Crc64.generate(crc64, srunHost);      }    }    return crc64;  }    /**   * Queries the cluster.   */  private void queryServer(WriteStream os)    throws IOException  {    writeString(os, HmuxRequest.HMUX_HEADER, "check-interval");    writeString(os, HmuxRequest.HMUX_STRING,		String.valueOf(_server.getDependencyCheckInterval() / 1000));        writeString(os, HmuxRequest.HMUX_HEADER, "cookie");    writeString(os, HmuxRequest.HMUX_STRING,		_server.getSessionCookie());    writeString(os, HmuxRequest.HMUX_HEADER, "ssl-cookie");    writeString(os, HmuxRequest.HMUX_STRING,		_server.getSSLSessionCookie());    writeString(os, HmuxRequest.HMUX_HEADER, "session-url-prefix");    writeString(os, HmuxRequest.HMUX_STRING,		_server.getSessionURLPrefix());    writeString(os, HmuxRequest.HMUX_HEADER, "alt-session-url-prefix");    writeString(os, HmuxRequest.HMUX_STRING,		_server.getAlternateSessionURLPrefix());    if (_server.getConnectionErrorPage() != null) {      writeString(os, HmuxRequest.HMUX_HEADER, "connection-error-page");      writeString(os, HmuxRequest.HMUX_STRING,		  _server.getConnectionErrorPage());    }  }  void writeString(WriteStream os, int code, String value)    throws IOException  {    if (os == null)      return;        if (value == null)      value = "";        int len = value.length();    os.write(code);    os.write(len >> 8);    os.write(len);    os.print(value);        if (log.isLoggable(Level.FINE))      log.fine(dbgId() + (char)code + " " + value);  }  void writeString(WriteStream os, int code, CharBuffer value)    throws IOException  {    if (os == null)      return;        int len = value.length();    os.write(code);    os.write(len >> 8);    os.write(len);    os.print(value);        if (log.isLoggable(Level.FINE))      log.fine(dbgId() + (char)code + " " + value);  }  private String dbgId()  {    return _request.dbgId();  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?