001 /* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2013 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028 029 package edu.wisc.ssec.mcidasv; 030 031 import ucar.unidata.idv.IntegratedDataViewer; 032 import ucar.unidata.util.HttpServer; 033 import ucar.unidata.util.LogUtil; 034 035 import java.util.Hashtable; 036 037 038 import java.net.InetAddress; 039 import java.net.Socket; 040 041 042 043 /** 044 * This provides http based access to a stack trace and enables the user to shut down McIDAS-V. 045 * This only is responsive to incoming requests from localhost 046 * the urls this provides are: 047 * http://localhost:<port>/stack.html 048 * http://localhost:<port>/info.html 049 * http://localhost:<port>/shutdown.html 050 * 051 * @author IDV development team 052 */ 053 public class McIDASVMonitor extends HttpServer { 054 055 private IntegratedDataViewer idv; 056 057 /** The localhost */ 058 private InetAddress localHost; 059 060 public McIDASVMonitor(IntegratedDataViewer idv, int port) { 061 super(port); 062 this.idv = idv; 063 } 064 065 /** 066 * Make the handler for this request. Check if the client is coming from localhost 067 * if not then return null. 068 * 069 * @param socket incoming socket 070 * @return handler or null 071 */ 072 protected RequestHandler doMakeRequestHandler(Socket socket) 073 throws Exception { 074 if (localHost == null) { 075 localHost = InetAddress.getLocalHost(); 076 } 077 InetAddress inet = socket.getInetAddress(); 078 if (! (inet.getHostAddress().equals("127.0.0.1") || inet.getHostName().equals("localhost"))) { 079 return null; 080 } 081 return new MonitorRequestHandler(idv, this, socket); 082 } 083 084 /** 085 * Class OneInstanceRequestHandler the handler 086 * 087 * 088 * @author IDV Development Team 089 * @version $Revision$ 090 */ 091 public class MonitorRequestHandler extends HttpServer.RequestHandler { 092 093 /** The idv */ 094 IntegratedDataViewer idv; 095 096 /** The socket */ 097 Socket mysocket; 098 099 /** 100 * ctor 101 * 102 * @param idv the idv 103 * @param server the server 104 * @param socket the socket we handle the connection of 105 * 106 * @throws Exception On badness 107 */ 108 public MonitorRequestHandler(IntegratedDataViewer idv, 109 HttpServer server, Socket socket) 110 throws Exception { 111 super(server, socket); 112 this.idv = idv; 113 this.mysocket = socket; 114 } 115 116 /** 117 * Try to trap the case where the socket doesn't contain any bytes 118 * This can happen when mcservl connects to ping 119 * Prevents an infinite loop in HttpServer 120 */ 121 public void run() { 122 try { 123 int availableBytes = mysocket.getInputStream().available(); 124 if (availableBytes != 0) { 125 super.run(); 126 } 127 mysocket.close(); 128 } catch (Exception e) { 129 System.err.println("HTTP server error"); 130 } 131 } 132 133 private void decorateHtml(StringBuffer sb) throws Exception { 134 String header = "<h1>McIDAS-V HTTP monitor</h1><hr>" + 135 "<a href=stack.html>Stack Trace</a> | " + 136 "<a href=info.html>System Information</a> | " + 137 "<a href=shutdown.html>Shut Down</a><hr>"; 138 writeResult(true, header+sb.toString(),"text/html"); 139 } 140 141 /** 142 * 143 * @param path url path. ignored. 144 * @param formArgs form args 145 * @param httpArgs http args 146 * @param content content. unused. 147 * 148 * @throws Exception On badness 149 */ 150 protected void handleRequest(String path, Hashtable formArgs, 151 Hashtable httpArgs, String content) 152 throws Exception { 153 if (path.equals("/stack.html")) { 154 StringBuffer stack = LogUtil.getStackDump(true); 155 decorateHtml(stack); 156 } 157 else if (path.equals("/info.html")) { 158 StringBuffer extra = idv.getIdvUIManager().getSystemInfo(); 159 extra.append("<H3>Data Sources</H3>"); 160 extra.append("<div style=\"margin-left:20px;\">"); 161 extra.append(idv.getDataManager().getDataSourceHtml()); 162 extra.append("</div>"); 163 extra.append(idv.getPluginManager().getPluginHtml()); 164 extra.append(idv.getResourceManager().getHtmlView()); 165 decorateHtml(extra); 166 } 167 else if (path.equals("/shutdown.html")) { 168 decorateHtml(new StringBuffer("<a href=\"reallyshutdown.html\">Shut down McIDAS-V</a>")); 169 } 170 else if (path.equals("/reallyshutdown.html")) { 171 writeResult(true, "McIDAS-V is shutting down","text/html"); 172 System.exit(0); 173 } 174 else if (path.equals("/") || path.equals("/index.html")) { 175 decorateHtml(new StringBuffer("")); 176 } 177 else { 178 decorateHtml(new StringBuffer("Unknown url:" + path)); 179 } 180 } 181 } 182 183 }