Clean catvod code

release
FongMi 4 weeks ago
parent a556ad8e06
commit 8c50808dc3
  1. 15
      catvod/src/main/java/com/github/catvod/bean/Doh.java
  2. 4
      catvod/src/main/java/com/github/catvod/net/OkAuthenticator.java
  3. 2
      catvod/src/main/java/com/github/catvod/net/OkDns.java
  4. 4
      catvod/src/main/java/com/github/catvod/net/OkHttp.java
  5. 6
      catvod/src/main/java/com/github/catvod/net/interceptor/AuthInterceptor.java
  6. 83
      catvod/src/main/java/com/github/catvod/utils/Auth.java
  7. 4
      catvod/src/main/java/com/github/catvod/utils/Json.java
  8. 27
      catvod/src/main/java/com/github/catvod/utils/Prefers.java
  9. 47
      catvod/src/main/java/com/github/catvod/utils/Util.java

@ -41,9 +41,13 @@ public class Doh {
}
public static List<Doh> arrayFrom(JsonElement element) {
Type listType = new TypeToken<List<Doh>>() {}.getType();
List<Doh> items = new Gson().fromJson(element, listType);
return items == null ? new ArrayList<>() : items;
try {
Type listType = new TypeToken<List<Doh>>() {}.getType();
List<Doh> items = new Gson().fromJson(element, listType);
return items == null ? new ArrayList<>() : items;
} catch (Exception e) {
return new ArrayList<>();
}
}
public Doh name(String name) {
@ -85,6 +89,11 @@ public class Doh {
return getUrl().equals(it.getUrl());
}
@Override
public int hashCode() {
return getUrl().hashCode();
}
@NonNull
@Override
public String toString() {

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.github.catvod.bean.Proxy;
import com.github.catvod.utils.Util;
import com.github.catvod.utils.Auth;
import com.google.common.net.HttpHeaders;
import java.net.InetSocketAddress;
@ -49,7 +49,7 @@ public class OkAuthenticator implements Authenticator {
if (url.contains(proxyHost)) {
String userInfo = Uri.parse(url).getUserInfo();
if (userInfo != null) {
return response.request().newBuilder().header(HttpHeaders.PROXY_AUTHORIZATION, Util.basic(userInfo)).build();
return response.request().newBuilder().header(HttpHeaders.PROXY_AUTHORIZATION, Auth.basic(userInfo)).build();
}
}
}

@ -7,14 +7,12 @@ import com.github.catvod.utils.Util;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import kotlin._Assertions;
import okhttp3.Dns;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;

@ -89,12 +89,12 @@ public class OkHttp {
return get().selector = new OkProxySelector();
}
public static OkHttpClient client() {
public static synchronized OkHttpClient client() {
if (get().client != null) return get().client;
return get().client = getBuilder().build();
}
public static OkHttpClient player() {
public static synchronized OkHttpClient player() {
if (get().player != null) return get().player;
return get().player = getBuilder().build();
}

@ -2,7 +2,7 @@ package com.github.catvod.net.interceptor;
import androidx.annotation.NonNull;
import com.github.catvod.utils.Util;
import com.github.catvod.utils.Auth;
import com.google.common.net.HttpHeaders;
import java.io.IOException;
@ -37,7 +37,7 @@ public class AuthInterceptor implements Interceptor {
if (user == null) return response;
response.close();
String header = response.header(HttpHeaders.WWW_AUTHENTICATE);
String auth = digest(header) ? Util.digest(user, header, request) : Util.basic(user);
String auth = digest(header) ? Auth.digest(user, header, request) : Auth.basic(user);
return chain.proceed(request.newBuilder().header(HttpHeaders.AUTHORIZATION, auth).build());
}
@ -49,6 +49,6 @@ public class AuthInterceptor implements Interceptor {
URI uri = request.url().uri();
if (uri.getUserInfo() == null) return request;
userMap.put(request.url().host(), uri.getUserInfo());
return request.newBuilder().header(HttpHeaders.AUTHORIZATION, Util.basic(uri.getUserInfo())).build();
return request.newBuilder().header(HttpHeaders.AUTHORIZATION, Auth.basic(uri.getUserInfo())).build();
}
}

@ -0,0 +1,83 @@
package com.github.catvod.utils;
import android.util.Base64;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import okhttp3.Request;
public class Auth {
private static final Pattern DIGEST = Pattern.compile("(\\w+)=\\s*([^,]+)\\s*");
public static String basic(String userInfo) {
if (!userInfo.contains(":")) userInfo += ":";
return "Basic " + Base64.encodeToString(userInfo.getBytes(), Base64.NO_WRAP);
}
public static String digest(String userInfo, String header, Request request) {
Map<String, String> params = parseDigest(header.substring(7));
String[] credentials = userInfo.split(":", 2);
String username = credentials[0];
String password = credentials.length > 1 ? credentials[1] : "";
String realm = params.getOrDefault("realm", "");
String nonce = params.getOrDefault("nonce", "");
String opaque = params.get("opaque");
String uri = digestUri(request);
String qop = selectQop(params.get("qop"));
String nc = "00000001";
String cnonce = newCnonce();
String ha1 = Util.md5(username + ":" + realm + ":" + password);
String ha2 = Util.md5(request.method() + ":" + uri);
String response = digestResponse(ha1, ha2, nonce, nc, cnonce, qop);
return buildHeader(username, realm, nonce, uri, nc, cnonce, qop, response, opaque);
}
private static String digestUri(Request request) {
String query = request.url().encodedQuery();
String path = request.url().encodedPath();
return query != null ? path + "?" + query : path;
}
private static String digestResponse(String ha1, String ha2, String nonce, String nc, String cnonce, String qop) {
return qop.isEmpty() ? Util.md5(ha1 + ":" + nonce + ":" + ha2) : Util.md5(ha1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + ha2);
}
private static String buildHeader(String username, String realm, String nonce, String uri, String nc, String cnonce, String qop, String response, String opaque) {
List<String> fields = new ArrayList<>();
fields.add("username=\"" + username + "\"");
fields.add("realm=\"" + realm + "\"");
fields.add("nonce=\"" + nonce + "\"");
fields.add("uri=\"" + uri + "\"");
boolean hasQop = !qop.isEmpty();
if (hasQop) fields.add("cnonce=\"" + cnonce + "\"");
if (hasQop) fields.add("nc=" + nc);
if (hasQop) fields.add("qop=" + qop);
fields.add("response=\"" + response + "\"");
if (opaque != null) fields.add("opaque=\"" + opaque + "\"");
return "Digest " + String.join(", ", fields);
}
private static String newCnonce() {
return UUID.randomUUID().toString().replace("-", "");
}
private static String selectQop(String qop) {
if (qop == null || qop.isEmpty()) return "";
for (String option : qop.split(",")) if ("auth".equalsIgnoreCase(option.trim())) return "auth";
return "";
}
private static Map<String, String> parseDigest(String header) {
Map<String, String> params = new HashMap<>();
Matcher matcher = DIGEST.matcher(header.trim());
while (matcher.find()) params.put(matcher.group(1), matcher.group(2).replaceAll("\"", "").trim());
return params;
}
}

@ -20,7 +20,7 @@ public class Json {
try {
return JsonParser.parseString(json);
} catch (Throwable e) {
return new JsonParser().parse(json);
return new JsonObject();
}
}
@ -73,7 +73,7 @@ public class Json {
List<JsonElement> result = new ArrayList<>();
if (!obj.has(key)) return result;
if (obj.get(key).isJsonObject()) result.add(obj.get(key).getAsJsonObject());
for (JsonElement opt : obj.getAsJsonArray(key)) result.add(opt.getAsJsonObject());
else for (JsonElement opt : obj.getAsJsonArray(key)) result.add(opt.getAsJsonObject());
return result;
}

@ -5,7 +5,6 @@ import android.content.SharedPreferences;
import androidx.preference.PreferenceManager;
import com.github.catvod.Init;
import com.google.gson.internal.LazilyParsedNumber;
public class Prefers {
@ -63,19 +62,19 @@ public class Prefers {
public static void put(String key, Object obj) {
if (obj == null) return;
if (obj instanceof String) {
getPrefers().edit().putString(key, (String) obj).apply();
} else if (obj instanceof Boolean) {
getPrefers().edit().putBoolean(key, (Boolean) obj).apply();
} else if (obj instanceof Float) {
getPrefers().edit().putFloat(key, (Float) obj).apply();
} else if (obj instanceof Integer) {
getPrefers().edit().putInt(key, (Integer) obj).apply();
} else if (obj instanceof Long) {
getPrefers().edit().putLong(key, (Long) obj).apply();
} else if (obj instanceof LazilyParsedNumber number) {
if (number.toString().contains(".")) put(key, number.floatValue());
else put(key, number.intValue());
if (obj instanceof String val) {
getPrefers().edit().putString(key, val).apply();
} else if (obj instanceof Boolean val) {
getPrefers().edit().putBoolean(key, val).apply();
} else if (obj instanceof Float val) {
getPrefers().edit().putFloat(key, val).apply();
} else if (obj instanceof Integer val) {
getPrefers().edit().putInt(key, val).apply();
} else if (obj instanceof Long val) {
getPrefers().edit().putLong(key, val).apply();
} else if (obj instanceof Number val) {
if (val.toString().contains(".")) put(key, val.floatValue());
else put(key, val.intValue());
}
}

@ -17,22 +17,15 @@ import java.net.SocketException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import okhttp3.OkHttp;
import okhttp3.Request;
public class Util {
public static final String OKHTTP = "okhttp/" + OkHttp.VERSION;
public static final String CHROME = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36";
public static final int URL_SAFE = Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP;
public static final Pattern DIGEST = Pattern.compile("(\\w+)=\\s*([^,]+)\\s*");
public static String base64(String s) {
return base64(s.getBytes());
@ -58,11 +51,6 @@ public class Util {
return Base64.decode(s, flags);
}
public static String basic(String userInfo) {
if (!userInfo.contains(":")) userInfo += ":";
return "Basic " + base64(userInfo, Base64.NO_WRAP);
}
public static byte[] hex2byte(String s) {
byte[] bytes = new byte[s.length() / 2];
for (int i = 0; i < bytes.length; i++) bytes[i] = Integer.valueOf(s.substring(i * 2, i * 2 + 2), 16).byteValue();
@ -153,39 +141,4 @@ public class Util {
}
return "";
}
public static String digest(String userInfo, String header, Request request) {
Map<String, String> params = parse(header.substring(7));
String[] parts = userInfo.split(":", 2);
String nc = "00000001";
String username = parts[0];
String password = parts.length > 1 ? parts[1] : "";
String qop = params.get("qop");
String realm = params.get("realm");
String nonce = params.get("nonce");
String opaque = params.get("opaque");
String uri = request.url().encodedPath();
String hash1 = Util.md5(username + ":" + realm + ":" + password);
String hash2 = Util.md5(request.method() + ":" + uri);
String cnonce = UUID.randomUUID().toString().replace("-", "");
String response = Util.md5(hash1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + hash2);
StringBuilder sb = new StringBuilder("Digest ");
sb.append("username=\"").append(username).append("\", ");
sb.append("realm=\"").append(realm).append("\", ");
sb.append("nonce=\"").append(nonce).append("\", ");
sb.append("uri=\"").append(uri).append("\", ");
sb.append("cnonce=\"").append(cnonce).append("\", ");
sb.append("nc=").append(nc).append(", ");
sb.append("qop=\"").append(qop).append("\", ");
sb.append("response=\"").append(response).append("\"");
if (opaque != null) sb.append(", opaque=\"").append(opaque).append("\"");
return sb.toString();
}
private static Map<String, String> parse(String header) {
Map<String, String> params = new HashMap<>();
Matcher matcher = DIGEST.matcher(header.trim());
while (matcher.find()) params.put(matcher.group(1), matcher.group(2).replaceAll("\"", "").trim());
return params;
}
}

Loading…
Cancel
Save