generated from Grigo/AndroidTemplate
111 lines
3.8 KiB
Java
111 lines
3.8 KiB
Java
package com.grigowashere.aismap.utils;
|
|
|
|
import android.util.Log;
|
|
|
|
import java.io.InputStream;
|
|
import java.net.ConnectException;
|
|
import java.net.HttpURLConnection;
|
|
import java.net.NoRouteToHostException;
|
|
import java.net.SocketTimeoutException;
|
|
import java.net.URL;
|
|
import java.net.UnknownHostException;
|
|
import java.security.cert.CertificateException;
|
|
import java.util.Locale;
|
|
|
|
import javax.net.ssl.SSLException;
|
|
import javax.net.ssl.SSLHandshakeException;
|
|
import javax.net.ssl.SSLPeerUnverifiedException;
|
|
|
|
/**
|
|
* Lightweight reachability check for {@code https://aismap.local/} (feasibility / diagnostics).
|
|
* Runs on a background thread; callers must not invoke from the UI thread.
|
|
*/
|
|
public final class AismapLocalHttpsProbe {
|
|
|
|
private static final String TAG = "AismapLocalHttpsProbe";
|
|
|
|
/** Hub HTTPS root — user-requested feasibility target. */
|
|
public static final String PROBE_URL = "https://aismap.local/";
|
|
|
|
private static final int CONNECT_TIMEOUT_MS = 2500;
|
|
private static final int READ_TIMEOUT_MS = 2500;
|
|
|
|
private AismapLocalHttpsProbe() {}
|
|
|
|
/**
|
|
* Performs a GET with short timeouts. Returns a short UI-safe line (no stack traces).
|
|
*/
|
|
public static String probeOnce() {
|
|
HttpURLConnection conn = null;
|
|
try {
|
|
URL url = new URL(PROBE_URL);
|
|
conn = (HttpURLConnection) url.openConnection();
|
|
conn.setConnectTimeout(CONNECT_TIMEOUT_MS);
|
|
conn.setReadTimeout(READ_TIMEOUT_MS);
|
|
conn.setRequestMethod("GET");
|
|
conn.setInstanceFollowRedirects(true);
|
|
conn.setUseCaches(false);
|
|
int code = conn.getResponseCode();
|
|
InputStream body = code >= HttpURLConnection.HTTP_BAD_REQUEST
|
|
? conn.getErrorStream() : conn.getInputStream();
|
|
drain(body);
|
|
if (code >= 200 && code < 400) {
|
|
return "HTTPS aismap.local: OK HTTP " + code;
|
|
}
|
|
return "HTTPS aismap.local: HTTP " + code;
|
|
} catch (Throwable t) {
|
|
Log.w(TAG, "probe failed: " + t.getClass().getSimpleName() + ": " + t.getMessage(), t);
|
|
return "HTTPS aismap.local: " + classify(t);
|
|
} finally {
|
|
if (conn != null) {
|
|
try {
|
|
conn.disconnect();
|
|
} catch (Throwable ignore) {}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void drain(InputStream in) {
|
|
if (in == null) return;
|
|
byte[] buf = new byte[512];
|
|
try (InputStream stream = in) {
|
|
while (stream.read(buf) != -1) { /* discard */ }
|
|
} catch (Throwable ignore) {}
|
|
}
|
|
|
|
static String classify(Throwable t) {
|
|
if (t instanceof SSLHandshakeException || t instanceof SSLPeerUnverifiedException) {
|
|
return "TLS/cert issue";
|
|
}
|
|
if (t instanceof CertificateException) {
|
|
return "TLS/cert issue";
|
|
}
|
|
if (t instanceof SSLException) {
|
|
String m = t.getMessage();
|
|
if (m != null && m.toLowerCase(Locale.US).contains("cert")) {
|
|
return "TLS/cert issue";
|
|
}
|
|
return "TLS: " + t.getClass().getSimpleName();
|
|
}
|
|
if (t instanceof SocketTimeoutException) {
|
|
return "timeout";
|
|
}
|
|
if (t instanceof UnknownHostException) {
|
|
return "no DNS (aismap.local)";
|
|
}
|
|
if (t instanceof ConnectException || t instanceof NoRouteToHostException) {
|
|
return "no route / refused";
|
|
}
|
|
Throwable c = t.getCause();
|
|
if (c != null && c != t) {
|
|
return classify(c);
|
|
}
|
|
String m = t.getMessage();
|
|
if (m != null && !m.isEmpty()) {
|
|
String shortM = m.length() > 48 ? m.substring(0, 45) + "…" : m;
|
|
return t.getClass().getSimpleName() + ": " + shortM;
|
|
}
|
|
return t.getClass().getSimpleName();
|
|
}
|
|
}
|