diff --git a/.github/apk-badge.png b/.github/apk-badge.png new file mode 100644 index 00000000..5d112c2f Binary files /dev/null and b/.github/apk-badge.png differ diff --git a/.github/google-play-badge.png b/.github/google-play-badge.png new file mode 100644 index 00000000..7da103b5 Binary files /dev/null and b/.github/google-play-badge.png differ diff --git a/.github/readme-banner.png b/.github/readme-banner.png new file mode 100644 index 00000000..03e78742 Binary files /dev/null and b/.github/readme-banner.png differ diff --git a/.github/utils/.gitignore b/.github/utils/.gitignore new file mode 100644 index 00000000..d50a09fc --- /dev/null +++ b/.github/utils/.gitignore @@ -0,0 +1,2 @@ +.env +__pycache__/ diff --git a/.github/utils/_get_password.py b/.github/utils/_get_password.py new file mode 100644 index 00000000..33071b6c --- /dev/null +++ b/.github/utils/_get_password.py @@ -0,0 +1,57 @@ +import base64 +import secrets +from hashlib import sha256 +from typing import Tuple + +import mysql.connector as mysql +from Crypto.Cipher import AES + + +def get_password( + version_name: str, + version_code: int, + db_host: str, + db_user: str, + db_pass: str, + db_name: str, +) -> Tuple[str, bytes]: + db = mysql.connect( + host=db_host, + user=db_user, + password=db_pass, + database=db_name, + auth_plugin="mysql_native_password", + ) + + print(f"Generating passwords for version {version_name} ({version_code})") + + password = base64.b64encode(secrets.token_bytes(16)).decode() + iv = secrets.token_bytes(16) + + key = f"{version_name}.{password}.{version_code}" + key = sha256(key.encode()).digest() + data = "ThisIsOurHardWorkPleaseDoNotCopyOrSteal(c)2019.KubaSz" + data = sha256(data.encode()).digest() + data = data + (chr(16) * 16).encode() + + aes = AES.new(key=key, mode=AES.MODE_CBC, iv=iv) + + app_password = base64.b64encode(aes.encrypt(data)).decode() + + c = db.cursor() + c.execute( + "INSERT IGNORE INTO _appPasswords (versionCode, appPassword, password, iv) VALUES (%s, %s, %s, %s);", + (version_code, app_password, password, iv), + ) + db.commit() + + c = db.cursor() + c.execute( + "SELECT password, iv FROM _appPasswords WHERE versionCode = %s;", + (version_code,), + ) + row = c.fetchone() + + db.close() + + return (row[0], row[1]) diff --git a/.github/utils/_utils.py b/.github/utils/_utils.py new file mode 100644 index 00000000..09b59f4a --- /dev/null +++ b/.github/utils/_utils.py @@ -0,0 +1,142 @@ +import re +import subprocess +import sys +from datetime import datetime +from typing import Tuple + +VERSION_NAME_REGEX = r'versionName: "(.+?)"' +VERSION_CODE_REGEX = r"versionCode: ([0-9]+)" +VERSION_NAME_FORMAT = 'versionName: "{}"' +VERSION_CODE_FORMAT = "versionCode: {}" + + +def get_project_dir() -> str: + project_dir = sys.argv[1] + if project_dir[-1:] == "/" or project_dir[-1:] == "\\": + project_dir = project_dir[:-1] + return project_dir + + +def read_gradle_version(project_dir: str) -> Tuple[int, str]: + GRADLE_PATH = f"{project_dir}/build.gradle" + + with open(GRADLE_PATH, "r") as f: + gradle = f.read() + + version_name = re.search(VERSION_NAME_REGEX, gradle).group(1) + version_code = int(re.search(VERSION_CODE_REGEX, gradle).group(1)) + + return (version_code, version_name) + + +def write_gradle_version(project_dir: str, version_code: int, version_name: str): + GRADLE_PATH = f"{project_dir}/build.gradle" + + with open(GRADLE_PATH, "r") as f: + gradle = f.read() + + gradle = re.sub( + VERSION_NAME_REGEX, VERSION_NAME_FORMAT.format(version_name), gradle + ) + gradle = re.sub( + VERSION_CODE_REGEX, VERSION_CODE_FORMAT.format(version_code), gradle + ) + + with open(GRADLE_PATH, "w") as f: + f.write(gradle) + + +def build_version_code(version_name: str) -> int: + version = version_name.split("+")[0].split("-") + version_base = version[0] + version_suffix = version[1] if len(version) == 2 else "" + + base_parts = version_base.split(".") + major = int(base_parts[0]) or 0 + minor = int(base_parts[1]) if len(base_parts) > 1 else 0 + patch = int(base_parts[2]) if len(base_parts) > 2 else 0 + + beta = 9 + rc = 9 + if "dev" in version_suffix: + beta = 0 + rc = 0 + elif "beta." in version_suffix: + beta = int(version_suffix.split(".")[1]) + rc = 0 + elif "rc." in version_suffix: + beta = 0 + rc = int(version_suffix.split(".")[1]) + + version_code = beta + rc * 10 + patch * 100 + minor * 10000 + major * 1000000 + return version_code + + +def get_changelog(project_dir: str, format: str) -> Tuple[str, str]: + with open( + f"{project_dir}/app/src/main/assets/pl-changelog.html", "r", encoding="utf-8" + ) as f: + changelog = f.read() + + title = re.search(r"
Description : AbsResponseHandler. - * Callback lifecycle as follow: - * onStart() - * ------------------------------------------------------- - * | - * | - * is canceled --- Y --- onCancel() - * | - * N - * | - * onFinish() - * | - * | - * is successful --- N --- onFailure() ------------------ - * | | - * Y | - * | | - * backgroundParser() --is download-- onProgress() | - * | | | - * | | | - * onSuccess() onSuccess() | - * | | | - * | | | - * --------------------------------------------------------- - * onFinally() - *
- *Author : wangchao.
- *Date : 15/8/17.
- *Time : 下午5:56.
- */ -public abstract class AbsCallbackHandlerDescription : Accept.
- *Author : wangchao.
- *Date : 16/4/25.
- *Time : 上午11:06.
- */ -public interface Accept { - String EMPTY = ""; - String ACCEPT_JSON = "application/json;charset=utf-8"; - String ACCEPT_TEXT = "text/html;charset=utf-8"; - String ACCEPT_DATA = "application/octet-stream"; - String ACCEPT_IMAGE = "image/png,image/jpeg,image/*"; - String ACCEPT_FILE = "application/octet-stream"; - - @Retention(RetentionPolicy.SOURCE) - @StringDef({ - Accept.EMPTY, - Accept.ACCEPT_JSON, - Accept.ACCEPT_TEXT, - Accept.ACCEPT_DATA, - Accept.ACCEPT_IMAGE, - Accept.ACCEPT_FILE - }) - public @interface $Accept { - } -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/Android5SSL.java b/mhttp/src/main/java/im/wangchao/mhttp/Android5SSL.java deleted file mode 100644 index 4ddbc6de..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/Android5SSL.java +++ /dev/null @@ -1,149 +0,0 @@ -package im.wangchao.mhttp; - -import android.os.Build; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; -import java.security.GeneralSecurityException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.X509TrustManager; - -/** - *Description : Android5SSL.
- *Author : wangchao.
- *Date : 2018/3/19.
- *Time : 上午11:09.
- */ -/*package*/ class Android5SSL extends SSLSocketFactory { - private SSLSocketFactory defaultFactory; - // Android 5.0+ (API level21) provides reasonable default settings - // but it still allows SSLv3 - // https://developer.android.com/about/versions/android-5.0-changes.html#ssl - static String protocols[] = null, cipherSuites[] = null; - - static { - try { - SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(); - if (socket != null) { - /* set reasonable protocol versions */ - // - enable all supported protocols (enables TLSv1.1 and TLSv1.2 on Android <5.0) - // - remove all SSL versions (especially SSLv3) because they're insecure now - ListDescription : BindApi.
- *Author : wangchao.
- *Date : 15/10/19.
- *Time : 上午8:23.
- */ -final class BindApi { - /** HttpProcessor.SUFFIX */ - private static final String SUFFIX = "_HttpBinder"; - - @SuppressWarnings("unchecked") public staticDescription : OkCallback.
- *Author : wangchao.
- *Date : 16/6/3.
- *Time : 上午10:16.
- */ -public interface Callback extends okhttp3.Callback { - - Callback EMPTY = new Callback() { - @Override public void initialize(Request request) {} - - @Override public String accept() { - return Accept.EMPTY; - } - - @Override public void onFailure(Call call, IOException e) {} - - @Override public void onResponse(Call call, Response response) throws IOException { - response.close(); - } - }; - - /** - * Initialize the callback. - */ - void initialize(Request request); - - /** - * Request accept. - */ - String accept(); - -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/Converter.java b/mhttp/src/main/java/im/wangchao/mhttp/Converter.java deleted file mode 100644 index c75bf3f0..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/Converter.java +++ /dev/null @@ -1,12 +0,0 @@ -package im.wangchao.mhttp; - -/** - *Description : Converter.
- *Author : wangchao.
- *Date : 2018/3/20.
- *Time : 下午10:26.
- */ -public interface ConverterDescription : HTTPS.
- *Author : wangchao.
- *Date : 16/9/2.
- *Time : 下午3:58.
- */ -/*package*/ final class HTTPS { - - // 信任所有证书的 TrustManager - private static X509TrustManager TrustAllCertificate = new X509TrustManager() { - @Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { - } - - @Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { - } - - @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return new java.security.cert.X509Certificate[]{}; - } - }; - - /** - * Trust all certificate for debug - */ - /*package*/ static void trustAllCertificate(OkHttpClient.Builder builder) { - builder.sslSocketFactory(new Android5SSL(TrustAllCertificate), TrustAllCertificate); - } - - /** - * Set Certificate - */ - /*package*/ static void setCertificates(OkHttpClient.Builder builder, - InputStream... certificates) throws Exception { - setCertificates(builder, null, certificates, null, null); - } - - /** - * Set Certificate - */ - /*package*/ static void setCertificates(OkHttpClient.Builder builder, - X509TrustManager trustManager, - InputStream bksFile, - String password) throws Exception { - setCertificates(builder, trustManager, null, bksFile, password); - } - - /** - * Set Certificate - */ - /*package*/ static void setCertificates(OkHttpClient.Builder builder, - InputStream[] certificates, - InputStream bksFile, - String password) throws Exception { - setCertificates(builder, null, certificates, bksFile, password); - } - - /** - * Set Certificate - */ - /*package*/ static void setCertificates(OkHttpClient.Builder builder, - X509TrustManager trustManager, - InputStream[] certificates, - InputStream bksFile, - String password) throws Exception { - TrustManager[] trustManagers = prepareTrustManager(certificates); - KeyManager[] keyManagers = prepareKeyManager(bksFile, password); - - X509TrustManager manager; - if (trustManager != null) { - manager = trustManager; - } else if (trustManagers != null) { - manager = chooseTrustManager(trustManagers); - } else { - manager = TrustAllCertificate; - } - - // 创建TLS类型的SSLContext对象, that uses our finalTrustManager - SSLContext sslContext = SSLContext.getInstance("TLS"); - // 用上面得到的trustManagers初始化SSLContext,这样sslContext就会信任keyStore中的证书 - // 第一个参数是授权的密钥管理器,用来授权验证,比如授权自签名的证书验证。第二个是被授权的证书管理器,用来验证服务器端的证书 - sslContext.init(keyManagers, new TrustManager[]{manager}, new SecureRandom()); - builder.sslSocketFactory(sslContext.getSocketFactory(), manager); - } - - /*package*/ static TrustManager[] prepareTrustManager(InputStream... certificates) throws Exception { - if (certificates == null || certificates.length <= 0) return null; - - CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); - // 创建一个默认类型的KeyStore,存储我们信任的证书 - KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); - keyStore.load(null); - int index = 0; - for (InputStream certificate : certificates) { - String certificateAlias = Integer.toString(index++); - keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate)); - Util.closeQuietly(certificate); - } - - TrustManagerFactory trustManagerFactory = TrustManagerFactory. - getInstance(TrustManagerFactory.getDefaultAlgorithm()); - //用我们之前的keyStore实例初始化TrustManagerFactory,使TrustManagerFactory信任keyStore中的证书 - trustManagerFactory.init(keyStore); - return trustManagerFactory.getTrustManagers(); - } - - /*package*/ static KeyManager[] prepareKeyManager(InputStream bksFile, String password) throws Exception{ - if (bksFile == null || password == null) return null; - - KeyStore clientKeyStore = KeyStore.getInstance("BKS"); - clientKeyStore.load(bksFile, password.toCharArray()); - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - keyManagerFactory.init(clientKeyStore, password.toCharArray()); - return keyManagerFactory.getKeyManagers(); - } - - /*package*/ static X509TrustManager chooseTrustManager(TrustManager[] trustManagers) { - for (TrustManager trustManager : trustManagers) { - if (trustManager instanceof X509TrustManager) { - return (X509TrustManager) trustManager; - } - } - return null; - } - - /* X509TrustManager */ - /*package*/ static class MyTrustManager implements X509TrustManager { - private X509TrustManager defaultTrustManager; - private X509TrustManager localTrustManager; - - /*package*/ MyTrustManager(X509TrustManager localTrustManager) throws NoSuchAlgorithmException, KeyStoreException { - TrustManagerFactory var4 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - var4.init((KeyStore) null); - defaultTrustManager = chooseTrustManager(var4.getTrustManagers()); - this.localTrustManager = localTrustManager; - } - - @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { -// try { -// defaultTrustManager.checkClientTrusted(chain, authType); -// } catch (CertificateException e) { -// localTrustManager.checkClientTrusted(chain, authType); -// } - } - - @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - try { - defaultTrustManager.checkServerTrusted(chain, authType); - } catch (CertificateException e) { - localTrustManager.checkServerTrusted(chain, authType); - } - } - - - @Override public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } - } -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/MHttp.java b/mhttp/src/main/java/im/wangchao/mhttp/MHttp.java deleted file mode 100644 index af46229b..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/MHttp.java +++ /dev/null @@ -1,252 +0,0 @@ -package im.wangchao.mhttp; - -import android.content.Context; -import android.os.Build; -import android.os.StatFs; -import androidx.annotation.NonNull; - -import java.io.File; -import java.io.InputStream; -import java.net.URL; -import java.util.concurrent.TimeUnit; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.X509TrustManager; - -import im.wangchao.mhttp.internal.interceptor.HttpLoggingInterceptor; -import im.wangchao.mhttp.internal.interceptor.MBridgeInterceptor; -import im.wangchao.mhttp.internal.log.LoggerImpl; -import okhttp3.Cache; -import okhttp3.Call; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; - -/** - *Description : MHttp.
- *Author : wangchao.
- *Date : 16/6/2.
- *Time : 上午8:40.
- */ -public final class MHttp { - private static volatile MHttp instance; - - private OkHttpClient.Builder mOkBuilder; - private OkHttpClient mInnerClient; - private URLInterceptor mURLInterceptor; - private final HttpLoggingInterceptor mLoggingInterceptor = new HttpLoggingInterceptor(LoggerImpl.instance.get()); - - public static MHttp instance(){ - if (instance == null) { - synchronized (MHttp.class){ - instance = new MHttp(); - } - } - return instance; - } - - /** - * Create annotation api - */ - public staticDescription : Method.
- *Author : wangchao.
- *Date : 16/3/8.
- *Time : 下午4:08.
- */ -public interface Method { - String POST = "POST"; - String GET = "GET"; - String HEAD = "HEAD"; - String DELETE = "DELETE"; - String PUT = "PUT"; - String PATCH = "PATCH"; - - @Retention(RetentionPolicy.SOURCE) - @StringDef({Method.POST, Method.GET, Method.HEAD, Method.DELETE, Method.PUT, Method.PATCH}) - @interface MethodType{} -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/Request.java b/mhttp/src/main/java/im/wangchao/mhttp/Request.java deleted file mode 100644 index 426b0eab..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/Request.java +++ /dev/null @@ -1,503 +0,0 @@ -package im.wangchao.mhttp; - -import androidx.annotation.NonNull; -import android.util.Pair; -import android.util.Log; - -import com.google.gson.JsonObject; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executor; - -import im.wangchao.mhttp.body.JSONBody; -import im.wangchao.mhttp.body.MediaTypeUtils; -import okhttp3.CacheControl; -import okhttp3.Call; -import okhttp3.Headers; -import okhttp3.HttpUrl; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.RequestBody; -import okio.Buffer; -import okio.BufferedSink; - -/** - *Description : MRequest.
- *Author : wangchao.
- *Date : 16/6/2.
- *Time : 下午4:16.
- */ -public final class Request { - public static Builder builder(){ - return new Builder(); - } - - private final okhttp3.Request mRawRequest; - private final RequestParams mRequestParams; - private final Callback mCallback; - private final MediaType mMediaType; - private final Executor mExecutor; - private final ThreadMode mThreadMode; - private final JsonObject mJsonBody; - private final okhttp3.OkHttpClient mOkHttpClient; - private final ListDescription : RequestParams.
- *Author : wangchao.
- *Date : 15/8/17.
- *Time : 下午2:16.
- */ -public class RequestParams{ - final private static String UTF_8_STR = "utf-8"; - final private static Charset UTF_8 = Charset.forName(UTF_8_STR); - - //params - final private ListDescription : MResponse.
- *Author : wangchao.
- *Date : 16/6/3.
- *Time : 下午3:03.
- */ -public final class Response { - public final static int IO_EXCEPTION_CODE = 1000; - - public static Response error(Request request, int code, String message){ - if (message == null){ - message = "unknown exception."; - } - return new Response(request, new okhttp3.Response.Builder() - .request(request.raw()) - .protocol(Protocol.HTTP_1_1) - .code(code) - .message(message) - .build()); - } - - public static Response newResponse(Request request, okhttp3.Response raw){ - return new Response(request, raw); - } - - private final Request request; - private final okhttp3.Response rawResponse; - public String parserErrorBody = null; - - private Response(Request request, okhttp3.Response rawResponse){ - this.request = request; - this.rawResponse = rawResponse; - } - - public Request request() { - return request; - } - - public okhttp3.Response raw() { - return rawResponse; - } - - /** HTTP status code. */ - public int code() { - return rawResponse.code(); - } - - /** HTTP status message or null if unknown. */ - public String message() { - return rawResponse.message(); - } - - /** HTTP headers. */ - public Headers headers() { - return rawResponse.headers(); - } - -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/ThreadMode.java b/mhttp/src/main/java/im/wangchao/mhttp/ThreadMode.java deleted file mode 100644 index 49a23195..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/ThreadMode.java +++ /dev/null @@ -1,43 +0,0 @@ -package im.wangchao.mhttp; - -import java.util.concurrent.Executor; - -import im.wangchao.mhttp.executor.BACKGROUND; -import im.wangchao.mhttp.executor.MAIN; -import im.wangchao.mhttp.executor.SENDING; - -/** - *Description : ThreadMode.
- *Author : wangchao.
- *Date : 16/8/3.
- *Time : 下午12:44.
- */ -public enum ThreadMode { - /** - * Callback will be called in the same thread, which is sending the request. - */ - SENDING{ - @Override public Executor executor() { - return new SENDING(); - } - }, - /** - * Callback will be called in Android's main thread (UI thread). - */ - MAIN{ - @Override public Executor executor() { - return new MAIN(); - } - }, - - /** - * Callback will be called in a background thread. That is, work on the request thread(okhttp thread). - */ - BACKGROUND{ - @Override public Executor executor() { - return new BACKGROUND(); - } - }; - - public abstract Executor executor(); -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/URLInterceptor.java b/mhttp/src/main/java/im/wangchao/mhttp/URLInterceptor.java deleted file mode 100644 index 739a24f2..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/URLInterceptor.java +++ /dev/null @@ -1,20 +0,0 @@ -package im.wangchao.mhttp; - -import java.net.URL; - -import okhttp3.HttpUrl; - -/** - *Description : URLInterceptor.
- *Author : wangchao.
- *Date : 2018/1/15.
- *Time : 上午11:01.
- */ -public interface URLInterceptor { - - String interceptor(String origin); - - HttpUrl interceptor(HttpUrl origin); - - URL interceptor(URL origin); -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/body/FileBody.java b/mhttp/src/main/java/im/wangchao/mhttp/body/FileBody.java deleted file mode 100644 index 051dce2c..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/body/FileBody.java +++ /dev/null @@ -1,53 +0,0 @@ -package im.wangchao.mhttp.body; - -import androidx.annotation.NonNull; -import android.text.TextUtils; - -import java.io.File; -import java.io.IOException; - -import okhttp3.MediaType; -import okhttp3.RequestBody; -import okhttp3.internal.Util; -import okio.BufferedSink; -import okio.Okio; -import okio.Source; - -/** - *Description : FileBody.
- *Author : wangchao.
- *Date : 16/3/8.
- *Time : 下午6:10.
- */ -public final class FileBody extends RequestBody{ - private final static MediaType CONTENT_TYPE = MediaTypeUtils.OCTET; - private final MediaType contentType; - private final File file; - - public FileBody(File file){ - this(file, null); - } - - public FileBody(File file, String contentType){ - this.file = file; - this.contentType = TextUtils.isEmpty(contentType) ? CONTENT_TYPE : MediaType.parse(contentType); - } - - @Override public MediaType contentType() { - return contentType; - } - - @Override public long contentLength() throws IOException { - return file.length(); - } - - @Override public void writeTo(@NonNull BufferedSink sink) throws IOException { - Source source = null; - try { - source = Okio.source(file); - sink.writeAll(source); - } finally { - Util.closeQuietly(source); - } - } -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/body/JSONBody.java b/mhttp/src/main/java/im/wangchao/mhttp/body/JSONBody.java deleted file mode 100644 index 8449625c..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/body/JSONBody.java +++ /dev/null @@ -1,50 +0,0 @@ -package im.wangchao.mhttp.body; - -import androidx.annotation.NonNull; -import android.text.TextUtils; - -import java.io.IOException; - -import okhttp3.MediaType; -import okhttp3.RequestBody; -import okio.BufferedSink; - -/** - *Description : JSONBody.
- *Author : wangchao.
- *Date : 16/3/8.
- *Time : 下午4:31.
- */ -public final class JSONBody extends RequestBody{ - private final static MediaType CONTENT_TYPE = MediaTypeUtils.JSON; - private final MediaType contentType; - private final byte[] bytes; - - public JSONBody(String content){ - this(content, null); - } - - public JSONBody(String content, String charset){ - if (TextUtils.isEmpty(content)){ - throw new NullPointerException("content == null"); - } - if (TextUtils.isEmpty(charset)){ - charset = "utf-8"; - } - this.contentType = TextUtils.isEmpty(charset) ? CONTENT_TYPE : MediaType.parse("application/json; charset=" + charset); - bytes = content.getBytes(contentType.charset()); - } - - @Override public MediaType contentType() { - return contentType; - } - - @Override public long contentLength() throws IOException { - return bytes.length; - } - - @Override public void writeTo(@NonNull BufferedSink sink) throws IOException { - sink.write(bytes, 0, bytes.length); - } - -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/body/MediaTypeUtils.java b/mhttp/src/main/java/im/wangchao/mhttp/body/MediaTypeUtils.java deleted file mode 100644 index ff665962..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/body/MediaTypeUtils.java +++ /dev/null @@ -1,53 +0,0 @@ -package im.wangchao.mhttp.body; - -import androidx.annotation.NonNull; -import android.text.TextUtils; - -import okhttp3.MediaType; - -/** - *Description : MediaType.
- *Author : wangchao.
- *Date : 2017/6/23.
- *Time : 下午2:15.
- */ -public final class MediaTypeUtils { - /** MediaType String */ - public static final String APPLICATION_OCTET_STREAM = "application/octet-stream"; - public static final String APPLICATION_JSON = "application/json; charset=utf-8"; - public static final String APPLICATION_FORM = "application/x-www-form-urlencoded"; - public static final String APPLICATION_XML = "application/xml"; - - /** MediaType */ - public static final MediaType JSON = MediaType.parse(APPLICATION_JSON); - public static final MediaType OCTET = MediaType.parse(APPLICATION_OCTET_STREAM); - public static final MediaType FORM = MediaType.parse(APPLICATION_FORM); - public static final MediaType XML = MediaType.parse(APPLICATION_XML); - public static final MediaType DEFAULT = FORM; - - /** - * 判断两个 MediaType 是否相等,只判断 type 和 subType。 - */ - public static boolean equals(@NonNull MediaType first, @NonNull MediaType second){ - String first_type_subType = first.type().concat(first.subtype()); - String second_type_subType = second.type().concat(second.subtype()); - - return TextUtils.equals(first_type_subType, second_type_subType); - } - - public static boolean isJSON(@NonNull MediaType mediaType){ - return equals(mediaType, JSON); - } - - public static boolean isOCTET(@NonNull MediaType mediaType){ - return equals(mediaType, OCTET); - } - - public static boolean isFORM(@NonNull MediaType mediaType){ - return equals(mediaType, FORM); - } - - public static boolean isXML(@NonNull MediaType mediaType){ - return equals(mediaType, XML); - } -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/body/OctetStreamBody.java b/mhttp/src/main/java/im/wangchao/mhttp/body/OctetStreamBody.java deleted file mode 100644 index faf1c113..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/body/OctetStreamBody.java +++ /dev/null @@ -1,88 +0,0 @@ -package im.wangchao.mhttp.body; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.text.TextUtils; - -import java.io.IOException; -import java.io.InputStream; - -import okhttp3.MediaType; -import okhttp3.RequestBody; -import okhttp3.internal.Util; -import okio.Buffer; -import okio.BufferedSink; -import okio.Okio; -import okio.Source; - -/** - *Description : OctetStreamBody.
- *Author : wangchao.
- *Date : 16/3/8.
- *Time : 下午4:31.
- */ -public final class OctetStreamBody extends RequestBody{ - private final static MediaType CONTENT_TYPE = MediaTypeUtils.OCTET; - private final MediaType contentType; - private final InputStream stream; - private long contentLength = -1L; - private Buffer buffer; - - public OctetStreamBody(InputStream stream){ - this(stream, null); - } - - public OctetStreamBody(InputStream stream, String contentType){ - this.stream = stream; - this.contentType = TextUtils.isEmpty(contentType) ? CONTENT_TYPE : MediaType.parse(contentType); - } - - @Override public MediaType contentType() { - return contentType; - } - - @Override public long contentLength() throws IOException { - long result = contentLength; - if (result != -1L) return result; - return contentLength = writeOrCountBytes(null, true); - } - - @Override public void writeTo(@NonNull BufferedSink sink) throws IOException { - contentLength = writeOrCountBytes(sink, false); - } - - private long writeOrCountBytes(@Nullable BufferedSink sink, boolean countBytes) throws IOException{ - long byteCount = 0L; - - if (countBytes) { - buffer = new Buffer(); - Source source = null; - try { - source = Okio.source(stream); - buffer.writeAll(source); - } finally { - Util.closeQuietly(source); - } - - byteCount = buffer.size(); - - return byteCount; - } else { - if (sink == null){ - return byteCount; - } - Source source = null; - try { - source = Okio.source(buffer == null ? stream : buffer.inputStream()); - return sink.writeAll(source); - } finally { - if (buffer != null){ - buffer.clear(); - } - Util.closeQuietly(source); - } - } - - } - -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/body/ProgressRequestBody.java b/mhttp/src/main/java/im/wangchao/mhttp/body/ProgressRequestBody.java deleted file mode 100644 index 2ea2b901..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/body/ProgressRequestBody.java +++ /dev/null @@ -1,70 +0,0 @@ -package im.wangchao.mhttp.body; - -import androidx.annotation.NonNull; - -import java.io.IOException; - -import im.wangchao.mhttp.AbsCallbackHandler; -import okhttp3.MediaType; -import okhttp3.RequestBody; -import okio.Buffer; -import okio.BufferedSink; -import okio.ForwardingSink; -import okio.Okio; -import okio.Sink; - -/** - *Description : ProgressRequestBody.
- *Author : wangchao.
- *Date : 2018/1/30.
- *Time : 下午8:25.
- */ -public class ProgressRequestBody extends RequestBody { - - private final RequestBody mRequestBody; - private final AbsCallbackHandler mCallback; - private BufferedSink mBufferedSink; - - public ProgressRequestBody(RequestBody requestBody, AbsCallbackHandler callback){ - this.mRequestBody = requestBody; - this.mCallback = callback; - } - - @Override public MediaType contentType() { - return mRequestBody.contentType(); - } - - @Override public long contentLength() throws IOException { - return mRequestBody.contentLength(); - } - - @Override public void writeTo(@NonNull BufferedSink sink) throws IOException { - if (mCallback == null){ - mRequestBody.writeTo(sink); - return; - } - if (mBufferedSink == null){ - mBufferedSink = Okio.buffer(forward(sink)); - } - - mRequestBody.writeTo(mBufferedSink); - mBufferedSink.flush(); - } - - private Sink forward(Sink sink){ - return new ForwardingSink(sink) { - private long bytesWritten = 0L; - private long contentLength = 0L; - - @Override public void write(@NonNull Buffer source, long byteCount) throws IOException { - super.write(source, byteCount); - if (contentLength == 0) { - contentLength = contentLength(); - } - bytesWritten += byteCount; - - mCallback.sendUploadProgressEvent((int) bytesWritten, (int) contentLength); - } - }; - } -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/callback/BinaryCallbackHandler.java b/mhttp/src/main/java/im/wangchao/mhttp/callback/BinaryCallbackHandler.java deleted file mode 100644 index 05b763b9..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/callback/BinaryCallbackHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -package im.wangchao.mhttp.callback; - -import im.wangchao.mhttp.AbsCallbackHandler; -import im.wangchao.mhttp.Accept; -import im.wangchao.mhttp.Response; - -/** - *Description : BinaryResponseHandler.
- *Author : wangchao.
- *Date : 15/10/18.
- *Time : 下午2:49.
- */ -public class BinaryCallbackHandler extends AbsCallbackHandlerDescription : ImageResponseHandler.
- *Author : wangchao.
- *Date : 15/10/18.
- *Time : 下午2:49.
- */ -public abstract class BitmapCallbackHandler extends AbsCallbackHandlerDescription : GSONResponseHandler.
- *Author : wangchao.
- *Date : 16/3/20.
- *Time : 上午9:06.
- */ -public abstract class CustomCallbackHandlerDescription : FileResponseHandler.
- *Author : wangchao.
- *Date : 15/10/18.
- *Time : 下午2:39.
- */ -public class FileCallbackHandler extends AbsCallbackHandlerDescription : JSONResponseHandler.
- *Author : wangchao.
- *Date : 15/10/18.
- *Time : 下午2:25.
- */ -public class JsonCallbackHandler extends AbsCallbackHandlerDescription : TextResponseHandler.
- *Author : wangchao.
- *Date : 15/10/18.
- *Time : 下午2:41.
- */ -public class TextCallbackHandler extends AbsCallbackHandlerDescription : BACKGROUND.
- *Author : wangchao.
- *Date : 16/9/2.
- *Time : 下午4:50.
- */ -public final class BACKGROUND implements Executor { - @Override public void execute(@NonNull Runnable command) { - command.run(); - } -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/executor/MAIN.java b/mhttp/src/main/java/im/wangchao/mhttp/executor/MAIN.java deleted file mode 100644 index 57785d2d..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/executor/MAIN.java +++ /dev/null @@ -1,21 +0,0 @@ -package im.wangchao.mhttp.executor; - -import android.os.Handler; -import android.os.Looper; -import androidx.annotation.NonNull; - -import java.util.concurrent.Executor; - -/** - *Description : MainThread.
- *Author : wangchao.
- *Date : 16/9/2.
- *Time : 下午4:45.
- */ -public final class MAIN implements Executor{ - private final Handler handler = new Handler(Looper.getMainLooper()); - - @Override public void execute(@NonNull Runnable command) { - handler.post(command); - } -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/executor/SENDING.java b/mhttp/src/main/java/im/wangchao/mhttp/executor/SENDING.java deleted file mode 100644 index 5960bf4e..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/executor/SENDING.java +++ /dev/null @@ -1,27 +0,0 @@ -package im.wangchao.mhttp.executor; - -import android.os.Handler; -import android.os.Looper; -import androidx.annotation.NonNull; - -import java.util.concurrent.Executor; - -/** - *Description : SENDING.
- *Author : wangchao.
- *Date : 16/9/2.
- *Time : 下午4:47.
- */ -public final class SENDING implements Executor { - private final Handler handler; - public SENDING(){ - if (Looper.myLooper() == null){ - throw new RuntimeException("The Looper of the current thread is null, please call Looper.prepare() on your thread."); - } - handler = new Handler(Looper.myLooper()); - } - - @Override public void execute(@NonNull Runnable command) { - handler.post(command); - } -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/internal/Singleton.java b/mhttp/src/main/java/im/wangchao/mhttp/internal/Singleton.java deleted file mode 100644 index 2a351d6f..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/internal/Singleton.java +++ /dev/null @@ -1,25 +0,0 @@ -package im.wangchao.mhttp.internal; - -/** - *Description : Singleton.
- *Author : wangchao.
- *Date : 16/8/25.
- *Time : 上午10:37.
- */ -public abstract class SingletonDescription : Version.
- *Author : wangchao.
- *Date : 16/8/24.
- *Time : 下午2:47.
- */ -public class Version { - private Version(){ - throw new AssertionError(); - } - - public static String userAgent() { - return moduleName().concat("1.10.1"); - } - - public static String moduleName() { - return "mhttp"; - } -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/internal/cookie/ClearableCookieJar.java b/mhttp/src/main/java/im/wangchao/mhttp/internal/cookie/ClearableCookieJar.java deleted file mode 100644 index 61c6e2ae..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/internal/cookie/ClearableCookieJar.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2016 Francisco José Montiel Navarro. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.wangchao.mhttp.internal.cookie; - -import okhttp3.CookieJar; - -public interface ClearableCookieJar extends CookieJar { - - void clear(); - void clearForDomain(String domain); -} diff --git a/mhttp/src/main/java/im/wangchao/mhttp/internal/cookie/MemoryCookieJar.java b/mhttp/src/main/java/im/wangchao/mhttp/internal/cookie/MemoryCookieJar.java deleted file mode 100644 index 34ff5235..00000000 --- a/mhttp/src/main/java/im/wangchao/mhttp/internal/cookie/MemoryCookieJar.java +++ /dev/null @@ -1,60 +0,0 @@ -package im.wangchao.mhttp.internal.cookie; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import im.wangchao.mhttp.internal.cookie.cache.CookieCache; -import okhttp3.Cookie; -import okhttp3.HttpUrl; - -/** - *Description : MemeryCookieJar.
- *Author : wangchao.
- *Date : 16/3/18.
- *Time : 下午2:20.
- */ -public class MemoryCookieJar implements ClearableCookieJar { - - private CookieCache cache; - - public MemoryCookieJar(CookieCache cache) { - this.cache = cache; - } - - @Override - synchronized public void saveFromResponse(HttpUrl url, List
- *
- * This new behaviour will be useful in determining when an already existing cookie in session must be overwritten.
- */
-class IdentifiableCookie {
-
- private Cookie cookie;
-
- static List Description : ParserException. Author : wangchao. Date : 16/4/26. Time : 下午8:38. Description : ResponseFailException. Author : wangchao. Date : 16/4/25. Time : 下午4:06. The format of the logs created by
- * this class should not be considered stable and may change slightly between releases. If you need
- * a stable logging format, use your own interceptor.
- */
-public final class HttpLoggingInterceptor implements Interceptor {
- private static final Charset UTF8 = Charset.forName("UTF-8");
-
- public enum Level {
- /** No logs. */
- NONE,
- /**
- * Logs request and response lines.
- *
- * Example:
- * Example:
- * Example:
- * Description : MBridgeInterceptors. Author : wangchao. Date : 16/8/24. Time : 下午4:32. Description : Logger. Author : wangchao. Date : 2018/3/20. Time : 下午5:36. Description : ResponseEnqueueObservable. Author : wangchao. Date : 2018/3/19. Time : 下午4:45. Description : ResponseExecuteObservable. Author : wangchao. Date : 2018/3/19. Time : 下午4:46. Description : RxRequest. Author : wangchao. Date : 2018/3/26. Time : 下午5:40.
- * Note: If an {@link OnChipClickListener} is set it's behavior will override the behavior described here if it's
- * {@link OnChipClickListener#onChipClick(Chip, MotionEvent)} method returns true. If that method returns false, the touched chip will be put
- * in editing mode as expected.
- *
- * If there is no ChipTokenizer set, we call through to the super method.
- *
- * @param text the text to be chipified
- */
- @Override
- protected void replaceText(CharSequence text) {
- // If we have a ChipTokenizer, this will be handled by our OnItemClickListener so we can do nothing here.
- // If we don't have a ChipTokenizer, we'll use the default behavior
- if (mChipTokenizer == null) {
- super.replaceText(text);
- }
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- if (mIgnoreTextChangedEvents) {
- return;
- }
-
- mTextChangedStart = start;
- mTextChangedEnd = start + after;
-
- // Check for backspace
- if (mChipTokenizer != null) {
- if (count > 0 && after < count) {
- int end = start + count;
- Editable message = getText();
- Chip[] chips = mChipTokenizer.findAllChips(start, end, message);
-
- for (Chip chip : chips) {
- int spanStart = mChipTokenizer.findChipStart(chip, message);
- int spanEnd = mChipTokenizer.findChipEnd(chip, message);
- if ((spanStart < end) && (spanEnd > start)) {
- // Add to remove list
- mChipsToRemove.add(chip);
- }
- }
- }
- }
- }
-
- @Override
- public void onTextChanged(@NonNull CharSequence textChanged, int start, int before, int count) {
- }
-
- @Override
- public void afterTextChanged(Editable message) {
- if (mIgnoreTextChangedEvents) {
- return;
- }
-
- // Avoid triggering text changed events from changes we make in this method
- beginUnwatchedTextChange();
-
- // Handle backspace key
- if (mChipTokenizer != null) {
- Iterator{@code
- * --> POST /greeting http/1.1 (3-byte body)
- *
- * <-- 200 OK (22ms, 6-byte body)
- * }
- */
- BASIC,
- /**
- * Logs request and response lines and their respective headers.
- *
- * {@code
- * --> POST /greeting http/1.1
- * Host: example.com
- * Content-Type: plain/text
- * Content-Length: 3
- * --> END POST
- *
- * <-- 200 OK (22ms)
- * Content-Type: plain/text
- * Content-Length: 6
- * <-- END HTTP
- * }
- */
- HEADERS,
- /**
- * Logs request and response lines and their respective headers and bodies (if present).
- *
- * {@code
- * --> POST /greeting http/1.1
- * Host: example.com
- * Content-Type: plain/text
- * Content-Length: 3
- *
- * Hi?
- * --> END POST
- *
- * <-- 200 OK (22ms)
- * Content-Type: plain/text
- * Content-Length: 6
- *
- * Hello!
- * <-- END HTTP
- * }
- */
- BODY
- }
-
- public interface Logger {
- void log(String message);
-
- /** A {@link Logger} defaults output appropriate for the current platform. */
- Logger DEFAULT = new Logger() {
- @Override public void log(String message) {
- Platform.get().log(INFO, message, null);
- }
- };
- }
-
- public HttpLoggingInterceptor() {
- this(Logger.DEFAULT);
- }
-
- public HttpLoggingInterceptor(Logger logger) {
- this.logger = logger;
- }
-
- private final Logger logger;
-
- private volatile Level level = Level.NONE;
-
- /** Change the level at which this interceptor logs. */
- public HttpLoggingInterceptor setLevel(Level level) {
- if (level == null) throw new NullPointerException("level == null. Use Level.NONE instead.");
- this.level = level;
- return this;
- }
-
- public Level getLevel() {
- return level;
- }
-
- @Override public Response intercept(Chain chain) throws IOException {
- Level level = this.level;
-
- Request request = chain.request();
- if (level == Level.NONE) {
- return chain.proceed(request);
- }
-
- boolean logBody = level == Level.BODY;
- boolean logHeaders = logBody || level == Level.HEADERS;
-
- RequestBody requestBody = request.body();
- boolean hasRequestBody = requestBody != null;
-
- Connection connection = chain.connection();
- String requestStartMessage = "--> "
- + request.method()
- + ' ' + request.url()
- + (connection != null ? " " + connection.protocol() : "");
- if (!logHeaders && hasRequestBody) {
- requestStartMessage += " (" + requestBody.contentLength() + "-byte body)";
- }
- logger.log(requestStartMessage);
-
- if (logHeaders) {
- if (hasRequestBody) {
- // Request body headers are only present when installed as a network interceptor. Force
- // them to be included (when available) so there values are known.
- if (requestBody.contentType() != null) {
- logger.log("Content-Type: " + requestBody.contentType());
- }
- if (requestBody.contentLength() != -1) {
- logger.log("Content-Length: " + requestBody.contentLength());
- }
- }
-
- Headers headers = request.headers();
- for (int i = 0, count = headers.size(); i < count; i++) {
- String name = headers.name(i);
- // Skip headers from the request body as they are explicitly logged above.
- if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
- logger.log(name + ": " + headers.value(i));
- }
- }
-
- if (!logBody || !hasRequestBody) {
- logger.log("--> END " + request.method());
- } else if (bodyHasUnknownEncoding(request.headers())) {
- logger.log("--> END " + request.method() + " (encoded body omitted)");
- } else {
- Buffer buffer = new Buffer();
- requestBody.writeTo(buffer);
-
- Charset charset = UTF8;
- MediaType contentType = requestBody.contentType();
- if (contentType != null) {
- charset = contentType.charset(UTF8);
- }
-
- logger.log("");
- if (isPlaintext(buffer)) {
- logger.log(buffer.readString(charset));
- logger.log("--> END " + request.method()
- + " (" + requestBody.contentLength() + "-byte body)");
- } else {
- logger.log("--> END " + request.method() + " (binary "
- + requestBody.contentLength() + "-byte body omitted)");
- }
- }
- }
-
- long startNs = System.nanoTime();
- Response response;
- try {
- response = chain.proceed(request);
- } catch (Exception e) {
- logger.log("<-- HTTP FAILED: " + e);
- throw e;
- }
- long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
-
- ResponseBody responseBody = response.body();
- long contentLength = responseBody.contentLength();
- String bodySize = contentLength != -1 ? contentLength + "-byte" : "unknown-length";
- logger.log("<-- "
- + response.code()
- + (response.message().isEmpty() ? "" : ' ' + response.message())
- + ' ' + response.request().url()
- + " (" + tookMs + "ms" + (!logHeaders ? ", " + bodySize + " body" : "") + ')');
-
- if (logHeaders) {
- Headers headers = response.headers();
- for (int i = 0, count = headers.size(); i < count; i++) {
- logger.log(headers.name(i) + ": " + headers.value(i));
- }
-
- if (!logBody || !HttpHeaders.hasBody(response)) {
- logger.log("<-- END HTTP");
- } else if (bodyHasUnknownEncoding(response.headers())) {
- logger.log("<-- END HTTP (encoded body omitted)");
- } else {
- BufferedSource source = responseBody.source();
- source.request(Long.MAX_VALUE); // Buffer the entire body.
- Buffer buffer = source.buffer();
-
- Long gzippedLength = null;
- if ("gzip".equalsIgnoreCase(headers.get("Content-Encoding"))) {
- gzippedLength = buffer.size();
- GzipSource gzippedResponseBody = null;
- try {
- gzippedResponseBody = new GzipSource(buffer.clone());
- buffer = new Buffer();
- buffer.writeAll(gzippedResponseBody);
- } finally {
- if (gzippedResponseBody != null) {
- gzippedResponseBody.close();
- }
- }
- }
-
- Charset charset = UTF8;
- MediaType contentType = responseBody.contentType();
- if (contentType != null) {
- charset = contentType.charset(UTF8);
- }
-
- if (!isPlaintext(buffer)) {
- logger.log("");
- logger.log("<-- END HTTP (binary " + buffer.size() + "-byte body omitted)");
- return response;
- }
-
- if (contentLength != 0) {
- logger.log("");
- logger.log(buffer.clone().readString(charset));
- }
-
- if (gzippedLength != null) {
- logger.log("<-- END HTTP (" + buffer.size() + "-byte, "
- + gzippedLength + "-gzipped-byte body)");
- } else {
- logger.log("<-- END HTTP (" + buffer.size() + "-byte body)");
- }
- }
- }
-
- return response;
- }
-
- /**
- * Returns true if the body in question probably contains human readable text. Uses a small sample
- * of code points to detect unicode control characters commonly used in binary file signatures.
- */
- static boolean isPlaintext(Buffer buffer) {
- try {
- Buffer prefix = new Buffer();
- long byteCount = buffer.size() < 64 ? buffer.size() : 64;
- buffer.copyTo(prefix, 0, byteCount);
- for (int i = 0; i < 16; i++) {
- if (prefix.exhausted()) {
- break;
- }
- int codePoint = prefix.readUtf8CodePoint();
- if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) {
- return false;
- }
- }
- return true;
- } catch (EOFException e) {
- return false; // Truncated UTF-8 sequence.
- }
- }
-
- private boolean bodyHasUnknownEncoding(Headers headers) {
- String contentEncoding = headers.get("Content-Encoding");
- return contentEncoding != null
- && !contentEncoding.equalsIgnoreCase("identity")
- && !contentEncoding.equalsIgnoreCase("gzip");
- }
-}
\ No newline at end of file
diff --git a/mhttp/src/main/java/im/wangchao/mhttp/internal/interceptor/MBridgeInterceptor.java b/mhttp/src/main/java/im/wangchao/mhttp/internal/interceptor/MBridgeInterceptor.java
deleted file mode 100644
index cd354e97..00000000
--- a/mhttp/src/main/java/im/wangchao/mhttp/internal/interceptor/MBridgeInterceptor.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package im.wangchao.mhttp.internal.interceptor;
-
-import java.io.IOException;
-
-import im.wangchao.mhttp.internal.Singleton;
-import im.wangchao.mhttp.internal.Version;
-import okhttp3.Interceptor;
-import okhttp3.Request;
-import okhttp3.Response;
-
-/**
- * The ChipTokenizer
- * To customize chipifying with this class you can provide a custom {@link ChipTokenizer} by calling {@link #setChipTokenizer(ChipTokenizer)}.
- * By default the {@link SpanChipTokenizer} is used.
- * Chip Terminators
- * To set which characters trigger the creation of a chip, call {@link #addChipTerminator(char, int)} or {@link #setChipTerminators(Map)}.
- * For example if tapping enter should cause all unchipped text to become chipped, call
- * {@code chipSuggestionTextView.addChipTerminator('\n', ChipTerminatorHandler.BEHAVIOR_CHIPIFY_ALL);}
- * To completely customize how chips are created when text is entered in this text view you can provide a custom {@link ChipTerminatorHandler}
- * through {@link #setChipTerminatorHandler(ChipTerminatorHandler)}
- * Illegal Characters
- * To prevent a character from being typed you can call {@link #setIllegalCharacterIdentifier(IllegalCharacterIdentifier)}} to identify characters
- * that should be considered illegal.
- * Suggestions
- * To provide suggestions you must provide an {@link android.widget.Adapter} by calling {@link #setAdapter(ListAdapter)}
- * UI Customization
- * This view defines six custom attributes (all of which are optional):
- *
- *
- * The values of these attributes will be passed to the ChipTokenizer through {@link ChipTokenizer#applyConfiguration(Editable, ChipConfiguration)}
- *
- *
- * Validation
- * This class can perform validation when certain events occur (such as losing focus). When the validation occurs is decided by
- * {@link AutoCompleteTextView}. To perform validation, set a {@link NachoValidator}:
- *
- * nachoTextView.setNachoValidator(new ChipifyingNachoValidator());
- *
- * Note: The NachoValidator will be ignored if a ChipTokenizer is not set. To perform validation without a ChipTokenizer you can use
- * {@link AutoCompleteTextView}'s built-in {@link AutoCompleteTextView.Validator Validator} through {@link #setValidator(Validator)}
- * Editing Chips
- * This class also supports editing chips on touch. To enable this behavior call {@link #enableEditChipOnTouch(boolean, boolean)}. To disable this
- * behavior you can call {@link #disableEditChipOnTouch()}
- * Example Setup:
- * A standard setup for this class could look something like the following:
- *
- * String[] suggestions = new String[]{"suggestion 1", "suggestion 2"};
- * ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, suggestions);
- * nachoTextView.setAdapter(adapter);
- * nachoTextView.addChipTerminator('\n', ChipTerminatorHandler.BEHAVIOR_CHIPIFY_ALL);
- * nachoTextView.addChipTerminator(' ', ChipTerminatorHandler.BEHAVIOR_CHIPIFY_TO_TERMINATOR);
- * nachoTextView.setIllegalCharacters('@');
- * nachoTextView.setNachoValidator(new ChipifyingNachoValidator());
- * nachoTextView.enableEditChipOnTouch(true, true);
- * nachoTextView.setOnChipClickListener(new NachoTextView.OnChipClickListener() {
- * {@literal @Override}
- * public void onChipClick(Chip chip, MotionEvent motionEvent) {
- * // Handle click event
- * }
- * });
- * nachoTextView.setOnChipRemoveListener(new NachoTextView.OnChipRemoveListener() {
- * {@literal @Override}
- * public void onChipRemove(Chip chip) {
- * // Handle remove event
- * }
- * });
- *
- *
- * @see SpanChipTokenizer
- * @see DefaultChipTerminatorHandler
- * @see ChipifyingNachoValidator
- */
-public class NachoTextView extends MultiAutoCompleteTextView implements TextWatcher, AdapterView.OnItemClickListener {
-
- // UI Attributes
- private int mChipHorizontalSpacing = -1;
- private ColorStateList mChipBackground = null;
- private int mChipCornerRadius = -1;
- private int mChipTextColor = Color.TRANSPARENT;
- private int mChipTextSize = -1;
- private int mChipHeight = -1;
- private int mChipVerticalSpacing = -1;
-
- private int mDefaultPaddingTop = 0;
- private int mDefaultPaddingBottom = 0;
- /**
- * Flag to keep track of the padding state so we only update the padding when necessary
- */
- private boolean mUsingDefaultPadding = true;
-
- // Touch events
- @Nullable
- private OnChipClickListener mOnChipClickListener;
- private GestureDetector singleTapDetector;
- private boolean mEditChipOnTouchEnabled;
- private boolean mMoveChipToEndOnEdit;
- private boolean mChipifyUnterminatedTokensOnEdit;
-
- // Text entry
- @Nullable
- private ChipTokenizer mChipTokenizer;
- @Nullable
- private ChipTerminatorHandler mChipTerminatorHandler;
- @Nullable
- private NachoValidator mNachoValidator;
- @Nullable
- private IllegalCharacterIdentifier illegalCharacterIdentifier;
-
- @Nullable
- private OnChipRemoveListener mOnChipRemoveListener;
- private List