Files
AndroidAisMap/app/src/main/java/com/grigowashere/aismap/utils/AismapLocalHttpsProbe.java
T
2026-05-21 12:38:18 +03:00

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();
}
}