diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigReseedHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigReseedHandler.java index 483bb9a7b6..faa007552e 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigReseedHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigReseedHandler.java @@ -9,6 +9,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import net.i2p.router.networkdb.reseed.ReseedChecker; import net.i2p.router.networkdb.reseed.Reseeder; /** @@ -21,15 +22,18 @@ public class ConfigReseedHandler extends FormHandler { @Override protected void processForm() { + ReseedChecker checker = _context.netDb().reseedChecker(); if (_action.equals(_t("Save changes and reseed now"))) { saveChanges(); - if (!_context.netDb().reseedChecker().requestReseed()) { + if (!checker.requestReseed()) { addFormError(_t("Reseeding is already in progress")); + addCheckerStatus(checker); } else { // skip the nonce checking in ReseedHandler addFormNotice(_t("Starting reseed process")); } } else if (_action.equals(_t("Reseed from URL"))) { + // threaded String val = getJettyString("url"); if (val != null) val = val.trim(); @@ -45,33 +49,31 @@ public class ConfigReseedHandler extends FormHandler { return; } try { - if (!_context.netDb().reseedChecker().requestReseed(url)) { + if (!checker.requestReseed(url)) { addFormError(_t("Reseeding is already in progress")); + addCheckerStatus(checker); } else { // wait a while for completion but not forever for (int i = 0; i < 40; i++) { try { Thread.sleep(500); } catch (InterruptedException ie) {} - if (!_context.netDb().reseedChecker().inProgress()) + if (!checker.inProgress()) break; } - String status = _context.netDb().reseedChecker().getStatus(); - String error = _context.netDb().reseedChecker().getError(); - if (error.length() > 0) { - addFormErrorNoEscape(error); - } else if (status.length() > 0) { - addFormNoticeNoEscape(status); - } else if (_context.netDb().reseedChecker().inProgress()) { - addFormNotice(_t("Reseed in progress, check summary bar for status")); - } else { - addFormNotice(_t("Reseed complete, check summary bar for status")); + if (!addCheckerStatus(checker)) { + if (checker.inProgress()) { + addFormNotice(_t("Reseed in progress, check summary bar for status")); + } else { + addFormNotice(_t("Reseed complete, check summary bar for status")); + } } } } catch (IllegalArgumentException iae) { addFormError(_t("Bad URL {0}", val) + " - " + iae.getMessage()); } } else if (_action.equals(_t("Reseed from file"))) { + // inline InputStream in = _requestWrapper.getInputStream("file"); try { // non-null but zero bytes if no file entered, don't know why @@ -79,9 +81,10 @@ public class ConfigReseedHandler extends FormHandler { addFormError(_t("You must enter a file")); return; } - int count = _context.netDb().reseedChecker().requestReseed(in); + int count = checker.requestReseed(in); if (count <= 0) { addFormError(_t("Reseed from file failed")); + addCheckerStatus(checker); } else { addFormNotice(ngettext("Reseed successful, loaded {0} router info from file", "Reseed successful, loaded {0} router infos from file", @@ -89,6 +92,7 @@ public class ConfigReseedHandler extends FormHandler { } } catch (IOException ioe) { addFormError(_t("Reseed from file failed") + " - " + ioe); + addCheckerStatus(checker); } finally { // it's really a ByteArrayInputStream but we'll play along... if (in != null) @@ -102,6 +106,24 @@ public class ConfigReseedHandler extends FormHandler { //addFormError(_t("Unsupported") + ' ' + _action + '.'); } + /** + * @return true if anything was output + * @since 0.9.33 + */ + private boolean addCheckerStatus(ReseedChecker checker) { + String error = checker.getError(); + if (error.length() > 0) { + addFormErrorNoEscape(error); + return true; + } + String status = checker.getStatus(); + if (status.length() > 0) { + addFormNoticeNoEscape(status); + return true; + } + return false; + } + private void resetUrlList() { if (_context.router().saveConfig(Reseeder.PROP_RESEED_URL, null)) addFormNotice(_t("URL list reset successfully")); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java index 458121a239..128e5760ec 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java @@ -23,6 +23,7 @@ import net.i2p.router.RouterContext; import net.i2p.router.RouterVersion; import net.i2p.router.TunnelPoolSettings; import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade; +import net.i2p.router.networkdb.reseed.ReseedChecker; import net.i2p.router.transport.TransportUtil; import net.i2p.stat.Rate; import net.i2p.stat.RateStat; @@ -153,7 +154,7 @@ public class SummaryHelper extends HelperBase { /** allowReseed */ public boolean allowReseed() { return _context.netDb().isInitialized() && - (_context.netDb().getKnownRouters() < 30) || + (_context.netDb().getKnownRouters() < ReseedChecker.MINIMUM) || _context.getBooleanProperty("i2p.alwaysAllowReseed"); } @@ -942,13 +943,20 @@ public class SummaryHelper extends HelperBase { .append(""); } - boolean reseedInProgress = _context.netDb().reseedChecker().inProgress(); - // If showing the reseed link is allowed - if (allowReseed()) { - if (reseedInProgress) { - // While reseed occurring, show status message instead - buf.append("
").append(_context.netDb().reseedChecker().getStatus()).append("
"); - } else { + ReseedChecker checker = _context.netDb().reseedChecker(); + String status = checker.getStatus(); + if (status.length() > 0) { + // Show status message even if not running, timer in ReseedChecker should remove after 20 minutes + buf.append("
").append(checker.getStatus()).append("
"); + } + if (!checker.inProgress()) { + // If a new reseed isn't running, and the last reseed had errors, show error message + String reseedErrorMessage = checker.getError(); + if (reseedErrorMessage.length() > 0) { + buf.append("
").append(reseedErrorMessage).append("
"); + } + // If showing the reseed link is allowed + if (allowReseed()) { // While no reseed occurring, show reseed link long nonce = _context.random().nextLong(); String prev = System.getProperty("net.i2p.router.web.ReseedHandler.nonce"); @@ -961,13 +969,6 @@ public class SummaryHelper extends HelperBase { buf.append("\" class=\"reload\" value=\"Reseed\" >").append(_t("Reseed")).append("

\n"); } } - // If a new reseed ain't running, and the last reseed had errors, show error message - if (!reseedInProgress) { - String reseedErrorMessage = _context.netDb().reseedChecker().getError(); - if (reseedErrorMessage.length() > 0) { - buf.append("
").append(reseedErrorMessage).append("
"); - } - } if (buf.length() <= 0) return ""; return buf.toString(); diff --git a/apps/routerconsole/jsp/configreseed.jsp b/apps/routerconsole/jsp/configreseed.jsp index 675a71c612..0ed1ed0336 100644 --- a/apps/routerconsole/jsp/configreseed.jsp +++ b/apps/routerconsole/jsp/configreseed.jsp @@ -22,8 +22,33 @@

<%=intl._t("Reseeding is the bootstrapping process used to find other routers when you first install I2P, or when your router has too few router references remaining.")%> +

  1. <%=intl._t("If reseeding has failed, you should first check your network connection.")%> +
  2. +<%=intl._t("If a firewall is blocking your connections to reseed hosts, you may have access to a proxy.")%> + +
  3. +<%=intl._t("If you know and trust somebody that runs I2P, ask them to send you a reseed file generated using this page on their router console.")%> +<%=intl._t("Then, use this page to reseed using file you received.")%> +
  4. +<%=intl._t("If you know and trust somebody that publishes reseed files, ask them for the URL.")%> +<%=intl._t("Then, use this page to reseed using the URL you received.")%> +
  5. <%=intl._t("See {0} for instructions on reseeding manually.", "" + intl._t("the FAQ") + "")%> +

<%=intl._t("Manual Reseed")%>

diff --git a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java index 00c9c3e326..c08bc5da97 100644 --- a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java +++ b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java @@ -257,8 +257,10 @@ public class Reseeder { private class ReseedRunner implements Runnable, EepGet.StatusListener { private boolean _isRunning; - private String _proxyHost, _sproxyHost; - private int _proxyPort, _sproxyPort; + private final String _proxyHost, _sproxyHost; + private final int _proxyPort, _sproxyPort; + private final boolean _shouldProxyHTTP, _shouldProxySSL; + private final SSLEepGet.ProxyType _sproxyType; private SSLEepGet.SSLState _sslState; private int _gotDate; private long _attemptStarted; @@ -271,8 +273,7 @@ public class Reseeder { * Start a reseed from the default URL list */ public ReseedRunner() { - _url = null; - _bandwidths = new ArrayList(4); + this(null); } /** @@ -283,11 +284,30 @@ public class Reseeder { * @since 0.9.19 */ public ReseedRunner(URI url) throws IllegalArgumentException { - String lc = url.getPath().toLowerCase(Locale.US); - if (!(lc.endsWith(".zip") || lc.endsWith(".su3"))) - throw new IllegalArgumentException("Reseed URL must end with .zip or .su3"); + if (url != null) { + String lc = url.getPath().toLowerCase(Locale.US); + if (!(lc.endsWith(".zip") || lc.endsWith(".su3"))) + throw new IllegalArgumentException("Reseed URL must end with .zip or .su3"); + } _url = url; _bandwidths = new ArrayList(4); + if (_context.getBooleanProperty(PROP_PROXY_ENABLE)) { + _proxyHost = _context.getProperty(PROP_PROXY_HOST); + _proxyPort = _context.getProperty(PROP_PROXY_PORT, -1); + } else { + _proxyHost = null; + _proxyPort = -1; + } + _shouldProxyHTTP = _proxyHost != null && _proxyHost.length() > 0 && _proxyPort > 0; + if (_context.getBooleanProperty(PROP_SPROXY_ENABLE)) { + _sproxyHost = _context.getProperty(PROP_SPROXY_HOST); + _sproxyPort = _context.getProperty(PROP_SPROXY_PORT, -1); + } else { + _sproxyHost = null; + _sproxyPort = -1; + } + _shouldProxySSL = _sproxyHost != null && _sproxyHost.length() > 0 && _sproxyPort > 0; + _sproxyType = _shouldProxySSL ? getProxyType() : SSLEepGet.ProxyType.NONE; } /* @@ -306,14 +326,6 @@ public class Reseeder { _isRunning = true; _checker.setError(""); _checker.setStatus(_t("Reseeding")); - if (_context.getBooleanProperty(PROP_PROXY_ENABLE)) { - _proxyHost = _context.getProperty(PROP_PROXY_HOST); - _proxyPort = _context.getProperty(PROP_PROXY_PORT, -1); - } - if (_context.getBooleanProperty(PROP_SPROXY_ENABLE)) { - _sproxyHost = _context.getProperty(PROP_SPROXY_HOST); - _sproxyPort = _context.getProperty(PROP_SPROXY_PORT, -1); - } System.out.println("Reseed start"); int total; if (_url != null) { @@ -328,27 +340,40 @@ public class Reseeder { total = reseed(false); } if (total >= 20) { - System.out.println("Reseed complete, " + total + " received"); + String s = ngettext("Reseed successful, fetched {0} router info", + "Reseed successful, fetched {0} router infos", total); + System.out.println(s + getDisplayString(_url)); + _checker.setStatus(s); _checker.setError(""); } else if (total > 0) { - System.out.println("Reseed complete, only " + total + " received"); - _checker.setError(ngettext("Reseed fetched only 1 router.", - "Reseed fetched only {0} routers.", total)); + String s = ngettext("Reseed fetched only 1 router.", + "Reseed fetched only {0} routers.", total); + System.out.println(s + getDisplayString(_url)); + _checker.setError(s); + _checker.setStatus(""); } else { if (total == 0) { - System.out.println("Reseed failed, check network connection"); + System.out.println("Reseed failed " + getDisplayString(_url) + ", check network connection"); System.out.println("Ensure that nothing blocks outbound HTTP or HTTPS, check the logs, " + "and if nothing helps, read the FAQ about reseeding manually."); - if (_sproxyHost != null && _sproxyPort > 0) - System.out.println("Check HTTPS proxy setting - host: " + _sproxyHost + " port: " + _sproxyPort); - else - System.out.println("Consider enabling an HTTPS proxy on the reseed configuration page"); + if (_url == null || "https".equals(_url.getScheme())) { + if (_sproxyHost != null && _sproxyPort > 0) + System.out.println("Check HTTPS proxy setting - host: " + _sproxyHost + " port: " + _sproxyPort); + else + System.out.println("Consider enabling an HTTPS proxy on the reseed configuration page"); + } else { + if (_proxyHost != null && _proxyPort > 0) + System.out.println("Check HTTP proxy setting - host: " + _proxyHost + " port: " + _proxyPort); + else + System.out.println("Consider enabling an HTTP proxy on the reseed configuration page"); + } } // else < 0, no valid URLs String old = _checker.getError(); _checker.setError(_t("Reseed failed.") + ' ' + _t("See {0} for help.", "" + _t("reseed configuration page") + "") + "
" + old); + _checker.setStatus(""); } _isRunning = false; // ReseedChecker will set timer to clean up @@ -597,16 +622,18 @@ public class Reseeder { * @return count of routerinfos successfully fetched **/ private int reseedOne(URI seedURL, boolean echoStatus) { + String s = getDisplayString(seedURL); try { // Don't use context clock as we may be adjusting the time final long timeLimit = System.currentTimeMillis() + MAX_TIME_PER_HOST; _checker.setStatus(_t("Reseeding: fetching seed URL.")); - System.err.println("Reseeding from " + seedURL); + System.err.println("Reseeding from " + s); byte contentRaw[] = readURL(seedURL); if (contentRaw == null) { // Logging deprecated here since attemptFailed() provides better info - _log.warn("Failed reading seed URL: " + seedURL); - System.err.println("Reseed got no router infos from " + seedURL); + if (_log.shouldWarn()) + _log.warn("Failed reading seed " + s); + System.err.println("Reseed got no router infos " + s); return 0; } String content = DataHelper.getUTF8(contentRaw); @@ -643,8 +670,9 @@ public class Reseeder { cur = end + 1; } if (total <= 0) { - _log.warn("Read " + contentRaw.length + " bytes from seed " + seedURL + ", but found no routerInfo URLs."); - System.err.println("Reseed got no router infos from " + seedURL); + if (_log.shouldWarn()) + _log.warn("Read " + contentRaw.length + " bytes " + s + ", but found no routerInfo URLs."); + System.err.println("Reseed got no router infos " + s); return 0; } @@ -676,14 +704,15 @@ public class Reseeder { if (errors >= 50 || (errors >= 10 && fetched <= 1)) break; } - System.err.println("Reseed got " + fetched + " router infos from " + seedURL + " with " + errors + " errors"); + System.err.println("Reseed got " + fetched + " router infos " + s + " with " + errors + " errors"); if (fetched > 0) _context.netDb().rescan(); return fetched; } catch (Throwable t) { - _log.warn("Error reseeding", t); - System.err.println("Reseed got no router infos from " + seedURL); + if (_log.shouldWarn()) + _log.warn("Error reseeding", t); + System.err.println("Reseed got no router infos " + s); return 0; } } @@ -732,7 +761,8 @@ public class Reseeder { File contentRaw = null; try { _checker.setStatus(_t("Reseeding: fetching seed URL.")); - System.err.println("Reseeding from " + seedURL); + String s = getDisplayString(seedURL); + System.err.println("Reseeding " + s); // don't use context time, as we may be step-changing it // from the server header long startTime = System.currentTimeMillis(); @@ -740,8 +770,9 @@ public class Reseeder { long totalTime = System.currentTimeMillis() - startTime; if (contentRaw == null) { // Logging deprecated here since attemptFailed() provides better info - _log.warn("Failed reading seed URL: " + seedURL); - System.err.println("Reseed got no router infos from " + seedURL); + if (_log.shouldWarn()) + _log.warn("Failed reading " + s); + System.err.println("Reseed got no router infos " + s); return 0; } if (totalTime > 0) { @@ -749,7 +780,7 @@ public class Reseeder { long bw = 1000 * sz / totalTime; _bandwidths.add(Long.valueOf(bw)); if (_log.shouldLog(Log.DEBUG)) - _log.debug("Rcvd " + sz + " bytes in " + totalTime + " ms from " + seedURL); + _log.debug("Rcvd " + sz + " bytes in " + totalTime + " ms " + getDisplayString(seedURL)); } int[] stats; if (isSU3) @@ -759,8 +790,9 @@ public class Reseeder { fetched = stats[0]; errors = stats[1]; } catch (Throwable t) { - System.err.println("Error reseeding: " + t); - _log.error("Error reseeding", t); + String s = getDisplayString(seedURL); + System.err.println("Error reseeding " + s + ": " + t); + _log.error("Error reseeding " + s, t); errors++; } finally { if (contentRaw != null) @@ -768,7 +800,7 @@ public class Reseeder { } _checker.setStatus( _t("Reseeding: fetching router info from seed URL ({0} successful, {1} errors).", fetched, errors)); - System.err.println("Reseed got " + fetched + " router infos from " + seedURL + " with " + errors + " errors"); + System.err.println("Reseed got " + fetched + " router infos " + getDisplayString(seedURL) + " with " + errors + " errors"); return fetched; } @@ -920,28 +952,26 @@ public class Reseeder { private byte[] readURL(URI url) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(4*1024); EepGet get; - boolean ssl = url.toString().startsWith("https"); + boolean ssl = "https".equals(url.getScheme()); if (ssl) { - boolean shouldProxy = _sproxyHost != null && _sproxyHost.length() > 0 && _sproxyPort > 0; - SSLEepGet.ProxyType ptype = getProxyType(); SSLEepGet sslget; if (_sslState == null) { - if (shouldProxy) - sslget = new SSLEepGet(_context, ptype, _sproxyHost, _sproxyPort, + if (_shouldProxySSL) + sslget = new SSLEepGet(_context, _sproxyType, _sproxyHost, _sproxyPort, baos, url.toString()); else sslget = new SSLEepGet(_context, baos, url.toString()); // save state for next time _sslState = sslget.getSSLState(); } else { - if (shouldProxy) - sslget = new SSLEepGet(_context, ptype, _sproxyHost, _sproxyPort, + if (_shouldProxySSL) + sslget = new SSLEepGet(_context, _sproxyType, _sproxyHost, _sproxyPort, baos, url.toString(), _sslState); else sslget = new SSLEepGet(_context, baos, url.toString(), _sslState); } get = sslget; - if (shouldProxy && _context.getBooleanProperty(PROP_SPROXY_AUTH_ENABLE)) { + if (_shouldProxySSL && _context.getBooleanProperty(PROP_SPROXY_AUTH_ENABLE)) { String user = _context.getProperty(PROP_SPROXY_USERNAME); String pass = _context.getProperty(PROP_SPROXY_PASSWORD); if (user != null && user.length() > 0 && @@ -950,10 +980,9 @@ public class Reseeder { } } else { // Do a (probably) non-proxied eepget into our ByteArrayOutputStream with 0 retries - boolean shouldProxy = _proxyHost != null && _proxyHost.length() > 0 && _proxyPort > 0; - get = new EepGet(_context, shouldProxy, _proxyHost, _proxyPort, 0, 0, MAX_RESEED_RESPONSE_SIZE, + get = new EepGet(_context, _shouldProxyHTTP, _proxyHost, _proxyPort, 0, 0, MAX_RESEED_RESPONSE_SIZE, null, baos, url.toString(), false, null, null); - if (shouldProxy && _context.getBooleanProperty(PROP_PROXY_AUTH_ENABLE)) { + if (_shouldProxyHTTP && _context.getBooleanProperty(PROP_PROXY_AUTH_ENABLE)) { String user = _context.getProperty(PROP_PROXY_USERNAME); String pass = _context.getProperty(PROP_PROXY_PASSWORD); if (user != null && user.length() > 0 && @@ -980,28 +1009,26 @@ public class Reseeder { private File fetchURL(URI url) throws IOException { File out = new File(_context.getTempDir(), "reseed-" + _context.random().nextInt() + ".tmp"); EepGet get; - boolean ssl = url.toString().startsWith("https"); + boolean ssl = "https".equals(url.getScheme()); if (ssl) { - boolean shouldProxy = _sproxyHost != null && _sproxyHost.length() > 0 && _sproxyPort > 0; - SSLEepGet.ProxyType ptype = getProxyType(); SSLEepGet sslget; if (_sslState == null) { - if (shouldProxy) - sslget = new SSLEepGet(_context, ptype, _sproxyHost, _sproxyPort, + if (_shouldProxySSL) + sslget = new SSLEepGet(_context, _sproxyType, _sproxyHost, _sproxyPort, out.getPath(), url.toString()); else sslget = new SSLEepGet(_context, out.getPath(), url.toString()); // save state for next time _sslState = sslget.getSSLState(); } else { - if (shouldProxy) - sslget = new SSLEepGet(_context, ptype, _sproxyHost, _sproxyPort, + if (_shouldProxySSL) + sslget = new SSLEepGet(_context, _sproxyType, _sproxyHost, _sproxyPort, out.getPath(), url.toString(), _sslState); else sslget = new SSLEepGet(_context, out.getPath(), url.toString(), _sslState); } get = sslget; - if (shouldProxy && _context.getBooleanProperty(PROP_SPROXY_AUTH_ENABLE)) { + if (_shouldProxySSL && _context.getBooleanProperty(PROP_SPROXY_AUTH_ENABLE)) { String user = _context.getProperty(PROP_SPROXY_USERNAME); String pass = _context.getProperty(PROP_SPROXY_PASSWORD); if (user != null && user.length() > 0 && @@ -1010,10 +1037,9 @@ public class Reseeder { } } else { // Do a (probably) non-proxied eepget into file with 0 retries - boolean shouldProxy = _proxyHost != null && _proxyHost.length() > 0 && _proxyPort > 0; - get = new EepGet(_context, shouldProxy, _proxyHost, _proxyPort, 0, 0, MAX_SU3_RESPONSE_SIZE, + get = new EepGet(_context, _shouldProxyHTTP, _proxyHost, _proxyPort, 0, 0, MAX_SU3_RESPONSE_SIZE, out.getPath(), null, url.toString(), false, null, null); - if (shouldProxy && _context.getBooleanProperty(PROP_PROXY_AUTH_ENABLE)) { + if (_shouldProxyHTTP && _context.getBooleanProperty(PROP_PROXY_AUTH_ENABLE)) { String user = _context.getProperty(PROP_PROXY_USERNAME); String pass = _context.getProperty(PROP_PROXY_PASSWORD); if (user != null && user.length() > 0 && @@ -1065,17 +1091,76 @@ public class Reseeder { } /** - * @throws IOException if unknown, default is HTTP + * @throws IllegalArgumentException if unknown, default is HTTP * @return non-null * @since 0.9.33 */ - private SSLEepGet.ProxyType getProxyType() throws IOException { + private SSLEepGet.ProxyType getProxyType() throws IllegalArgumentException { String sptype = _context.getProperty(PROP_SPROXY_TYPE, "HTTP").toUpperCase(Locale.US); - try { - return SSLEepGet.ProxyType.valueOf(sptype); - } catch (IllegalArgumentException iae) { - throw new IOException("Unsupported proxy type " + sptype); + return SSLEepGet.ProxyType.valueOf(sptype); + } + + /** + * Display string for what we're fetching. + * Untranslated, for logs only. + * + * @param url if null, returns "" + * @return non-null + * @since 0.9.33 + */ + private String getDisplayString(URI url) { + if (url == null) + return ""; + return getDisplayString(url.toString()); + } + + /** + * Display string for what we're fetching. + * Untranslated, for logs only. + * + * @param url if null, returns "" + * @return non-null + * @since 0.9.33 + */ + private String getDisplayString(String url) { + if (url == null) + return ""; + StringBuilder buf = new StringBuilder(64); + buf.append("from ").append(url); + boolean ssl = url.startsWith("https://"); + if (ssl && _shouldProxySSL) { + buf.append(" (using "); + switch(_sproxyType) { + case HTTP: + buf.append("HTTPS"); + break; + case SOCKS4: + buf.append("SOCKS 4/4a"); + break; + case SOCKS5: + buf.append("SOCKS 5"); + break; + default: + buf.append(_sproxyType.toString()); + break; + } + buf.append(" proxy "); + if (_sproxyHost.contains(":")) + buf.append('[').append(_sproxyHost).append(']'); + else + buf.append(_sproxyHost); + buf.append(':').append(_sproxyPort); + buf.append(')'); + } else if (!ssl && _shouldProxyHTTP) { + buf.append(" (using HTTP proxy "); + if (_proxyHost.contains(":")) + buf.append('[').append(_proxyHost).append(']'); + else + buf.append(_proxyHost); + buf.append(':').append(_proxyPort); + buf.append(')'); } + return buf.toString(); } }