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