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 }