1 29 30 package com.caucho.server.hmux; 31 32 import com.caucho.log.Log; 33 import com.caucho.server.cluster.Cluster; 34 import com.caucho.server.cluster.ClusterPort; 35 import com.caucho.server.cluster.ClusterServer; 36 import com.caucho.server.cluster.Server; 37 import com.caucho.server.host.Host; 38 import com.caucho.server.webapp.WebApp; 39 import com.caucho.server.webapp.WebAppController; 40 import com.caucho.util.*; 41 import com.caucho.vfs.ReadStream; 42 import com.caucho.vfs.WriteStream; 43 44 import java.io.IOException ; 45 import java.util.ArrayList ; 46 import java.util.logging.Level ; 47 import java.util.logging.Logger ; 48 49 52 public class HmuxDispatchRequest { 53 private static final Logger log = Log.open(HmuxDispatchRequest.class); 54 55 public static final int HMUX_HOST = 'h'; 57 public static final int HMUX_QUERY_ALL = 'q'; 58 public static final int HMUX_QUERY_URL = 'r'; 59 public static final int HMUX_QUERY_SERVER = 's'; 60 public static final int HMUX_WEB_APP = 'a'; 61 public static final int HMUX_MATCH = 'm'; 62 public static final int HMUX_IGNORE = 'i'; 63 public static final int HMUX_ETAG = 'e'; 64 public static final int HMUX_NO_CHANGE = 'n'; 65 public static final int HMUX_CLUSTER = 'c'; 66 public static final int HMUX_SRUN = 's'; 67 public static final int HMUX_SRUN_BACKUP = 'b'; 68 69 private CharBuffer _cb = new CharBuffer(); 70 71 private HmuxRequest _request; 72 private Server _server; 73 74 private int _srunIndex; 75 76 public HmuxDispatchRequest(HmuxRequest request) 77 { 78 _request = request; 79 80 _server = (Server) request.getDispatchServer(); 81 } 82 83 90 public boolean handleRequest(ReadStream is, WriteStream os) 91 throws IOException 92 { 93 CharBuffer cb = _cb; 94 boolean isLoggable = log.isLoggable(Level.FINE); 95 int code; 96 int len; 97 String host = ""; 98 String etag = null; 99 100 while (true) { 101 code = is.read(); 102 103 switch (code) { 104 case -1: 105 if (isLoggable) 106 log.fine(dbgId() + "end of file"); 107 return false; 108 109 case HmuxRequest.HMUX_QUIT: 110 if (isLoggable) 111 log.fine(dbgId() + (char) code + ": end of request"); 112 return true; 113 114 case HmuxRequest.HMUX_EXIT: 115 if (isLoggable) 116 log.fine(dbgId() + (char) code + ": end of socket"); 117 118 return false; 119 120 case HMUX_ETAG: 121 len = (is.read() << 8) + is.read(); 122 _cb.clear(); 123 is.readAll(_cb, len); 124 etag = _cb.toString(); 125 126 if (isLoggable) 127 log.fine(dbgId() + "etag: " + etag); 128 break; 129 130 case HMUX_HOST: 131 len = (is.read() << 8) + is.read(); 132 _cb.clear(); 133 is.readAll(_cb, len); 134 host = _cb.toString(); 135 136 if (isLoggable) 137 log.fine(dbgId() + "host: " + host); 138 break; 139 140 case HMUX_QUERY_ALL: 141 len = (is.read() << 8) + is.read(); 142 _cb.clear(); 143 is.readAll(_cb, len); 144 145 if (isLoggable) 146 log.fine(dbgId() + "query: " + _cb); 147 148 queryAll(os, host, _cb.toString(), etag); 149 break; 150 151 163 164 default: 165 len = (is.read() << 8) + is.read(); 166 167 if (isLoggable) 168 log.fine(dbgId() + (char) code + " " + len + " (dispatch)"); 169 is.skip(len); 170 break; 171 } 172 } 173 174 176 } 178 179 182 private void queryAll(WriteStream os, String hostName, 183 String url, String etag) 184 throws IOException 185 { 186 int channel = 2; 187 boolean isLoggable = log.isLoggable(Level.FINE); 188 189 os.write(HmuxRequest.HMUX_CHANNEL); 190 os.write(channel >> 8); 191 os.write(channel); 192 193 Host host = _server.getHost(hostName, 80); 194 if (host == null) { 195 writeString(os, HmuxRequest.HMUX_HEADER, "check-interval"); 196 writeString(os, HmuxRequest.HMUX_STRING, 197 String.valueOf(_server.getDependencyCheckInterval() / 1000)); 198 writeString(os, HMUX_WEB_APP, ""); 199 200 if (isLoggable) 201 log.fine(dbgId() + "host '" + host + "' not configured"); 202 return; 203 } 204 else if (! host.isActive()) { 205 if (etag == null) { 206 writeString(os, HMUX_WEB_APP, ""); 208 writeString(os, HMUX_MATCH, "/*"); 209 } 210 else { 211 sendQuery(null, host, hostName, url); 212 213 writeString(os, HMUX_NO_CHANGE, ""); 214 } 215 216 if (isLoggable) 217 log.fine(dbgId() + "host '" + host + "' not active"); 218 return; 219 } 220 221 if (host.getConfigETag() == null) 222 sendQuery(null, host, hostName, url); 223 224 if (etag == null) { 225 } 226 else if (etag.equals(host.getConfigETag())) { 227 if (isLoggable) 228 log.fine(dbgId() + "host '" + host + "' no change"); 229 230 writeString(os, HMUX_NO_CHANGE, ""); 231 return; 232 } 233 else { 234 if (isLoggable) 235 log.fine(dbgId() + "host '" + host + "' changed"); 236 } 237 238 sendQuery(os, host, hostName, url); 239 } 240 241 244 private void sendQuery(WriteStream os, Host host, 245 String hostName, String url) 246 throws IOException 247 { 248 boolean isLoggable = log.isLoggable(Level.FINE); 249 250 long crc64 = 0; 251 252 if (! Alarm.isTest()) 253 crc64 = Crc64.generate(crc64, com.caucho.Version.FULL_VERSION); 254 255 queryServer(os); 256 257 writeString(os, HMUX_HOST, host.getHostName()); 258 259 if (hostName.equals(host.getHostName())) { 260 crc64 = queryCluster(os, host, crc64); 261 262 WebAppController controller = host.findByURI(url); 263 if (controller != null) { 264 try { 265 controller.request(); 266 } catch (Throwable e) { 267 log.log(Level.WARNING, e.toString(), e); 268 } 269 } 270 271 ArrayList <WebAppController> appList = host.getWebAppList(); 272 273 for (int i = 0; i < appList.size(); i++) { 274 WebAppController appEntry = appList.get(i); 275 276 if (appEntry.getParent() != null && 277 appEntry.getParent().isDynamicDeploy()) { 278 continue; 279 } 280 281 writeString(os, HMUX_WEB_APP, appEntry.getContextPath()); 282 if (isLoggable) 283 log.fine(dbgId() + "web-app '" + appEntry.getContextPath() + "'"); 284 285 crc64 = Crc64.generate(crc64, appEntry.getContextPath()); 286 287 WebApp app = appEntry.getWebApp(); 288 289 if (appEntry.isDynamicDeploy()) { 290 writeString(os, HMUX_MATCH, "/*"); 291 292 crc64 = Crc64.generate(crc64, "/*"); 293 294 if (isLoggable) 295 log.fine(dbgId() + "dynamic '" + appEntry.getContextPath() + "'"); 296 } 297 else if (app == null || ! app.isActive()) { 298 if (isLoggable) 299 log.fine(dbgId() + "not active '" + appEntry.getContextPath() + "'"); 300 301 writeString(os, HMUX_NO_CHANGE, ""); 302 } 303 else { 304 if (isLoggable) 305 log.fine(dbgId() + "active '" + appEntry.getContextPath() + "'"); 306 ArrayList <String > patternList = app.getServletMappingPatterns(); 307 308 for (int j = 0; patternList != null && j < patternList.size(); j++) { 309 String pattern = patternList.get(j); 310 311 writeString(os, HMUX_MATCH, pattern); 312 313 crc64 = Crc64.generate(crc64, pattern); 314 } 315 316 patternList = app.getServletIgnoreMappingPatterns(); 317 318 for (int j = 0; patternList != null && j < patternList.size(); j++) { 319 String pattern = patternList.get(j); 320 321 writeString(os, HMUX_IGNORE, pattern); 322 323 crc64 = Crc64.generate(crc64, "i"); 324 crc64 = Crc64.generate(crc64, pattern); 325 } 326 } 327 } 328 329 CharBuffer cb = new CharBuffer(); 330 Base64.encode(cb, crc64); 331 String newETag = cb.close(); 332 host.setConfigETag(newETag); 333 } 334 335 writeString(os, HMUX_ETAG, host.getConfigETag()); 336 } 337 338 341 private long queryCluster(WriteStream os, Host host, long crc64) 342 throws IOException 343 { 344 351 352 Cluster cluster = host.getCluster(); 353 354 if (cluster == null) 355 return 0; 356 357 writeString(os, HMUX_CLUSTER, cluster.getId()); 358 359 crc64 = Crc64.generate(crc64, cluster.getId()); 360 361 writeString(os, HmuxRequest.HMUX_HEADER, "live-time"); 362 writeString(os, HmuxRequest.HMUX_STRING, "" + (cluster.getClientMaxIdleTime() / 1000)); 363 364 writeString(os, HmuxRequest.HMUX_HEADER, "dead-time"); 365 writeString(os, HmuxRequest.HMUX_STRING, "" + (cluster.getClientFailRecoverTime() / 1000)); 366 367 ClusterServer []servers = cluster.getServerList(); 368 369 for (int i = 0; i < servers.length; i++) { 370 ClusterServer server = servers[i]; 371 372 if (server != null && server.getClusterPort() != null) { 373 ClusterPort port = server.getClusterPort(); 374 375 String srunHost = port.getAddress() + ":" + port.getPort(); 376 377 382 writeString(os, HMUX_SRUN, srunHost); 383 384 crc64 = Crc64.generate(crc64, srunHost); 385 } 386 } 387 388 return crc64; 389 } 390 391 394 private void queryServer(WriteStream os) 395 throws IOException 396 { 397 writeString(os, HmuxRequest.HMUX_HEADER, "check-interval"); 398 writeString(os, HmuxRequest.HMUX_STRING, 399 String.valueOf(_server.getDependencyCheckInterval() / 1000)); 400 401 writeString(os, HmuxRequest.HMUX_HEADER, "cookie"); 402 writeString(os, HmuxRequest.HMUX_STRING, 403 _server.getSessionCookie()); 404 writeString(os, HmuxRequest.HMUX_HEADER, "ssl-cookie"); 405 writeString(os, HmuxRequest.HMUX_STRING, 406 _server.getSSLSessionCookie()); 407 writeString(os, HmuxRequest.HMUX_HEADER, "session-url-prefix"); 408 writeString(os, HmuxRequest.HMUX_STRING, 409 _server.getSessionURLPrefix()); 410 writeString(os, HmuxRequest.HMUX_HEADER, "alt-session-url-prefix"); 411 writeString(os, HmuxRequest.HMUX_STRING, 412 _server.getAlternateSessionURLPrefix()); 413 414 if (_server.getConnectionErrorPage() != null) { 415 writeString(os, HmuxRequest.HMUX_HEADER, "connection-error-page"); 416 writeString(os, HmuxRequest.HMUX_STRING, 417 _server.getConnectionErrorPage()); 418 } 419 } 420 421 void writeString(WriteStream os, int code, String value) 422 throws IOException 423 { 424 if (os == null) 425 return; 426 427 if (value == null) 428 value = ""; 429 430 int len = value.length(); 431 432 os.write(code); 433 os.write(len >> 8); 434 os.write(len); 435 os.print(value); 436 437 if (log.isLoggable(Level.FINE)) 438 log.fine(dbgId() + (char)code + " " + value); 439 } 440 441 void writeString(WriteStream os, int code, CharBuffer value) 442 throws IOException 443 { 444 if (os == null) 445 return; 446 447 int len = value.length(); 448 449 os.write(code); 450 os.write(len >> 8); 451 os.write(len); 452 os.print(value); 453 454 if (log.isLoggable(Level.FINE)) 455 log.fine(dbgId() + (char)code + " " + value); 456 } 457 458 private String dbgId() 459 { 460 return _request.dbgId(); 461 } 462 } 463 | Popular Tags |