From 9ca625a64e8d5a5355c8d4b4b96a8b7f0da82b92 Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 24 Jan 2014 16:52:29 +0000 Subject: [PATCH] - Fix up the header processing for SSL thru HTTP proxy - Fix the CONNECT line output - Set use-plugin default to true - Log tweaks - rename a variable --- .../i2p/i2ptunnel/I2PTunnelHTTPClient.java | 41 ++++++++++++------- .../i2ptunnel/I2PTunnelOutproxyRunner.java | 14 +++---- .../src/net/i2p/i2ptunnel/web/EditBean.java | 7 +++- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java index ac3f3a466..cbf0fd556 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java @@ -52,6 +52,8 @@ import net.i2p.util.Translate; * $method /eepproxy/$site/$path $protocolVersion * * + * CONNECT (https) supported as of release 0.9.11. + * * Note that http://i2p/$b64key/... and /eepproxy/$site/... are not recommended * in browsers or other user-visible applications, as relative links will not * resolve correctly, cookies won't work, etc. @@ -332,12 +334,14 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn OutputStream out = null; /** - * The URL after fixup, always starting with http:// + * The URL after fixup, always starting with http:// or https:// */ String targetRequest = null; + // in-net outproxy boolean usingWWWProxy = false; - boolean usingOutproxy = false; + // local outproxy plugin + boolean usingInternalOutproxy = false; Outproxy outproxy = null; boolean usingInternalServer = false; String internalPath = null; @@ -425,7 +429,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn if (method.toUpperCase(Locale.US).equals("CONNECT")) { // this makes things easier later, by spoofing a // protocol so the URI parser find the host and port - // FIXME breaks in-net outproxy + // For in-net outproxy, will be fixed up below request = "https://" + request + '/'; } @@ -711,14 +715,14 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn remotePort = 443; else remotePort = 80; - usingOutproxy = true; + usingInternalOutproxy = true; targetRequest = requestURI.toASCIIString(); if(_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix(requestId) + " [" + host + "]: outproxy!"); } } } - if (!usingOutproxy) { + if (!usingInternalOutproxy) { if(port >= 0) { host = host + ':' + port; } @@ -738,7 +742,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn if(_log.shouldLog(Log.WARN)) { _log.warn(getPrefix(requestId) + "Host wants to be outproxied, but we dont have any!"); } - l.log("No HTTP outproxy found for the request."); + l.log("No outproxy found for the request."); if(out != null) { out.write(getErrorPage("noproxy", _ERR_NO_OUTPROXY)); writeFooter(out); @@ -769,7 +773,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn return; } // end host name processing - boolean isValid = usingOutproxy || usingWWWProxy || + boolean isValid = usingInternalOutproxy || usingWWWProxy || usingInternalServer || isSupportedAddress(host, protocol); if(!isValid) { if(_log.shouldLog(Log.INFO)) { @@ -780,7 +784,12 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn break; } - line = method + ' ' + requestURI.toASCIIString() + ' ' + protocolVersion; + if (method.toUpperCase(Locale.US).equals("CONNECT")) { + // fix up the change to requestURI above to get back to the original host:port + line = method + ' ' + requestURI.getHost() + ':' + requestURI.getPort() + ' ' + protocolVersion; + } else { + line = method + ' ' + requestURI.toASCIIString() + ' ' + protocolVersion; + } if(_log.shouldLog(Log.DEBUG)) { _log.debug(getPrefix(requestId) + "NEWREQ: \"" + line + "\""); @@ -791,7 +800,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn // end first line processing } else { - if(lowercaseLine.startsWith("host: ") && !usingWWWProxy && !usingOutproxy) { + if(lowercaseLine.startsWith("host: ") && !usingWWWProxy && !usingInternalOutproxy) { // Note that we only pass the original Host: line through to the outproxy // But we don't create a Host: line if it wasn't sent to us line = "Host: " + host; @@ -853,17 +862,19 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn if(ok != null) { gzip = Boolean.parseBoolean(ok); } - if(gzip && !usingInternalServer) { + if(gzip && !usingInternalServer && + !method.toUpperCase(Locale.US).equals("CONNECT")) { // according to rfc2616 s14.3, this *should* force identity, even if // an explicit q=0 for gzip doesn't. tested against orion.i2p, and it // seems to work. newRequest.append("Accept-Encoding: \r\n"); - newRequest.append("X-Accept-Encoding: x-i2p-gzip;q=1.0, identity;q=0.5, deflate;q=0, gzip;q=0, *;q=0\r\n"); + if (!usingInternalOutproxy) + newRequest.append("X-Accept-Encoding: x-i2p-gzip;q=1.0, identity;q=0.5, deflate;q=0, gzip;q=0, *;q=0\r\n"); } - if(!shout) { + if(!shout && !method.toUpperCase(Locale.US).equals("CONNECT")) { if(!Boolean.parseBoolean(getTunnel().getClientOptions().getProperty(PROP_USER_AGENT))) { // let's not advertise to external sites that we are from I2P - if(usingWWWProxy || usingOutproxy) { + if(usingWWWProxy || usingInternalOutproxy) { newRequest.append("User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6\r\n"); } else { newRequest.append("User-Agent: MYOB/6.66 (AN/ON)\r\n"); @@ -896,7 +907,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn _log.debug(getPrefix(requestId) + "NewRequest header: [" + newRequest.toString() + "]"); } - if(method == null || (destination == null && !usingOutproxy)) { + if(method == null || (destination == null && !usingInternalOutproxy)) { //l.log("No HTTP method found in the request."); if(out != null) { if(protocol != null && "http".equals(protocol.toLowerCase(Locale.US))) { @@ -945,7 +956,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn } // no destination, going to outproxy plugin - if (usingOutproxy) { + if (usingInternalOutproxy) { Socket outSocket = outproxy.connect(host, remotePort); Runnable onTimeout = new OnTimeout(s, s.getOutputStream(), targetRequest, usingWWWProxy, currentProxy, requestId); byte[] data; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelOutproxyRunner.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelOutproxyRunner.java index a399a6ed0..d59d84c78 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelOutproxyRunner.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelOutproxyRunner.java @@ -39,9 +39,9 @@ public class I2PTunnelOutproxyRunner extends I2PAppThread { * Sun's impl of BufferedOutputStream), but that is the streaming * api's job... */ - static int MAX_PACKET_SIZE = 1024 * 4; + private static final int MAX_PACKET_SIZE = 1024 * 4; - static final int NETWORK_BUFFER_SIZE = MAX_PACKET_SIZE; + private static final int NETWORK_BUFFER_SIZE = MAX_PACKET_SIZE; private final Socket s; private final Socket i2ps; @@ -61,7 +61,7 @@ public class I2PTunnelOutproxyRunner extends I2PAppThread { private static final AtomicLong __forwarderId = new AtomicLong(); /** - * Starts itself + * Starts itself (fixme) * * @param slock the socket lock, non-null * @param initialI2PData may be null @@ -80,9 +80,9 @@ public class I2PTunnelOutproxyRunner extends I2PAppThread { startedOn = Clock.getInstance().now(); _log = I2PAppContext.getGlobalContext().logManager().getLog(getClass()); if (_log.shouldLog(Log.INFO)) - _log.info("I2PTunnelRunner started"); + _log.info("OutproxyRunner started"); _runnerId = __runnerId.incrementAndGet(); - setName("I2PTunnelOutproxyRunner " + _runnerId); + setName("OutproxyRunner " + _runnerId); start(); } @@ -254,9 +254,9 @@ public class I2PTunnelOutproxyRunner extends I2PAppThread { this.in = in; this.out = out; _toI2P = toI2P; - direction = (toI2P ? "toI2P" : "fromI2P"); + direction = (toI2P ? "toOutproxy" : "fromOutproxy"); _cache = ByteCache.getInstance(32, NETWORK_BUFFER_SIZE); - setName("StreamForwarder " + _runnerId + '.' + __forwarderId.incrementAndGet()); + setName("OutproxyForwarder " + _runnerId + '.' + __forwarderId.incrementAndGet()); start(); } 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 c67083a4f..990d2d1f1 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java @@ -251,9 +251,12 @@ public class EditBean extends IndexBean { return getProperty(tunnel, I2PTunnelHTTPClient.PROP_SSL_OUTPROXIES, ""); } - /** @since 0.9.11 */ + /** + * Default true + * @since 0.9.11 + */ public boolean getUseOutproxyPlugin(int tunnel) { - return getBooleanProperty(tunnel, I2PTunnelHTTPClient.PROP_USE_OUTPROXY_PLUGIN); + return Boolean.parseBoolean(getProperty(tunnel, I2PTunnelHTTPClient.PROP_USE_OUTPROXY_PLUGIN, "true")); } /** all of these are @since 0.8.3 */