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 + -
显示快捷键?