From dd014fee8864f13720567b841733ceb80c767088 Mon Sep 17 00:00:00 2001 From: jrandom Date: Fri, 9 Jul 2004 05:29:02 +0000 Subject: [PATCH] send the router console out bit by bit rather than building it all up and sending it (thereby reducing its memory footprint dramatically) --- .../net/i2p/router/ClientManagerFacade.java | 5 +- .../src/net/i2p/router/CommSystemFacade.java | 5 +- router/java/src/net/i2p/router/JobQueue.java | 16 +-- .../net/i2p/router/NetworkDatabaseFacade.java | 6 +- .../src/net/i2p/router/PeerManagerFacade.java | 3 +- router/java/src/net/i2p/router/Router.java | 108 ++++++++++-------- router/java/src/net/i2p/router/Service.java | 5 +- .../router/SessionKeyPersistenceHelper.java | 3 +- router/java/src/net/i2p/router/Shitlist.java | 9 +- .../src/net/i2p/router/StatisticsManager.java | 5 +- .../net/i2p/router/admin/AdminManager.java | 5 +- .../src/net/i2p/router/admin/AdminRunner.java | 20 +++- .../net/i2p/router/client/ClientManager.java | 9 +- .../client/ClientManagerFacadeImpl.java | 11 +- .../KademliaNetworkDatabaseFacade.java | 21 +++- .../router/peermanager/ProfileOrganizer.java | 6 +- .../transport/CommSystemFacadeImpl.java | 7 +- .../transport/FIFOBandwidthLimiter.java | 13 ++- .../transport/OutboundMessageRegistry.java | 7 +- .../router/transport/TransportManager.java | 9 +- .../i2p/router/transport/VMCommSystem.java | 4 + .../PoolingTunnelManagerFacade.java | 9 +- .../i2p/router/tunnelmanager/TunnelPool.java | 33 +++--- 23 files changed, 208 insertions(+), 111 deletions(-) diff --git a/router/java/src/net/i2p/router/ClientManagerFacade.java b/router/java/src/net/i2p/router/ClientManagerFacade.java index 323593346..cdc9c4109 100644 --- a/router/java/src/net/i2p/router/ClientManagerFacade.java +++ b/router/java/src/net/i2p/router/ClientManagerFacade.java @@ -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 { diff --git a/router/java/src/net/i2p/router/CommSystemFacade.java b/router/java/src/net/i2p/router/CommSystemFacade.java index d3342138f..6c062cd67 100644 --- a/router/java/src/net/i2p/router/CommSystemFacade.java +++ b/router/java/src/net/i2p/router/CommSystemFacade.java @@ -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(); } diff --git a/router/java/src/net/i2p/router/JobQueue.java b/router/java/src/net/i2p/router/JobQueue.java index 3eabef095..0435b58f9 100644 --- a/router/java/src/net/i2p/router/JobQueue.java +++ b/router/java/src/net/i2p/router/JobQueue.java @@ -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("

JobQueue

"); buf.append("# runners: "); synchronized (_queueRunners) { @@ -597,13 +601,12 @@ public class JobQueue { buf.append(new Date(j.getTiming().getStartAfter())).append("\n"); } buf.append("\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("\n"); buf.append(""); buf.append(""); @@ -672,6 +675,5 @@ public class JobQueue { buf.append("\n"); buf.append("
JobRunsTimeAvgMaxMin
\n"); - return buf.toString(); } } diff --git a/router/java/src/net/i2p/router/NetworkDatabaseFacade.java b/router/java/src/net/i2p/router/NetworkDatabaseFacade.java index b93b18487..bc6621cd3 100644 --- a/router/java/src/net/i2p/router/NetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/NetworkDatabaseFacade.java @@ -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 {} } diff --git a/router/java/src/net/i2p/router/PeerManagerFacade.java b/router/java/src/net/i2p/router/PeerManagerFacade.java index 99a111897..108413a52 100644 --- a/router/java/src/net/i2p/router/PeerManagerFacade.java +++ b/router/java/src/net/i2p/router/PeerManagerFacade.java @@ -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; } } diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 37149ce1e..e164207e2 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -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("I2P Router Console\n"); - buf.append("

Router console

\n"); - buf.append("console | stats
\n"); - - buf.append("
"); - buf.append(""); - buf.append("
"); - - buf.append("
"); - buf.append("Shut down the router:"); - buf.append(""); - buf.append(""); - buf.append("
"); - buf.append("
\n"); + public void renderStatusHTML(OutputStream out) throws IOException { + out.write(("I2P Router Console\n" + + "

Router console

\n" + + "console | stats
\n" + + "
" + + "" +"
" + + "
" + + "Shut down the router:" + + "" + + "" + + "
" + + "
\n").getBytes()); + StringBuffer buf = new StringBuffer(32*1024); + if ( (_routerInfo != null) && (_routerInfo.getIdentity() != null) ) buf.append("Router: ").append(_routerInfo.getIdentity().getHash().toBase64()).append("
\n"); buf.append("As of: ").append(new Date(_context.clock().now())).append(" (uptime: ").append(DataHelper.formatDuration(getUptime())).append(")
\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]"); buf.append("\n"); - buf.append(_context.bandwidthLimiter().renderStatusHTML()); + out.write(buf.toString().getBytes()); + + _context.bandwidthLimiter().renderStatusHTML(out); - buf.append("
\n"); - buf.append(_context.clientManager().renderStatusHTML()); - buf.append("\n
\n"); - buf.append(_context.commSystem().renderStatusHTML()); - buf.append("\n
\n"); - buf.append(_context.peerManager().renderStatusHTML()); - buf.append("\n
\n"); - buf.append(_context.tunnelManager().renderStatusHTML()); - buf.append("\n
\n"); - buf.append(_context.jobQueue().renderStatusHTML()); - buf.append("\n
\n"); - buf.append(_context.shitlist().renderStatusHTML()); - buf.append("\n
\n"); - buf.append(_context.messageRegistry().renderStatusHTML()); - buf.append("\n
\n"); - buf.append(_context.netDb().renderStatusHTML()); + out.write("
\n".getBytes()); + + _context.clientManager().renderStatusHTML(out); + + out.write("\n
\n".getBytes()); + + _context.commSystem().renderStatusHTML(out); + + out.write("\n
\n".getBytes()); + + _context.peerManager().renderStatusHTML(out); + + out.write("\n
\n".getBytes()); + + _context.tunnelManager().renderStatusHTML(out); + + out.write("\n
\n".getBytes()); + + _context.jobQueue().renderStatusHTML(out); + + out.write("\n
\n".getBytes()); + + _context.shitlist().renderStatusHTML(out); + + out.write("\n
\n".getBytes()); + + _context.messageRegistry().renderStatusHTML(out); + + out.write("\n
\n".getBytes()); + + _context.netDb().renderStatusHTML(out); + + buf.setLength(0); buf.append("\n
\n"); List msgs = _context.logManager().getBuffer().getMostRecentMessages(); buf.append("\n

Most recent console messages:

\n"); @@ -380,7 +398,7 @@ public class Router { } buf.append("
"); buf.append("\n"); - return buf.toString(); + out.write(buf.toString().getBytes()); } public void shutdown() { diff --git a/router/java/src/net/i2p/router/Service.java b/router/java/src/net/i2p/router/Service.java index 9ec1211ab..1c276c861 100644 --- a/router/java/src/net/i2p/router/Service.java +++ b/router/java/src/net/i2p/router/Service.java @@ -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; } diff --git a/router/java/src/net/i2p/router/SessionKeyPersistenceHelper.java b/router/java/src/net/i2p/router/SessionKeyPersistenceHelper.java index 26bc85c06..24aadc537 100644 --- a/router/java/src/net/i2p/router/SessionKeyPersistenceHelper.java +++ b/router/java/src/net/i2p/router/SessionKeyPersistenceHelper.java @@ -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() { diff --git a/router/java/src/net/i2p/router/Shitlist.java b/router/java/src/net/i2p/router/Shitlist.java index ff093fcde..64922a82e 100644 --- a/router/java/src/net/i2p/router/Shitlist.java +++ b/router/java/src/net/i2p/router/Shitlist.java @@ -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("

Shitlist

"); Map shitlist = new HashMap(); synchronized (_shitlist) { @@ -99,6 +102,6 @@ public class Shitlist { buf.append("
  • ").append(key.toBase64()).append(" was shitlisted on ").append(shitDate).append("
  • \n"); } buf.append("\n"); - return buf.toString(); + out.write(buf.toString().getBytes()); } } diff --git a/router/java/src/net/i2p/router/StatisticsManager.java b/router/java/src/net/i2p/router/StatisticsManager.java index 7ef180850..41956a307 100644 --- a/router/java/src/net/i2p/router/StatisticsManager.java +++ b/router/java/src/net/i2p/router/StatisticsManager.java @@ -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) { } } diff --git a/router/java/src/net/i2p/router/admin/AdminManager.java b/router/java/src/net/i2p/router/admin/AdminManager.java index 39ddfa0b7..007c8b02e 100644 --- a/router/java/src/net/i2p/router/admin/AdminManager.java +++ b/router/java/src/net/i2p/router/admin/AdminManager.java @@ -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) { diff --git a/router/java/src/net/i2p/router/admin/AdminRunner.java b/router/java/src/net/i2p/router/admin/AdminRunner.java index 2a32bec0b..06143d424 100644 --- a/router/java/src/net/i2p/router/admin/AdminRunner.java +++ b/router/java/src/net/i2p/router/admin/AdminRunner.java @@ -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; + } } } diff --git a/router/java/src/net/i2p/router/client/ClientManager.java b/router/java/src/net/i2p/router/client/ClientManager.java index f1064de1f..8de832018 100644 --- a/router/java/src/net/i2p/router/client/ClientManager.java +++ b/router/java/src/net/i2p/router/client/ClientManager.java @@ -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("

    Clients

    \n"); - return buf.toString(); + out.write(buf.toString().getBytes()); } public void messageReceived(ClientMessage msg) { diff --git a/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java b/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java index 59caca44d..68db62729 100644 --- a/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java +++ b/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java @@ -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); } } diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java index 1dc81456c..6ce250a6d 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java @@ -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("

    Kademlia Network DB Contents

    \n"); if (!_initialized) { buf.append("Not initialized\n"); - return buf.toString(); + out.write(buf.toString().getBytes()); + return; } Set leases = getLeases(); buf.append("

    Leases

    \n"); buf.append("\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(""); buf.append("\n"); + out.write(buf.toString().getBytes()); + buf.setLength(0); } buf.append("
    Last sent successfully: never
    \n").append(ls.toString()).append("
    \n"); @@ -632,6 +638,9 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade { Set routers = getRouters(); buf.append("

    Routers

    \n"); buf.append("\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(""); } buf.append("\n"); + out.write(buf.toString().getBytes()); + buf.setLength(0); } - buf.append("
    Profile
    \n").append(ri.toString()).append("
    \n"); - - return buf.toString(); + out.write("\n".getBytes()); } } diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java index 22e997273..d56e2af04 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java @@ -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("

    Peer Profiles

    \n"); buf.append(""); buf.append(""); @@ -660,7 +660,7 @@ public class ProfileOrganizer { buf.append("Speed: ").append(num(_thresholdSpeedValue)).append(" (").append(fast).append(" fast peers)
    "); buf.append("Reliability: ").append(num(_thresholdReliabilityValue)).append(" (").append(reliable).append(" reliable peers)
    "); buf.append("Integration: ").append(num(_thresholdIntegrationValue)).append(" (").append(integrated).append(" well integrated peers)
    "); - return buf.toString(); + out.write(buf.toString().getBytes()); } diff --git a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java index 495e499f2..afb401d15 100644 --- a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java +++ b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java @@ -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(); diff --git a/router/java/src/net/i2p/router/transport/FIFOBandwidthLimiter.java b/router/java/src/net/i2p/router/transport/FIFOBandwidthLimiter.java index 7c096d3dc..c6eb8f157 100644 --- a/router/java/src/net/i2p/router/transport/FIFOBandwidthLimiter.java +++ b/router/java/src/net/i2p/router/transport/FIFOBandwidthLimiter.java @@ -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("
    Pending bandwidth requests (with "); @@ -271,7 +274,7 @@ public class FIFOBandwidthLimiter { } } buf.append("\n"); - return buf.toString(); + out.write(buf.toString().getBytes()); } private static long __requestId = 0; diff --git a/router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java b/router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java index b18ba5cd4..fbf92fc55 100644 --- a/router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java +++ b/router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java @@ -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("

    Pending messages

    \n"); Map msgs = null; @@ -291,7 +294,7 @@ public class OutboundMessageRegistry { buf.append("\n"); } buf.append(""); - return buf.toString(); + out.write(buf.toString().getBytes()); } /** diff --git a/router/java/src/net/i2p/router/transport/TransportManager.java b/router/java/src/net/i2p/router/transport/TransportManager.java index 14c90ce91..c42b19a80 100644 --- a/router/java/src/net/i2p/router/transport/TransportManager.java +++ b/router/java/src/net/i2p/router/transport/TransportManager.java @@ -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("

    Transport Manager

    \n"); buf.append("Listening on:
    \n");
             for (Iterator iter = _addresses.iterator(); iter.hasNext(); ) {
    @@ -269,6 +272,6 @@ public class TransportManager implements TransportEventListener {
                     buf.append("
  • ").append(str).append("
  • \n"); } buf.append("\n"); - return buf.toString(); + out.write(buf.toString().getBytes()); } } diff --git a/router/java/src/net/i2p/router/transport/VMCommSystem.java b/router/java/src/net/i2p/router/transport/VMCommSystem.java index 91749ff0b..3c6dac7cb 100644 --- a/router/java/src/net/i2p/router/transport/VMCommSystem.java +++ b/router/java/src/net/i2p/router/transport/VMCommSystem.java @@ -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) {} } diff --git a/router/java/src/net/i2p/router/tunnelmanager/PoolingTunnelManagerFacade.java b/router/java/src/net/i2p/router/tunnelmanager/PoolingTunnelManagerFacade.java index f42fbe2c3..8780c4c11 100644 --- a/router/java/src/net/i2p/router/tunnelmanager/PoolingTunnelManagerFacade.java +++ b/router/java/src/net/i2p/router/tunnelmanager/PoolingTunnelManagerFacade.java @@ -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 "

    Tunnel Manager not initialized

    \n"; + _pool.renderStatusHTML(out); } } diff --git a/router/java/src/net/i2p/router/tunnelmanager/TunnelPool.java b/router/java/src/net/i2p/router/tunnelmanager/TunnelPool.java index 3cdb0a2df..fa87136eb 100644 --- a/router/java/src/net/i2p/router/tunnelmanager/TunnelPool.java +++ b/router/java/src/net/i2p/router/tunnelmanager/TunnelPool.java @@ -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("

    Tunnel Pool

    \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("

    Tunnel Pool

    \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("").append(msg).append(": (").append(tunnelIds.size()).append(" tunnels)
      \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("
    \n"); + out.write("\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("
  • Tunnel: ").append(id.getTunnelId()).append(" is not known
  • \n"); } else { @@ -675,6 +680,8 @@ class TunnelPool { buf.append("\n
    "); } + out.write(buf.toString().getBytes()); + buf.setLength(0); } private final static String getStyle(TunnelId id) {