diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java index 65af72159431522a9bd6d632154116f5a7495378..ac3f3a466d23259ec90b8a908797fb7ff34ea507 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java @@ -323,7 +323,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn public static final String PROP_VIA = "i2ptunnel.httpclient.sendVia"; public static final String PROP_JUMP_SERVERS = "i2ptunnel.httpclient.jumpServers"; public static final String PROP_DISABLE_HELPER = "i2ptunnel.httpclient.disableAddressHelper"; - public static final String PROP_OUTPROXY = "i2ptunnel.useLocalOutproxy"; + /** @since 0.9.11 */ + public static final String PROP_USE_OUTPROXY_PLUGIN = "i2ptunnel.useLocalOutproxy"; + /** @since 0.9.11 */ + public static final String PROP_SSL_OUTPROXIES = "i2ptunnel.httpclient.SSLOutproxies"; protected void clientConnectionRun(Socket s) { OutputStream out = null; @@ -694,7 +697,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn s.close(); return; } else if(host.contains(".") || host.startsWith("[")) { - if (Boolean.parseBoolean(getTunnel().getClientOptions().getProperty(PROP_OUTPROXY))) { + if (Boolean.parseBoolean(getTunnel().getClientOptions().getProperty(PROP_USE_OUTPROXY_PLUGIN))) { ClientAppManager mgr = _context.clientAppManager(); if (mgr != null) { ClientApp op = mgr.getRegisteredApp(Outproxy.NAME); @@ -723,7 +726,11 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn if(_log.shouldLog(Log.DEBUG)) { _log.debug("Before selecting outproxy for " + host); } - currentProxy = selectProxy(); + if ("https".equals(protocol) || + method.toUpperCase(Locale.US).equals("CONNECT")) + currentProxy = selectSSLProxy(); + else + currentProxy = selectProxy(); if(_log.shouldLog(Log.DEBUG)) { _log.debug("After selecting outproxy for " + host + ": " + currentProxy); } @@ -1102,6 +1109,26 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn } } + /** + * Unlike selectProxy(), we parse the option on the fly so it + * can be changed. selectProxy() requires restart... + * @return null if none + * @since 0.9.11 + */ + private String selectSSLProxy() { + String s = getTunnel().getClientOptions().getProperty(PROP_SSL_OUTPROXIES); + if (s == null) + return null; + String[] p = s.split(", "); + if (p.length == 0) + return null; + // todo doesn't check for "" + if (p.length == 1) + return p[0]; + int i = _context.random().nextInt(p.length); + return p[i]; + } + /** @since 0.8.7 */ private void writeHelperSaveForm(OutputStream out, String destination, String ahelperKey, String targetRequest, String referer) throws IOException { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java index 6e917cf0c13725e81306fac0803a51a9e2c40e42..c67083a4f76e91c91644250689dc8f39d73ab99b 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java @@ -245,7 +245,17 @@ public class EditBean extends IndexBean { return ""; return getProperty(tunnel, I2PTunnelHTTPClientBase.PROP_OUTPROXY_PW, ""); } + + /** @since 0.9.11 */ + public String getSslProxies(int tunnel) { + return getProperty(tunnel, I2PTunnelHTTPClient.PROP_SSL_OUTPROXIES, ""); + } + /** @since 0.9.11 */ + public boolean getUseOutproxyPlugin(int tunnel) { + return getBooleanProperty(tunnel, I2PTunnelHTTPClient.PROP_USE_OUTPROXY_PLUGIN); + } + /** all of these are @since 0.8.3 */ public String getLimitMinute(int tunnel) { return getProperty(tunnel, PROP_MAX_CONNS_MIN, "0"); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java index 56be5d3a83731f4a14c9d906227235c6fc48873c..81833c991064628c7266f10431e7024ccd18135d 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java @@ -868,6 +868,17 @@ public class IndexBean { if (s != null) _otherOptions.put(I2PTunnelHTTPClientBase.PROP_OUTPROXY_PW, s.trim()); } + + /** @since 0.9.11 */ + public void setSslProxies(String s) { + if (s != null) + _otherOptions.put(I2PTunnelHTTPClient.PROP_SSL_OUTPROXIES, s.trim().replace(" ", ",")); + } + + /** @since 0.9.11 */ + public void setUseOutproxyPlugin(String moo) { + _booleanOptions.add(I2PTunnelHTTPClient.PROP_USE_OUTPROXY_PLUGIN); + } /** all of these are @since 0.8.3 */ protected static final String PROP_MAX_CONNS_MIN = "i2p.streaming.maxConnsPerMinute"; @@ -1189,7 +1200,8 @@ public class IndexBean { "i2cp.reduceOnIdle", "i2cp.closeOnIdle", "i2cp.newDestOnResume", "persistentClientKey", "i2cp.delayOpen" }; private static final String _booleanProxyOpts[] = { - I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH + I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH, + I2PTunnelHTTPClient.PROP_USE_OUTPROXY_PLUGIN }; private static final String _booleanServerOpts[] = { "i2cp.reduceOnIdle", "i2cp.encryptLeaseSet", PROP_ENABLE_ACCESS_LIST, PROP_ENABLE_BLACKLIST, @@ -1199,7 +1211,8 @@ public class IndexBean { "i2cp.reduceIdleTime", "i2cp.reduceQuantity", "i2cp.closeIdleTime", "outproxyUsername", "outproxyPassword", I2PTunnelHTTPClient.PROP_JUMP_SERVERS, - I2PTunnelHTTPClientBase.PROP_AUTH + I2PTunnelHTTPClientBase.PROP_AUTH, + I2PTunnelHTTPClient.PROP_SSL_OUTPROXIES }; private static final String _otherServerOpts[] = { "i2cp.reduceIdleTime", "i2cp.reduceQuantity", "i2cp.leaseSetKey", "i2cp.accessList", diff --git a/apps/i2ptunnel/jsp/editClient.jsp b/apps/i2ptunnel/jsp/editClient.jsp index 41727d79f06824180dcff5a37bf185cc7147a819..ff397556cfc5f750a9ca7984c1799b088a0e73ee 100644 --- a/apps/i2ptunnel/jsp/editClient.jsp +++ b/apps/i2ptunnel/jsp/editClient.jsp @@ -151,6 +151,21 @@ input.default { width: 1px; height: 1px; visibility: hidden; } <%=intl._("Outproxies")%>(<span class="accessKey">x</span>): </label> <input type="text" size="30" id="proxyList" name="proxyList" title="List of Outproxy I2P destinations" value="<%=editBean.getClientDestination(curTunnel)%>" class="freetext" /> + </div> + <% if ("httpclient".equals(tunnelType)) { + %><div id="destinationField" class="rowItem"> + <label> + <%=intl._("SSL Outproxies")%>: + </label> + <input type="text" size="30" id="sslProxyList" name="sslProxies" title="List of Outproxy I2P destinations" value="<%=editBean.getSslProxies(curTunnel)%>" class="freetext" /> + </div> + <% } // httpclient %> + <div id="startupField" class="rowItem"> + <label> + <%=intl._("Use Outproxy Plugin")%>: + </label> + <input value="1" type="checkbox" id="shared" name="useOutproxyPlugin" title="Use plugin instead of above-listed proxies if available"<%=(editBean.getUseOutproxyPlugin(curTunnel) ? " checked=\"checked\"" : "")%> class="tickbox" /> + <span class="comment"><%=intl._("(Check the Box for 'YES')")%></span> </div> <% } else if ("client".equals(tunnelType) || "ircclient".equals(tunnelType) || "streamrclient".equals(tunnelType)) { %><div id="destinationField" class="rowItem">