summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/com/isode/stroke/network/HTTPConnectProxiedConnection.java27
-rw-r--r--src/com/isode/stroke/network/HTTPTrafficFilter.java5
-rw-r--r--src/com/isode/stroke/network/JavaNetworkEnviroment.java51
-rw-r--r--src/com/isode/stroke/network/NetworkInterface.java24
-rw-r--r--src/com/isode/stroke/network/PlatformDomainNameAddressQuery.java86
-rw-r--r--src/com/isode/stroke/network/ProxiedConnection.java26
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