diff options
Diffstat (limited to 'src/com/isode')
6 files changed, 204 insertions, 15 deletions
diff --git a/src/com/isode/stroke/network/HTTPConnectProxiedConnection.java b/src/com/isode/stroke/network/HTTPConnectProxiedConnection.java index a85758c..d2915bd 100644 --- a/src/com/isode/stroke/network/HTTPConnectProxiedConnection.java +++ b/src/com/isode/stroke/network/HTTPConnectProxiedConnection.java @@ -4,7 +4,7 @@ * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2011-2015 Isode Limited. + * Copyright (c) 2011-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -19,6 +19,8 @@ package com.isode.stroke.network; import com.isode.stroke.base.SafeByteArray; import com.isode.stroke.stringcodecs.Base64; +import java.util.ArrayList; +import java.util.List; import java.util.Scanner; import java.util.Vector; @@ -28,6 +30,7 @@ public class HTTPConnectProxiedConnection extends ProxiedConnection { private SafeByteArray authPassword_; private HTTPTrafficFilter trafficFilter_; private StringBuffer httpResponseBuffer_ = new StringBuffer(""); + private final List<Pair> nextHTTPRequestHeaders_ = new ArrayList<Pair>(); public static class Pair { String a; @@ -51,6 +54,8 @@ public class HTTPConnectProxiedConnection extends ProxiedConnection { } protected void initializeProxy() { + httpResponseBuffer_.setLength(0); + StringBuffer connect = new StringBuffer(); connect.append("CONNECT ").append(getServer().getAddress().toString()).append(":").append(getServer().getPort()).append(" HTTP/1.1\r\n"); SafeByteArray data = new SafeByteArray(connect.toString()); @@ -62,8 +67,16 @@ public class HTTPConnectProxiedConnection extends ProxiedConnection { data.append(Base64.encode(credentials)); data.append(new SafeByteArray("\r\n")); } + else if (!nextHTTPRequestHeaders_.isEmpty()) { + for (Pair headerField : nextHTTPRequestHeaders_) { + data.append(headerField.a); + data.append(": "); + data.append(headerField.b); + data.append("\r\n"); + } + nextHTTPRequestHeaders_.clear(); + } data.append(new SafeByteArray("\r\n")); - //SWIFT_LOG(debug) << "HTTP Proxy send headers: " << byteArrayToString(ByteArray(data.begin(), data.end())) << std::endl; write(data); } @@ -85,12 +98,12 @@ public class HTTPConnectProxiedConnection extends ProxiedConnection { String statusLine = parseHTTPHeader(httpResponseBuffer_.substring(0, headerEnd), headerFields); if (trafficFilter_ != null) { - Vector<Pair> newHeaderFields = trafficFilter_.filterHTTPResponseHeader(headerFields); + Vector<Pair> newHeaderFields = trafficFilter_.filterHTTPResponseHeader(statusLine, headerFields); if (!newHeaderFields.isEmpty()) { - StringBuffer statusLines = new StringBuffer(); - statusLines.append("CONNECT ").append(getServer().getAddress().toString()).append(":").append(getServer().getPort()); - sendHTTPRequest(statusLines.toString(), newHeaderFields); - return; + reconnect(); + nextHTTPRequestHeaders_.clear(); + nextHTTPRequestHeaders_.addAll(newHeaderFields); + return; } } diff --git a/src/com/isode/stroke/network/HTTPTrafficFilter.java b/src/com/isode/stroke/network/HTTPTrafficFilter.java index 86f0659..c9a039e 100644 --- a/src/com/isode/stroke/network/HTTPTrafficFilter.java +++ b/src/com/isode/stroke/network/HTTPTrafficFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Isode Limited. + * Copyright (c) 2015-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -18,8 +18,9 @@ public interface HTTPTrafficFilter { /** * @brief This method is called by the HTTPConnectPRoxiedConnection on every incoming HTTP response. * It can be used to insert additional HTTP requests into the HTTP CONNECT proxy initalization process. + * @param statusLine status line from a HTTP header * @return A vector of HTTP header fields to use in a new request. If an empty vector is returned, * no new request will be send and the normal proxy logic continues. */ - public Vector<HTTPConnectProxiedConnection.Pair> filterHTTPResponseHeader(final Vector<HTTPConnectProxiedConnection.Pair> responseHeader); + public Vector<HTTPConnectProxiedConnection.Pair> filterHTTPResponseHeader(String statusLine, final Vector<HTTPConnectProxiedConnection.Pair> responseHeader); }
\ No newline at end of file diff --git a/src/com/isode/stroke/network/JavaNetworkEnviroment.java b/src/com/isode/stroke/network/JavaNetworkEnviroment.java new file mode 100644 index 0000000..0113c57 --- /dev/null +++ b/src/com/isode/stroke/network/JavaNetworkEnviroment.java @@ -0,0 +1,51 @@ +/* Copyright (c) 2016, Isode Limited, London, England. + * All rights reserved. + * + * Acquisition and use of this software and related materials for any + * purpose requires a written license agreement from Isode Limited, + * or a written license from an organisation licensed by Isode Limited + * to grant such a license. + * + */ +package com.isode.stroke.network; + +import java.net.SocketException; +import java.util.Enumeration; +import java.util.Vector; +import java.util.logging.Logger; + +/** + * Java implementation of {@link NetworkEnvironment} + */ +public class JavaNetworkEnviroment extends NetworkEnvironment { + + /** + * Logger + */ + private final Logger logger = Logger.getLogger(this.getClass().getName()); + + @Override + public Vector<NetworkInterface> getNetworkInterfaces() { + Vector<NetworkInterface> results = new Vector<NetworkInterface>(); + try { + Enumeration<java.net.NetworkInterface> javaNIEnumeration = + java.net.NetworkInterface.getNetworkInterfaces(); + if (javaNIEnumeration.hasMoreElements()) { + java.net.NetworkInterface javaNI = javaNIEnumeration.nextElement(); + try { + NetworkInterface strokeNI = new NetworkInterface(javaNI); + results.add(strokeNI); + } catch (SocketException e) { + logger.warning("Error determining if "+javaNI+ + " is loopback : "+e.getMessage()); + } + + } + } + catch (SocketException e) { + logger.warning("Error occured when getting network interfaces - "+e.getMessage()); + } + return results; + } + +} diff --git a/src/com/isode/stroke/network/NetworkInterface.java b/src/com/isode/stroke/network/NetworkInterface.java index 5590837..1bffafc 100644 --- a/src/com/isode/stroke/network/NetworkInterface.java +++ b/src/com/isode/stroke/network/NetworkInterface.java @@ -4,7 +4,7 @@ * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2015 Isode Limited. + * Copyright (c) 2015-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -16,6 +16,9 @@ package com.isode.stroke.network; +import java.net.InetAddress; +import java.net.SocketException; +import java.util.Enumeration; import java.util.Vector; public class NetworkInterface { @@ -28,6 +31,25 @@ public class NetworkInterface { this.name = name; this.loopback = loopback; } + + /** + * Creates a {@link NetworkInterface} from a {@link java.net.NetworkInterface} including + * all addresses in the {@link java.net.NetworkInterface} + * @param javaNI The {@link java.net.NetworkInterface} to create the {@link NetworkInterface} + * from, should not be {@code null}. + * @throws SocketException If an I/O error occurs when trying to determine if it is + * a loop back interface. + */ + public NetworkInterface(java.net.NetworkInterface javaNI) throws SocketException { + this.name = javaNI.getName(); + this.loopback = javaNI.isLoopback(); + Enumeration<InetAddress> addressEnumeration = javaNI.getInetAddresses(); + while (addressEnumeration.hasMoreElements()) { + InetAddress inetAddress = addressEnumeration.nextElement(); + HostAddress hostAddress = new HostAddress(inetAddress); + addAddress(hostAddress); + } + } public void addAddress(final HostAddress address) { addresses.add(address); diff --git a/src/com/isode/stroke/network/PlatformDomainNameAddressQuery.java b/src/com/isode/stroke/network/PlatformDomainNameAddressQuery.java new file mode 100644 index 0000000..24deb4d --- /dev/null +++ b/src/com/isode/stroke/network/PlatformDomainNameAddressQuery.java @@ -0,0 +1,86 @@ +/* Copyright (c) 2016, Isode Limited, London, England. + * All rights reserved. + * + * Acquisition and use of this software and related materials for any + * purpose requires a written license agreement from Isode Limited, + * or a written license from an organisation licensed by Isode Limited + * to grant such a license. + * + */ +package com.isode.stroke.network; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.isode.stroke.eventloop.Event.Callback; +import com.isode.stroke.eventloop.EventLoop; + +public class PlatformDomainNameAddressQuery extends DomainNameAddressQuery { + + private final String host_; + private final EventLoop eventLoop_; + + public PlatformDomainNameAddressQuery(String host,EventLoop eventLoop) { + host_ = host; + eventLoop_ = eventLoop; + } + + private class QueryRunnable implements Runnable { + + private final List<HostAddress> results_ = + Collections.synchronizedList(new ArrayList<HostAddress>()); + + @Override + public void run() { + try { + InetAddress[] inetAddresses = InetAddress.getAllByName(host_); + for (InetAddress address : inetAddresses) { + HostAddress result = new HostAddress(address); + results_.add(result); + } + } catch (UnknownHostException e) { + emitError(); + } + emitResults(); + } + + private void emitError() { + eventLoop_.postEvent(new Callback() { + + @Override + public void run() { + onResult.emit(new ArrayList<HostAddress>(),new DomainNameResolveError()); + } + + }); + } + + private void emitResults() { + eventLoop_.postEvent(new Callback() { + + @Override + public void run() { + // For thread safety emit a copy of the results + List<HostAddress> resultCopy = new ArrayList<HostAddress>(); + synchronized (results_) { + resultCopy.addAll(results_); + } + onResult.emit(results_,null); + } + + }); + } + + } + + @Override + public void run() { + Thread queryThread = new Thread(new QueryRunnable()); + queryThread.setDaemon(true); + queryThread.run(); + } + +} diff --git a/src/com/isode/stroke/network/ProxiedConnection.java b/src/com/isode/stroke/network/ProxiedConnection.java index a94fbc5..6f4c044 100644 --- a/src/com/isode/stroke/network/ProxiedConnection.java +++ b/src/com/isode/stroke/network/ProxiedConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015 Isode Limited. + * Copyright (c) 2012-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -27,8 +27,8 @@ public abstract class ProxiedConnection extends Connection { private HostAddressPort server_; private Connector connector_; private Connection connection_; - private SignalConnection onDataReadConnection; - private SignalConnection onDisconnectedConnection; + private SignalConnection onDataReadConnection_; + private SignalConnection onDisconnectedConnection_; private SignalConnection onConnectFinishedConnection; public ProxiedConnection(DomainNameResolver resolver, ConnectionFactory connectionFactory, TimerFactory timerFactory, final String proxyHost, int proxyPort) { @@ -45,8 +45,8 @@ public abstract class ProxiedConnection extends Connection { try { cancelConnector(); if (connection_ != null) { - onDataReadConnection.disconnect(); - onDisconnectedConnection.disconnect(); + onDataReadConnection_.disconnect(); + onDisconnectedConnection_.disconnect(); } if (connected_) { System.err.println("Warning: Connection was still established."); @@ -147,4 +147,20 @@ public abstract class ProxiedConnection extends Connection { protected HostAddressPort getServer() { return server_; } + + protected void reconnect() { + if (onDataReadConnection_ != null) { + onDataReadConnection_.disconnect(); + onDataReadConnection_ = null; + } + if (onDisconnectedConnection_ != null) { + onDisconnectedConnection_.disconnect(); + onDisconnectedConnection_ = null; + } + if (connected_) { + connection_.disconnect(); + } + connect(server_); + } + }
\ No newline at end of file |