Repository: seanmonstar/reqwest (language: rust)

Issue:
0.9.6 "connect" error on Android
In the most recent patch build we're seeing a Connection error that describes itself as "io error" (and barely any other information). We've only seen it on Android. Pinning the version to 0.9.5 fixes the issue.

Unfortunately, due to difficulty getting symbolicated stacks off of android, we don't have anything more than to say that the specific error we're getting formats as follows:

```
Error { kind: Hyper(Error { kind: Connect, cause: Custom { kind: Other, error: StringError("io error") } }), url: Some("https://latest.dev.lcip.org/.well-known/fxa-client-configuration") }
```

If you feel like debugging this yourself, I can give you steps to get set up, but it's a little involved if you want to do it in such a way that you have any insight into the rust code running under the hood. I'm also willing to help debug this in other ways, as we would rather not stay pinned to an old version forever.


Discussion / hints:
I believe this error is coming from trust-dns, since error claims it happened during `Connect`, and 0.9.6 replaced the blocking resolver with an async one. Additionally, I see in `trust-dns-resolver` that `io::Error`s toss their details and just say "io error".

Apart from that, I don't know why exactly it is failing. I'm thinking it may be loading the system conf that is failing...
Ah, so that's where it comes from. I can try getting more info out of the io error tomorrow if it would help.
In #429, we should be able to see better error details. If the error *is* around loading the system conf (`/etc/resolv.conf`), then maybe we can get that fixed in trust-dns, or at least in reqwest we can add a config flag when on Android to use the built-in `getaddrinfo` resolver instead.
I get `Error { kind: DnsSystemConf(Os { code: 2, kind: NotFound, message: "No such file or directory" }), url: None }` with this. So it looks like you were right, it is failing to load the system conf.

Fix patch:
diff --git a/.travis.yml b/.travis.yml
index 0581a0652..572e77dee 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -26,6 +26,13 @@ matrix:
         - rust: stable
           env: FEATURES="--features hyper-011"
 
+        # android
+        - rust: stable
+          env: TARGET=aarch64-linux-android
+          install: rustup target add "$TARGET"
+          # disable default-tls feature since cross-compiling openssl is dragons
+          script: cargo build --target "$TARGET" --no-default-features
+
         # minimum version
         - rust: 1.30.0
           script: cargo build
diff --git a/Cargo.toml b/Cargo.toml
index 3e6e1ffd3..ced131ba3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,7 +31,6 @@ tokio-executor = "0.1.4" # a minimum version so trust-dns-resolver compiles
 tokio-io = "0.1"
 tokio-threadpool = "0.1.8" # a minimum version so tokio compiles
 tokio-timer = "0.2.6" # a minimum version so trust-dns-resolver compiles
-trust-dns-resolver = "0.10"
 url = "1.2"
 uuid = { version = "0.7", features = ["v4"] }
 hyper-rustls = { version = "0.15", optional = true }
@@ -39,6 +38,9 @@ tokio-rustls = { version = "0.8", optional = true }
 webpki-roots = { version = "0.15", optional = true }
 rustls = { version = "0.14", features = ["dangerous_configuration"], optional = true }
 
+[target.'cfg(not(target_os = "android"))'.dependencies]
+trust-dns-resolver = "0.10"
+
 [dev-dependencies]
 env_logger = "0.6"
 serde_derive = "1.0"
diff --git a/src/connect.rs b/src/connect.rs
index cb580ce4a..a979a8545 100644
--- a/src/connect.rs
+++ b/src/connect.rs
@@ -13,10 +13,14 @@ use bytes::BufMut;
 use std::io;
 use std::sync::Arc;
 
+#[cfg(not(target_os = "android"))]
 use dns::TrustDnsResolver;
 use Proxy;
 
+#[cfg(not(target_os = "android"))]
 type HttpConnector = ::hyper::client::HttpConnector<TrustDnsResolver>;
+#[cfg(target_os = "android")]
+type HttpConnector = ::hyper::client::HttpConnector;
 
 
 pub(crate) struct Connector {
@@ -70,12 +74,18 @@ impl Connector {
     }
 }
 
+#[cfg(not(target_os = "android"))]
 fn http_connector() -> ::Result<HttpConnector> {
     TrustDnsResolver::new()
         .map(HttpConnector::new_with_resolver)
         .map_err(::error::dns_system_conf)
 }
 
+#[cfg(target_os = "android")]
+fn http_connector() -> ::Result<HttpConnector> {
+    Ok(HttpConnector::new(4))
+}
+
 impl Connect for Connector {
     type Transport = Conn;
     type Error = io::Error;
diff --git a/src/lib.rs b/src/lib.rs
index 008534ba5..28a28c0d9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -196,6 +196,7 @@ extern crate serde_urlencoded;
 extern crate tokio;
 #[cfg_attr(feature = "default-tls", macro_use)]
 extern crate tokio_io;
+#[cfg(not(target_os = "android"))]
 extern crate trust_dns_resolver;
 extern crate url;
 extern crate uuid;
@@ -237,6 +238,7 @@ mod connect;
 mod connect_async;
 mod body;
 mod client;
+#[cfg(not(target_os = "android"))]
 mod dns;
 mod into_url;
 mod proxy;


Test patch: