Created
February 28, 2017 17:10
-
-
Save ericcj/a4e5c99982d36d3348ff3c732fa51038 to your computer and use it in GitHub Desktop.
Naive timeout for DNS resolution using a thread per request
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Based on http://stackoverflow.com/questions/693997/how-to-set-httpresponse-timeout-for-android-in-java/31643186#31643186 | |
* as per https://github.com/square/okhttp/issues/95 | |
*/ | |
private static class DNSTimeoutInterceptor implements Interceptor { | |
long mTimeoutMillis; | |
public DNSTimeoutInterceptor(long timeoutMillis) { | |
mTimeoutMillis = timeoutMillis; | |
} | |
@Override | |
public Response intercept(final Chain chain) throws IOException { | |
Request request = chain.request(); | |
Log.SplitTimer timer = (request.tag() instanceof RequestTag ? ((RequestTag) request.tag()).getTimer() : null); | |
// underlying call should timeout after 2 tries of 5s: https://android.googlesource.com/platform/bionic/+/android-5.1.1_r38/libc/dns/include/resolv_private.h#137 | |
// could use our own Dns implementation that falls back to public DNS servers: https://garage.easytaxi.com/tag/dns-android-okhttp/ | |
if (!DNSResolver.isDNSReachable(request.url().host(), mTimeoutMillis)) { | |
throw new UnknownHostException("DNS timeout"); | |
} | |
return chain.proceed(request); | |
} | |
private static class DNSResolver implements Runnable { | |
private String mDomain; | |
private InetAddress mAddress; | |
public static boolean isDNSReachable(String domain, long timeoutMillis) { | |
try { | |
DNSResolver dnsRes = new DNSResolver(domain); | |
Thread t = new Thread(dnsRes, "DNSResolver"); | |
t.start(); | |
t.join(timeoutMillis); | |
return dnsRes.get() != null; | |
} catch(Exception e) { | |
return false; | |
} | |
} | |
public DNSResolver(String domain) { | |
this.mDomain = domain; | |
} | |
public void run() { | |
try { | |
InetAddress addr = InetAddress.getByName(mDomain); | |
set(addr); | |
} catch (UnknownHostException e) { | |
} | |
} | |
public synchronized void set(InetAddress inetAddr) { | |
this.mAddress = inetAddr; | |
} | |
public synchronized InetAddress get() { | |
return mAddress; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment