am aa83190c: Merge "Honor NetworkSecurityPolicy regarding cleartext traffic."
* commit 'aa83190cb650e9b714f2b980aa29ece8f86d587a':
Honor NetworkSecurityPolicy regarding cleartext traffic.
diff --git a/src/org/apache/http/impl/client/DefaultRequestDirector.java b/src/org/apache/http/impl/client/DefaultRequestDirector.java
index 9aafa85..6f9dcd0 100644
--- a/src/org/apache/http/impl/client/DefaultRequestDirector.java
+++ b/src/org/apache/http/impl/client/DefaultRequestDirector.java
@@ -33,6 +33,7 @@
import java.io.IOException;
import java.io.InterruptedIOException;
+import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Locale;
@@ -430,6 +431,12 @@
if (this.log.isDebugEnabled()) {
this.log.debug("Attempt " + execCount + " to execute request");
}
+ // BEGIN android-added
+ if ((!route.isSecure()) && (!isCleartextTrafficPermitted())) {
+ throw new IOException(
+ "Cleartext traffic not permitted: " + route.getTargetHost());
+ }
+ // END android-added
response = requestExec.execute(wrapper, managedConn, context);
retrying = false;
@@ -1121,4 +1128,40 @@
authState.setCredentials(creds);
}
+ // BEGIN android-added
+ /** Cached instance of android.security.NetworkSecurityPolicy. */
+ private static Object networkSecurityPolicy;
+
+ /** Cached android.security.NetworkSecurityPolicy.isCleartextTrafficPermitted method. */
+ private static Method cleartextTrafficPermittedMethod;
+
+ private static boolean isCleartextTrafficPermitted() {
+ // TODO: Remove this method once NetworkSecurityPolicy can be accessed without Reflection.
+ // This method invokes NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted
+ // via Reflection API.
+ // Because of the way external/apache-http is built, in the near term it can't invoke new
+ // Android framework API directly.
+ try {
+ Object policy;
+ Method method;
+ synchronized (DefaultRequestDirector.class) {
+ if (cleartextTrafficPermittedMethod == null) {
+ Class<?> cls = Class.forName("android.security.NetworkSecurityPolicy");
+ Method getInstanceMethod = cls.getMethod("getInstance");
+ networkSecurityPolicy = getInstanceMethod.invoke(null);
+ cleartextTrafficPermittedMethod = cls.getMethod("isCleartextTrafficPermitted");
+ }
+ policy = networkSecurityPolicy;
+ method = cleartextTrafficPermittedMethod;
+ }
+ return (Boolean) method.invoke(policy);
+ } catch (ReflectiveOperationException e) {
+ // Can't access the Android framework NetworkSecurityPolicy. To be backward compatible,
+ // assume that cleartext traffic is permitted. Android CTS will take care of ensuring
+ // this issue doesn't occur on new Android platforms.
+ return true;
+ }
+ }
+ // END android-added
+
} // class DefaultClientRequestDirector