From 04780cae4cd2ea0619ecaac060c1df423b01c831 Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 26 Feb 2026 10:07:48 -0500 Subject: [PATCH] Console: Limit banlist output, add page links Fix concurrent mod exception rendering banlist caused by switch to LHM --- .../router/web/helpers/BanlistRenderer.java | 62 ++++++++++++++++++- .../i2p/router/web/helpers/PeerHelper.java | 29 +++++++++ .../router/web/helpers/ProfilesHelper.java | 29 +++++++++ apps/routerconsole/jsp/peers.jsp | 2 + apps/routerconsole/jsp/profiles.jsp | 2 + router/java/src/net/i2p/router/Banlist.java | 4 +- .../src/net/i2p/router/sybil/Analysis.java | 3 +- 7 files changed, 125 insertions(+), 6 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/BanlistRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/BanlistRenderer.java index 39443cb40..c78cdfe2a 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/BanlistRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/BanlistRenderer.java @@ -25,30 +25,63 @@ import net.i2p.router.web.Messages; * Moved from Banlist.java */ class BanlistRenderer { + static final int PAGE_SIZE = 2048; + private int _pageSize = PAGE_SIZE; + private int _page; + private final RouterContext _context; public BanlistRenderer(RouterContext context) { _context = context; } + /** + * @param page 0-based + * @since 0.9.69 + */ + public void setPage(int page) { + _page = page; + } + + /** + * @since 0.9.69 + */ + public void setPageSize(int ps) { + _pageSize = ps; + } + public void renderStatusHTML(Writer out) throws IOException { StringBuilder buf = new StringBuilder(2048); Map entries = new TreeMap(HashComparator.getInstance()); - entries.putAll(_context.banlist().getEntries()); + _context.banlist().getEntries(entries); buf.append("

").append(_t("Banned Peers")); - if (entries.isEmpty()) { + int sz = entries.size(); + if (sz == 0) { buf.append("

").append(_t("none")).append(""); out.append(buf); return; } else { - buf.append(" (").append(entries.size()).append(")"); + buf.append(" (").append(sz).append(")"); } + boolean morePages = false; + int toSkip = _pageSize * _page; + int last = Math.min(toSkip + _pageSize, sz); + if (last < sz) + morePages = true; + if (_page > 0 || morePages) + outputPageLinks(buf, _page, _pageSize, morePages); + buf.append("
    "); String unban = _t("unban now"); + int i = 0; for (Map.Entry e : entries.entrySet()) { + if (i++ < toSkip) + continue; + if (i > last) + break; Hash key = e.getKey(); Banlist.Entry entry = e.getValue(); long expires = entry.expireOn-_context.clock().now(); @@ -85,10 +118,33 @@ class BanlistRenderer { } } buf.append("
\n"); + if (_page > 0 || morePages) + outputPageLinks(buf, _page, _pageSize, morePages); out.append(buf); out.flush(); } + /** + * @since 0.9.69 + */ + private void outputPageLinks(StringBuilder buf, int page, int pageSize, boolean morePages) { + buf.append("
"); + if (page > 0) { + buf.append(""); + buf.append(_t("Previous Page")); + buf.append("   "); + } + buf.append(_t("Page")).append(' ').append(page + 1); + if (morePages) { + buf.append("   "); + buf.append(_t("Next Page")); + buf.append(""); + } + buf.append("
"); + } + /** translate a string */ private String _t(String s) { return Messages.getString(s, _context); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/PeerHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/PeerHelper.java index daffe017d..c3659260a 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/PeerHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/PeerHelper.java @@ -38,6 +38,8 @@ public class PeerHelper extends HelperBase { private String _urlBase; private String _transport; private boolean _graphical; + private int _pageSize = BanlistRenderer.PAGE_SIZE; + private int _page; private static final String titles[] = { _x("Status"), @@ -80,6 +82,31 @@ public class PeerHelper extends HelperBase { /** @since 0.9.38 */ public void setTransport(String t) { _transport = t; } + /** + * @param page 1-based + * @since 0.9.69 + */ + public void setPage(String page) { + if (page != null) { + try { + _page = Integer.parseInt(page) - 1; + if (_page < 0) + _page = 0; + } catch (NumberFormatException nfe) {} + } + } + + /** + * @since 0.9.69 + */ + public void setPageSize(String ps) { + if (ps != null) { + try { + _pageSize = Integer.parseInt(ps); + } catch (NumberFormatException nfe) {} + } + } + /** * call for non-text-mode browsers * @since 0.9.38 @@ -164,6 +191,8 @@ public class PeerHelper extends HelperBase { _context.commSystem().renderStatusHTML(_out, _urlBase, _sortFlags); } else if ("banned".equals(_transport)) { BanlistRenderer br = new BanlistRenderer(_context); + br.setPage(_page); + br.setPageSize(_pageSize); br.renderStatusHTML(_out); } else if (_transport != null) { boolean rendered = false; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/ProfilesHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/ProfilesHelper.java index 632947c7c..86f2c56d5 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/ProfilesHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/ProfilesHelper.java @@ -8,6 +8,8 @@ import net.i2p.router.web.HelperBase; public class ProfilesHelper extends HelperBase { private int _full; private boolean _graphical; + private int _pageSize = BanlistRenderer.PAGE_SIZE; + private int _page; private static final String titles[] = {_x("High Capacity"), // 0 @@ -31,6 +33,31 @@ public class ProfilesHelper extends HelperBase { } } + /** + * @param page 1-based + * @since 0.9.69 + */ + public void setPage(String page) { + if (page != null) { + try { + _page = Integer.parseInt(page) - 1; + if (_page < 0) + _page = 0; + } catch (NumberFormatException nfe) {} + } + } + + /** + * @since 0.9.69 + */ + public void setPageSize(String ps) { + if (ps != null) { + try { + _pageSize = Integer.parseInt(ps); + } catch (NumberFormatException nfe) {} + } + } + /** * call for non-text-mode browsers * @since 0.9.1 @@ -69,6 +96,8 @@ public class ProfilesHelper extends HelperBase { public String getBanlistSummary() { try { BanlistRenderer rend = new BanlistRenderer(_context); + rend.setPage(_page); + rend.setPageSize(_pageSize); rend.renderStatusHTML(_out); } catch (IOException ioe) { ioe.printStackTrace(); diff --git a/apps/routerconsole/jsp/peers.jsp b/apps/routerconsole/jsp/peers.jsp index b3c0d06ef..833ddb300 100644 --- a/apps/routerconsole/jsp/peers.jsp +++ b/apps/routerconsole/jsp/peers.jsp @@ -20,5 +20,7 @@ " /> " /> + " /> + " /> diff --git a/apps/routerconsole/jsp/profiles.jsp b/apps/routerconsole/jsp/profiles.jsp index 68dcd69e8..553bd1a28 100644 --- a/apps/routerconsole/jsp/profiles.jsp +++ b/apps/routerconsole/jsp/profiles.jsp @@ -18,5 +18,7 @@ profilesHelper.allowGraphical(); %> " /> + " /> + " /> diff --git a/router/java/src/net/i2p/router/Banlist.java b/router/java/src/net/i2p/router/Banlist.java index 1904aea52..36d43a418 100644 --- a/router/java/src/net/i2p/router/Banlist.java +++ b/router/java/src/net/i2p/router/Banlist.java @@ -126,9 +126,9 @@ public class Banlist { * For BanlistRenderer in router console. * Note - may contain expired entries. */ - public Map getEntries() { + public void getEntries(Map rv) { synchronized(_entries) { - return Collections.unmodifiableMap(_entries); + rv.putAll(_entries); } } diff --git a/router/java/src/net/i2p/router/sybil/Analysis.java b/router/java/src/net/i2p/router/sybil/Analysis.java index d25c4cead..effead42d 100644 --- a/router/java/src/net/i2p/router/sybil/Analysis.java +++ b/router/java/src/net/i2p/router/sybil/Analysis.java @@ -1056,7 +1056,8 @@ public class Analysis extends JobImpl implements RouterApp, Runnable { private static final long DAY = 24*60*60*1000L; public void addProfilePoints(List ris, Map points) { - Map banEntries = _context.banlist().getEntries(); + Map banEntries = new HashMap(1024); + _context.banlist().getEntries(banEntries); long now = _context.clock().now(); RateAverages ra = RateAverages.getTemp(); for (RouterInfo info : ris) {