send the router console out bit by bit rather than building it all up and sending it (thereby reducing its memory footprint dramatically)

This commit is contained in:
jrandom
2004-07-09 05:29:02 +00:00
committed by zzz
parent c81f864de3
commit dd014fee88
23 changed files with 208 additions and 111 deletions

View File

@@ -8,6 +8,9 @@ package net.i2p.router;
*
*/
import java.io.IOException;
import java.io.OutputStream;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.data.LeaseSet;
@@ -67,7 +70,7 @@ public abstract class ClientManagerFacade implements Service {
*
*/
public abstract SessionConfig getClientSessionConfig(Destination dest);
public String renderStatusHTML() { return ""; }
public void renderStatusHTML(OutputStream out) throws IOException { }
}
class DummyClientManagerFacade extends ClientManagerFacade {

View File

@@ -8,6 +8,9 @@ package net.i2p.router;
*
*/
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Set;
@@ -19,7 +22,7 @@ import java.util.Set;
public abstract class CommSystemFacade implements Service {
public abstract void processMessage(OutNetMessage msg);
public String renderStatusHTML() { return ""; }
public void renderStatusHTML(OutputStream out) throws IOException { }
/** Create the set of RouterAddress structures based on the router's config */
public Set createAddresses() { return new HashSet(); }

View File

@@ -8,6 +8,9 @@ package net.i2p.router;
*
*/
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
@@ -534,7 +537,7 @@ public class JobQueue {
// the remainder are utility methods for dumping status info
////
public String renderStatusHTML() {
public void renderStatusHTML(OutputStream out) throws IOException {
ArrayList readyJobs = null;
ArrayList timedJobs = null;
ArrayList activeJobs = new ArrayList(1);
@@ -553,7 +556,8 @@ public class JobQueue {
}
}
}
StringBuffer buf = new StringBuffer(20*1024);
StringBuffer buf = new StringBuffer(32*1024);
buf.append("<h2>JobQueue</h2>");
buf.append("# runners: ");
synchronized (_queueRunners) {
@@ -597,13 +601,12 @@ public class JobQueue {
buf.append(new Date(j.getTiming().getStartAfter())).append("</li>\n");
}
buf.append("</ol>\n");
buf.append(getJobStats());
return buf.toString();
getJobStats(buf);
out.write(buf.toString().getBytes());
}
/** render the HTML for the job stats */
private String getJobStats() {
StringBuffer buf = new StringBuffer(16*1024);
private void getJobStats(StringBuffer buf) {
buf.append("<table border=\"1\">\n");
buf.append("<tr><td><b>Job</b></td><td><b>Runs</b></td>");
buf.append("<td><b>Time</b></td><td><b><i>Avg</i></b></td><td><b><i>Max</i></b></td><td><b><i>Min</i></b></td>");
@@ -672,6 +675,5 @@ public class JobQueue {
buf.append("</tr>\n");
buf.append("</table>\n");
return buf.toString();
}
}

View File

@@ -8,6 +8,9 @@ package net.i2p.router;
*
*/
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -44,7 +47,6 @@ public abstract class NetworkDatabaseFacade implements Service {
public abstract void publish(LeaseSet localLeaseSet);
public abstract void unpublish(LeaseSet localLeaseSet);
public abstract void fail(Hash dbEntry);
public String renderStatusHTML() { return ""; }
}
@@ -84,4 +86,6 @@ class DummyNetworkDatabaseFacade extends NetworkDatabaseFacade {
public void fail(Hash dbEntry) {}
public Set findNearestRouters(Hash key, int maxNumRouters, Set peersToIgnore) { return new HashSet(_routers.values()); }
public void renderStatusHTML(OutputStream out) throws IOException {}
}

View File

@@ -8,6 +8,7 @@ package net.i2p.router;
*
*/
import java.io.OutputStream;
import java.util.List;
/**
@@ -29,6 +30,6 @@ public interface PeerManagerFacade extends Service {
class DummyPeerManagerFacade implements PeerManagerFacade {
public void shutdown() {}
public void startup() {}
public String renderStatusHTML() { return ""; }
public void renderStatusHTML(OutputStream out) { }
public List selectPeers(PeerSelectionCriteria criteria) { return null; }
}

View File

@@ -10,6 +10,7 @@ package net.i2p.router;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
@@ -220,34 +221,32 @@ public class Router {
_context.inNetMessagePool().registerHandlerJobBuilder(SourceRouteReplyMessage.MESSAGE_TYPE, new SourceRouteReplyMessageHandler(_context));
}
public String renderStatusHTML() {
StringBuffer buf = new StringBuffer();
buf.append("<html><head><title>I2P Router Console</title></head><body>\n");
buf.append("<h1>Router console</h1>\n");
buf.append("<i><a href=\"/routerConsole.html\">console</a> | <a href=\"/routerStats.html\">stats</a></i><br>\n");
buf.append("<form action=\"/routerConsole.html\">");
buf.append("<select name=\"go\" onChange='location.href=this.value'>");
buf.append("<option value=\"/routerConsole.html#bandwidth\">Bandwidth</option>\n");
buf.append("<option value=\"/routerConsole.html#clients\">Clients</option>\n");
buf.append("<option value=\"/routerConsole.html#transports\">Transports</option>\n");
buf.append("<option value=\"/routerConsole.html#profiles\">Peer Profiles</option>\n");
buf.append("<option value=\"/routerConsole.html#tunnels\">Tunnels</option>\n");
buf.append("<option value=\"/routerConsole.html#jobs\">Jobs</option>\n");
buf.append("<option value=\"/routerConsole.html#shitlist\">Shitlist</option>\n");
buf.append("<option value=\"/routerConsole.html#pending\">Pending messages</option>\n");
buf.append("<option value=\"/routerConsole.html#netdb\">Network Database</option>\n");
buf.append("<option value=\"/routerConsole.html#logs\">Log messages</option>\n");
buf.append("</select>");
buf.append("</form>");
buf.append("<form action=\"/shutdown\" method=\"GET\">");
buf.append("<b>Shut down the router:</b>");
buf.append("<input type=\"password\" name=\"password\" size=\"8\" />");
buf.append("<input type=\"submit\" value=\"shutdown!\" />");
buf.append("</form>");
buf.append("<hr />\n");
public void renderStatusHTML(OutputStream out) throws IOException {
out.write(("<html><head><title>I2P Router Console</title></head><body>\n" +
"<h1>Router console</h1>\n" +
"<i><a href=\"/routerConsole.html\">console</a> | <a href=\"/routerStats.html\">stats</a></i><br>\n" +
"<form action=\"/routerConsole.html\">" +
"<select name=\"go\" onChange='location.href=this.value'>" +
"<option value=\"/routerConsole.html#bandwidth\">Bandwidth</option>\n" +
"<option value=\"/routerConsole.html#clients\">Clients</option>\n" +
"<option value=\"/routerConsole.html#transports\">Transports</option>\n" +
"<option value=\"/routerConsole.html#profiles\">Peer Profiles</option>\n" +
"<option value=\"/routerConsole.html#tunnels\">Tunnels</option>\n" +
"<option value=\"/routerConsole.html#jobs\">Jobs</option>\n" +
"<option value=\"/routerConsole.html#shitlist\">Shitlist</option>\n" +
"<option value=\"/routerConsole.html#pending\">Pending messages</option>\n" +
"<option value=\"/routerConsole.html#netdb\">Network Database</option>\n" +
"<option value=\"/routerConsole.html#logs\">Log messages</option>\n" +
"</select>" +"</form>" +
"<form action=\"/shutdown\" method=\"GET\">" +
"<b>Shut down the router:</b>" +
"<input type=\"password\" name=\"password\" size=\"8\" />" +
"<input type=\"submit\" value=\"shutdown!\" />" +
"</form>" +
"<hr />\n").getBytes());
StringBuffer buf = new StringBuffer(32*1024);
if ( (_routerInfo != null) && (_routerInfo.getIdentity() != null) )
buf.append("<b>Router: </b> ").append(_routerInfo.getIdentity().getHash().toBase64()).append("<br />\n");
buf.append("<b>As of: </b> ").append(new Date(_context.clock().now())).append(" (uptime: ").append(DataHelper.formatDuration(getUptime())).append(") <br />\n");
@@ -352,24 +351,43 @@ public class Router {
buf.append("trying to transfer data. Lifetime averages count how many elephants there are on the moon [like anyone reads this text]</i>");
buf.append("\n");
buf.append(_context.bandwidthLimiter().renderStatusHTML());
out.write(buf.toString().getBytes());
_context.bandwidthLimiter().renderStatusHTML(out);
buf.append("<hr /><a name=\"clients\"> </a>\n");
buf.append(_context.clientManager().renderStatusHTML());
buf.append("\n<hr /><a name=\"transports\"> </a>\n");
buf.append(_context.commSystem().renderStatusHTML());
buf.append("\n<hr /><a name=\"profiles\"> </a>\n");
buf.append(_context.peerManager().renderStatusHTML());
buf.append("\n<hr /><a name=\"tunnels\"> </a>\n");
buf.append(_context.tunnelManager().renderStatusHTML());
buf.append("\n<hr /><a name=\"jobs\"> </a>\n");
buf.append(_context.jobQueue().renderStatusHTML());
buf.append("\n<hr /><a name=\"shitlist\"> </a>\n");
buf.append(_context.shitlist().renderStatusHTML());
buf.append("\n<hr /><a name=\"pending\"> </a>\n");
buf.append(_context.messageRegistry().renderStatusHTML());
buf.append("\n<hr /><a name=\"netdb\"> </a>\n");
buf.append(_context.netDb().renderStatusHTML());
out.write("<hr /><a name=\"clients\"> </a>\n".getBytes());
_context.clientManager().renderStatusHTML(out);
out.write("\n<hr /><a name=\"transports\"> </a>\n".getBytes());
_context.commSystem().renderStatusHTML(out);
out.write("\n<hr /><a name=\"profiles\"> </a>\n".getBytes());
_context.peerManager().renderStatusHTML(out);
out.write("\n<hr /><a name=\"tunnels\"> </a>\n".getBytes());
_context.tunnelManager().renderStatusHTML(out);
out.write("\n<hr /><a name=\"jobs\"> </a>\n".getBytes());
_context.jobQueue().renderStatusHTML(out);
out.write("\n<hr /><a name=\"shitlist\"> </a>\n".getBytes());
_context.shitlist().renderStatusHTML(out);
out.write("\n<hr /><a name=\"pending\"> </a>\n".getBytes());
_context.messageRegistry().renderStatusHTML(out);
out.write("\n<hr /><a name=\"netdb\"> </a>\n".getBytes());
_context.netDb().renderStatusHTML(out);
buf.setLength(0);
buf.append("\n<hr /><a name=\"logs\"> </a>\n");
List msgs = _context.logManager().getBuffer().getMostRecentMessages();
buf.append("\n<h2>Most recent console messages:</h2><table border=\"1\">\n");
@@ -380,7 +398,7 @@ public class Router {
}
buf.append("</table>");
buf.append("</body></html>\n");
return buf.toString();
out.write(buf.toString().getBytes());
}
public void shutdown() {

View File

@@ -8,6 +8,9 @@ package net.i2p.router;
*
*/
import java.io.IOException;
import java.io.OutputStream;
/**
* Define the manageable service interface for the subsystems in the I2P router
*
@@ -28,5 +31,5 @@ public interface Service {
*/
public void shutdown();
public String renderStatusHTML();
public void renderStatusHTML(OutputStream out) throws IOException;
}

View File

@@ -4,6 +4,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import net.i2p.crypto.PersistentSessionKeyManager;
import net.i2p.crypto.SessionKeyManager;
@@ -89,7 +90,7 @@ public class SessionKeyPersistenceHelper implements Service {
}
}
public String renderStatusHTML() { return ""; }
public void renderStatusHTML(OutputStream out) { }
private class SessionKeyWriterJob extends JobImpl {
public SessionKeyWriterJob() {

View File

@@ -8,6 +8,9 @@ package net.i2p.router;
*
*/
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
@@ -79,8 +82,8 @@ public class Shitlist {
}
}
public String renderStatusHTML() {
StringBuffer buf = new StringBuffer();
public void renderStatusHTML(OutputStream out) throws IOException {
StringBuffer buf = new StringBuffer(1024);
buf.append("<h2>Shitlist</h2>");
Map shitlist = new HashMap();
synchronized (_shitlist) {
@@ -99,6 +102,6 @@ public class Shitlist {
buf.append("<li><b>").append(key.toBase64()).append("</b> was shitlisted on ").append(shitDate).append("</li>\n");
}
buf.append("</ul>\n");
return buf.toString();
out.write(buf.toString().getBytes());
}
}

View File

@@ -8,6 +8,9 @@ package net.i2p.router;
*
*/
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
@@ -259,5 +262,5 @@ public class StatisticsManager implements Service {
private final String num(double num) { synchronized (_fmt) { return _fmt.format(num); } }
private final String pct(double num) { synchronized (_pct) { return _pct.format(num); } }
public String renderStatusHTML() { return ""; }
public void renderStatusHTML(OutputStream out) { }
}

View File

@@ -1,5 +1,8 @@
package net.i2p.router.admin;
import java.io.IOException;
import java.io.OutputStream;
import net.i2p.router.RouterContext;
import net.i2p.router.Service;
import net.i2p.util.I2PThread;
@@ -18,7 +21,7 @@ public class AdminManager implements Service {
_log = context.logManager().getLog(AdminManager.class);
}
public String renderStatusHTML() { return ""; }
public void renderStatusHTML(OutputStream out) { }
public void shutdown() {
if (_listener != null) {

View File

@@ -47,7 +47,15 @@ class AdminRunner implements Runnable {
if (command.indexOf("favicon") >= 0) {
reply(out, "this is not a website");
} else if (command.indexOf("routerStats.html") >= 0) {
reply(out, _generator.generateStatsPage());
try {
out.write("HTTP/1.1 200 OK\nConnection: close\nCache-control: no-cache\nContent-type: text/html\n\n".getBytes());
_generator.generateStatsPage(out);
out.close();
} catch (IOException ioe) {
if (_log.shouldLog(Log.WARN))
_log.warn("Error writing out the admin reply");
throw ioe;
}
} else if (command.indexOf("/profile/") >= 0) {
replyText(out, getProfile(command));
} else if (command.indexOf("setTime") >= 0) {
@@ -60,7 +68,15 @@ class AdminRunner implements Runnable {
} else if (command.indexOf("/shutdown") >= 0) {
reply(out, shutdown(command));
} else if (true || command.indexOf("routerConsole.html") > 0) {
reply(out, _context.router().renderStatusHTML());
try {
out.write("HTTP/1.1 200 OK\nConnection: close\nCache-control: no-cache\nContent-type: text/html\n\n".getBytes());
_context.router().renderStatusHTML(out);
out.close();
} catch (IOException ioe) {
if (_log.shouldLog(Log.WARN))
_log.warn("Error writing out the admin reply");
throw ioe;
}
}
}

View File

@@ -8,6 +8,9 @@ package net.i2p.router.client;
*
*/
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -305,8 +308,8 @@ public class ClientManager {
}
}
public String renderStatusHTML() {
StringBuffer buf = new StringBuffer();
public void renderStatusHTML(OutputStream out) throws IOException {
StringBuffer buf = new StringBuffer(8*1024);
buf.append("<h2>Clients</h2><ul>");
Map runners = null;
synchronized (_runners) {
@@ -325,7 +328,7 @@ public class ClientManager {
buf.append(runner.getLeaseSet()).append("</pre>\n");
}
buf.append("</ul>\n");
return buf.toString();
out.write(buf.toString().getBytes());
}
public void messageReceived(ClientMessage msg) {

View File

@@ -8,6 +8,9 @@ package net.i2p.router.client;
*
*/
import java.io.IOException;
import java.io.OutputStream;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.data.LeaseSet;
@@ -148,12 +151,8 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade {
}
}
public String renderStatusHTML() {
public void renderStatusHTML(OutputStream out) throws IOException {
if (_manager != null)
return _manager.renderStatusHTML();
else {
_log.error("Null manager on renderStatusHTML!");
return null;
}
_manager.renderStatusHTML(out);
}
}

View File

@@ -11,6 +11,7 @@ package net.i2p.router.networkdb.kademlia;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
@@ -605,16 +606,19 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
return routers;
}
public String renderStatusHTML() {
StringBuffer buf = new StringBuffer();
public void renderStatusHTML(OutputStream out) throws IOException {
StringBuffer buf = new StringBuffer(10*1024);
buf.append("<h2>Kademlia Network DB Contents</h2>\n");
if (!_initialized) {
buf.append("<i>Not initialized</i>\n");
return buf.toString();
out.write(buf.toString().getBytes());
return;
}
Set leases = getLeases();
buf.append("<h3>Leases</h3>\n");
buf.append("<table border=\"1\">\n");
out.write(buf.toString().getBytes());
buf.setLength(0);
for (Iterator iter = leases.iterator(); iter.hasNext(); ) {
LeaseSet ls = (LeaseSet)iter.next();
Hash key = ls.getDestination().calculateHash();
@@ -625,6 +629,8 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
else
buf.append("<td valign=\"top\" align=\"left\"><b>Last sent successfully:</b> never</td></tr>");
buf.append("<tr><td valign=\"top\" align=\"left\" colspan=\"2\"><pre>\n").append(ls.toString()).append("</pre></td></tr>\n");
out.write(buf.toString().getBytes());
buf.setLength(0);
}
buf.append("</table>\n");
@@ -632,6 +638,9 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
Set routers = getRouters();
buf.append("<h3>Routers</h3>\n");
buf.append("<table border=\"1\">\n");
out.write(buf.toString().getBytes());
buf.setLength(0);
for (Iterator iter = routers.iterator(); iter.hasNext(); ) {
RouterInfo ri = (RouterInfo)iter.next();
Hash key = ri.getIdentity().getHash();
@@ -648,10 +657,10 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
buf.append("<td valign=\"top\" align=\"left\"><a href=\"/profile/").append(key.toBase64().substring(0, 32)).append("\">Profile</a></td></tr>");
}
buf.append("<tr><td valign=\"top\" align=\"left\" colspan=\"3\"><pre>\n").append(ri.toString()).append("</pre></td></tr>\n");
out.write(buf.toString().getBytes());
buf.setLength(0);
}
buf.append("</table>\n");
return buf.toString();
out.write("</table>\n".getBytes());
}
}

View File

@@ -563,7 +563,7 @@ public class ProfileOrganizer {
_persistenceHelper.writeProfile(prof, out);
}
public String renderStatusHTML() {
public void renderStatusHTML(OutputStream out) throws IOException {
Set peers = selectAllPeers();
long hideBefore = _context.clock().now() - 6*60*60*1000;
@@ -581,7 +581,7 @@ public class ProfileOrganizer {
int reliable = 0;
int integrated = 0;
int failing = 0;
StringBuffer buf = new StringBuffer(8*1024);
StringBuffer buf = new StringBuffer(16*1024);
buf.append("<h2>Peer Profiles</h2>\n");
buf.append("<table border=\"1\">");
buf.append("<tr>");
@@ -660,7 +660,7 @@ public class ProfileOrganizer {
buf.append("<b>Speed:</b> ").append(num(_thresholdSpeedValue)).append(" (").append(fast).append(" fast peers)<br />");
buf.append("<b>Reliability:</b> ").append(num(_thresholdReliabilityValue)).append(" (").append(reliable).append(" reliable peers)<br />");
buf.append("<b>Integration:</b> ").append(num(_thresholdIntegrationValue)).append(" (").append(integrated).append(" well integrated peers)<br />");
return buf.toString();
out.write(buf.toString().getBytes());
}

View File

@@ -8,6 +8,9 @@ package net.i2p.router.transport;
*
*/
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
@@ -52,7 +55,9 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
j.runJob();
}
public String renderStatusHTML() { return _manager.renderStatusHTML(); }
public void renderStatusHTML(OutputStream out) throws IOException {
_manager.renderStatusHTML(out);
}
public Set createAddresses() {
Set addresses = new HashSet();

View File

@@ -1,12 +1,15 @@
package net.i2p.router.transport;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
import net.i2p.util.I2PThread;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.ArrayList;
import net.i2p.I2PAppContext;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
public class FIFOBandwidthLimiter {
private Log _log;
private I2PAppContext _context;
@@ -244,7 +247,7 @@ public class FIFOBandwidthLimiter {
}
}
public String renderStatusHTML() {
public void renderStatusHTML(OutputStream out) throws IOException {
long now = _context.clock().now();
StringBuffer buf = new StringBuffer(4096);
buf.append("<br /><b>Pending bandwidth requests (with ");
@@ -271,7 +274,7 @@ public class FIFOBandwidthLimiter {
}
}
buf.append("</ol></li></ul>\n");
return buf.toString();
out.write(buf.toString().getBytes());
}
private static long __requestId = 0;

View File

@@ -8,6 +8,9 @@ package net.i2p.router.transport;
*
*/
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
@@ -271,7 +274,7 @@ public class OutboundMessageRegistry {
}
}
public String renderStatusHTML() {
public void renderStatusHTML(OutputStream out) throws IOException {
StringBuffer buf = new StringBuffer(8192);
buf.append("<h2>Pending messages</h2>\n");
Map msgs = null;
@@ -291,7 +294,7 @@ public class OutboundMessageRegistry {
buf.append("</li>\n");
}
buf.append("</ul>");
return buf.toString();
out.write(buf.toString().getBytes());
}
/**

View File

@@ -8,6 +8,9 @@ package net.i2p.router.transport;
*
*/
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -252,8 +255,8 @@ public class TransportManager implements TransportEventListener {
_log.debug("Added to in pool: "+ num);
}
public String renderStatusHTML() {
StringBuffer buf = new StringBuffer();
public void renderStatusHTML(OutputStream out) throws IOException {
StringBuffer buf = new StringBuffer(8*1024);
buf.append("<h2>Transport Manager</h2>\n");
buf.append("Listening on: <br /><pre>\n");
for (Iterator iter = _addresses.iterator(); iter.hasNext(); ) {
@@ -269,6 +272,6 @@ public class TransportManager implements TransportEventListener {
buf.append("<li>").append(str).append("</li>\n");
}
buf.append("</ul>\n");
return buf.toString();
out.write(buf.toString().getBytes());
}
}

View File

@@ -1,6 +1,8 @@
package net.i2p.router.transport;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -146,4 +148,6 @@ public class VMCommSystem extends CommSystemFacade {
public void startup() {
_commSystemFacades.put(_context.routerHash(), this);
}
public void renderStatusHTML(OutputStream out) {}
}

View File

@@ -1,5 +1,8 @@
package net.i2p.router.tunnelmanager;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
@@ -210,10 +213,8 @@ public class PoolingTunnelManagerFacade implements TunnelManagerFacade {
* Aint she pretty?
*
*/
public String renderStatusHTML() {
public void renderStatusHTML(OutputStream out) throws IOException {
if (_pool != null)
return _pool.renderStatusHTML();
else
return "<h2>Tunnel Manager not initialized</h2>\n";
_pool.renderStatusHTML(out);
}
}

View File

@@ -1,5 +1,8 @@
package net.i2p.router.tunnelmanager;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -621,32 +624,34 @@ class TunnelPool {
return settings;
}
public String renderStatusHTML() {
if (!_isLive) return "";
StringBuffer buf = new StringBuffer();
buf.append("<h2>Tunnel Pool</h2>\n");
renderTunnels(buf, "Free inbound tunnels", getFreeTunnels());
renderTunnels(buf, "Outbound tunnels", getOutboundTunnels());
renderTunnels(buf, "Participating tunnels", getParticipatingTunnels());
public void renderStatusHTML(OutputStream out) throws IOException {
if (!_isLive) return;
out.write("<h2>Tunnel Pool</h2>\n".getBytes());
StringBuffer buf = new StringBuffer(4096);
renderTunnels(out, buf, "Free inbound tunnels", getFreeTunnels());
renderTunnels(out, buf, "Outbound tunnels", getOutboundTunnels());
renderTunnels(out, buf, "Participating tunnels", getParticipatingTunnels());
for (Iterator iter = getClientPools().iterator(); iter.hasNext(); ) {
Destination dest = (Destination)iter.next();
ClientTunnelPool pool = getClientPool(dest);
renderTunnels(buf, "Inbound tunnels for " + dest.calculateHash() + " - (still connected? " + (!pool.isStopped()) + ")", pool.getInboundTunnelIds());
renderTunnels(out, buf, "Inbound tunnels for " + dest.calculateHash() + " - (still connected? " + (!pool.isStopped()) + ")", pool.getInboundTunnelIds());
}
return buf.toString();
}
private void renderTunnels(StringBuffer buf, String msg, Set tunnelIds) {
private void renderTunnels(OutputStream out, StringBuffer buf, String msg, Set tunnelIds) throws IOException {
buf.append("<b>").append(msg).append(":</b> <i>(").append(tunnelIds.size()).append(" tunnels)</i><ul>\n");
out.write(buf.toString().getBytes());
buf.setLength(0);
for (Iterator iter = tunnelIds.iterator(); iter.hasNext(); ) {
TunnelId id = (TunnelId)iter.next();
TunnelInfo tunnel = getTunnelInfo(id);
renderTunnel(buf, id, tunnel);
renderTunnel(out, buf, id, tunnel);
}
buf.append("</ul>\n");
out.write("</ul>\n".getBytes());
}
private final static void renderTunnel(StringBuffer buf, TunnelId id, TunnelInfo tunnel) {
private final static void renderTunnel(OutputStream out, StringBuffer buf, TunnelId id, TunnelInfo tunnel) throws IOException {
buf.setLength(0);
if (tunnel == null) {
buf.append("<li>Tunnel: ").append(id.getTunnelId()).append(" is not known</li>\n");
} else {
@@ -675,6 +680,8 @@ class TunnelPool {
buf.append("\n</pre>");
}
out.write(buf.toString().getBytes());
buf.setLength(0);
}
private final static String getStyle(TunnelId id) {