diff --git a/app/src/main/java/com/hippo/network/CookieDatabase.kt b/app/src/main/java/com/hippo/network/CookieDatabase.kt index 6d849d74b..ef0ef9fa1 100644 --- a/app/src/main/java/com/hippo/network/CookieDatabase.kt +++ b/app/src/main/java/com/hippo/network/CookieDatabase.kt @@ -13,225 +13,202 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.hippo.network -package com.hippo.network; +import android.content.ContentValues +import android.content.Context +import android.database.Cursor +import android.database.sqlite.SQLiteDatabase +import android.database.sqlite.SQLiteOpenHelper +import android.util.Log +import com.hippo.database.MSQLiteBuilder +import com.hippo.util.SqlUtils +import okhttp3.Cookie -/* - * Created by Hippo on 2017/9/4. - */ +internal class CookieDatabase(context: Context, name: String) { + private val cookieIdMap: MutableMap = HashMap() + private val helper: SQLiteOpenHelper + private val db: SQLiteDatabase -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; -import android.database.sqlite.SQLiteStatement; -import android.util.Log; + val allCookies: MutableMap + get() { + val now = System.currentTimeMillis() + val map: MutableMap = HashMap() + val toRemove: MutableList = ArrayList() + db.rawQuery("SELECT * FROM $TABLE_COOKIE;", null).use { cursor -> + while (cursor.moveToNext()) { + val id = SqlUtils.getLong(cursor, COLUMN_ID, 0) + val cookie = getCookie(cursor, now) + if (cookie != null) { + // Save id of the cookie in db + cookieIdMap[cookie] = id -import androidx.annotation.Nullable; - -import com.hippo.database.MSQLiteBuilder; -import com.hippo.util.SqlUtils; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import okhttp3.Cookie; - -class CookieDatabase { - - private static final String LOG_TAG = CookieDatabase.class.getSimpleName(); - - private static final int VERSION_1 = 1; - private static final String TABLE_COOKIE = "OK_HTTP_3_COOKIE"; - private static final String COLUMN_ID = "_id"; - private static final String COLUMN_NAME = "NAME"; - private static final String COLUMN_VALUE = "VALUE"; - private static final String COLUMN_EXPIRES_AT = "EXPIRES_AT"; - private static final String COLUMN_DOMAIN = "DOMAIN"; - private static final String COLUMN_PATH = "PATH"; - private static final String COLUMN_SECURE = "SECURE"; - private static final String COLUMN_HTTP_ONLY = "HTTP_ONLY"; - private static final String COLUMN_PERSISTENT = "PERSISTENT"; - private static final String COLUMN_HOST_ONLY = "HOST_ONLY"; - - private static final int DB_VERSION = VERSION_1; - - private final Map cookieIdMap = new HashMap<>(); - private final SQLiteOpenHelper helper; - private final SQLiteDatabase db; - - public CookieDatabase(Context context, String name) { - helper = new MSQLiteBuilder() - .version(VERSION_1) - .createTable(TABLE_COOKIE) - .insertColumn(TABLE_COOKIE, COLUMN_NAME, String.class) - .insertColumn(TABLE_COOKIE, COLUMN_VALUE, String.class) - .insertColumn(TABLE_COOKIE, COLUMN_EXPIRES_AT, long.class) - .insertColumn(TABLE_COOKIE, COLUMN_DOMAIN, String.class) - .insertColumn(TABLE_COOKIE, COLUMN_PATH, String.class) - .insertColumn(TABLE_COOKIE, COLUMN_SECURE, boolean.class) - .insertColumn(TABLE_COOKIE, COLUMN_HTTP_ONLY, boolean.class) - .insertColumn(TABLE_COOKIE, COLUMN_PERSISTENT, boolean.class) - .insertColumn(TABLE_COOKIE, COLUMN_HOST_ONLY, boolean.class) - .build(context, name, DB_VERSION); - db = helper.getWritableDatabase(); - } - - @Nullable - private static Cookie getCookie(Cursor cursor, long now) { - String name = SqlUtils.getString(cursor, COLUMN_NAME, null); - String value = SqlUtils.getString(cursor, COLUMN_VALUE, null); - long expiresAt = SqlUtils.getLong(cursor, COLUMN_EXPIRES_AT, 0); - String domain = SqlUtils.getString(cursor, COLUMN_DOMAIN, null); - String path = SqlUtils.getString(cursor, COLUMN_PATH, null); - boolean secure = SqlUtils.getBoolean(cursor, COLUMN_SECURE, false); - boolean httpOnly = SqlUtils.getBoolean(cursor, COLUMN_HTTP_ONLY, false); - boolean persistent = SqlUtils.getBoolean(cursor, COLUMN_PERSISTENT, false); - boolean hostOnly = SqlUtils.getBoolean(cursor, COLUMN_HOST_ONLY, false); - - if (name == null || domain == null || path == null) { - return null; - } - - // Check non-persistent or expired - if (!persistent || expiresAt <= now) { - return null; - } - - Cookie.Builder builder = new Cookie.Builder(); - builder.name(name); - builder.value(value); - if (hostOnly) { - builder.hostOnlyDomain(domain); - } else { - builder.domain(domain); - } - builder.path(path); - builder.expiresAt(expiresAt); - if (secure) builder.secure(); - if (httpOnly) builder.httpOnly(); - return builder.build(); - } - - public Map getAllCookies() { - long now = System.currentTimeMillis(); - Map map = new HashMap<>(); - List toRemove = new ArrayList<>(); - - try (Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_COOKIE + ";", null)) { - while (cursor.moveToNext()) { - long id = SqlUtils.getLong(cursor, COLUMN_ID, 0); - Cookie cookie = getCookie(cursor, now); - - if (cookie != null) { - // Save id of the cookie in db - cookieIdMap.put(cookie, id); - - // Put cookie to set - CookieSet set = map.get(cookie.domain()); - if (set == null) { - set = new CookieSet(); - map.put(cookie.domain(), set); + // Put cookie to set + var set = map[cookie.domain] + if (set == null) { + set = CookieSet() + map[cookie.domain] = set + } + set.add(cookie) + } else { + // Mark to remove the cookie + toRemove.add(id) } - set.add(cookie); - } else { - // Mark to remove the cookie - toRemove.add(id); } } - } - // Remove invalid or expired cookie - if (!toRemove.isEmpty()) { - SQLiteStatement statement = db.compileStatement( - "DELETE FROM " + TABLE_COOKIE + " WHERE " + COLUMN_ID + " = ?;"); - db.beginTransaction(); - try { - for (long id : toRemove) { - statement.bindLong(1, id); - statement.executeUpdateDelete(); + // Remove invalid or expired cookie + if (toRemove.isNotEmpty()) { + val statement = db.compileStatement( + "DELETE FROM $TABLE_COOKIE WHERE $COLUMN_ID = ?;" + ) + db.beginTransaction() + try { + for (id in toRemove) { + statement.bindLong(1, id) + statement.executeUpdateDelete() + } + db.setTransactionSuccessful() + } finally { + db.endTransaction() } - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); } + return map } - return map; + private fun toContentValues(cookie: Cookie): ContentValues { + val contentValues = ContentValues(9) + contentValues.put(COLUMN_NAME, cookie.name) + contentValues.put(COLUMN_VALUE, cookie.value) + contentValues.put(COLUMN_EXPIRES_AT, cookie.expiresAt) + contentValues.put(COLUMN_DOMAIN, cookie.domain) + contentValues.put(COLUMN_PATH, cookie.path) + contentValues.put(COLUMN_SECURE, cookie.secure) + contentValues.put(COLUMN_HTTP_ONLY, cookie.httpOnly) + contentValues.put(COLUMN_PERSISTENT, cookie.persistent) + contentValues.put(COLUMN_HOST_ONLY, cookie.hostOnly) + return contentValues } - public ContentValues toContentValues(Cookie cookie) { - ContentValues contentValues = new ContentValues(9); - contentValues.put(COLUMN_NAME, cookie.name()); - contentValues.put(COLUMN_VALUE, cookie.value()); - contentValues.put(COLUMN_EXPIRES_AT, cookie.expiresAt()); - contentValues.put(COLUMN_DOMAIN, cookie.domain()); - contentValues.put(COLUMN_PATH, cookie.path()); - contentValues.put(COLUMN_SECURE, cookie.secure()); - contentValues.put(COLUMN_HTTP_ONLY, cookie.httpOnly()); - contentValues.put(COLUMN_PERSISTENT, cookie.persistent()); - contentValues.put(COLUMN_HOST_ONLY, cookie.hostOnly()); - return contentValues; - } - - public void add(Cookie cookie) { - long id = db.insert(TABLE_COOKIE, null, toContentValues(cookie)); + fun add(cookie: Cookie) { + val id = db.insert(TABLE_COOKIE, null, toContentValues(cookie)) if (id != -1L) { - Long oldId = cookieIdMap.put(cookie, id); - if (oldId != null) Log.e(LOG_TAG, "Add a duplicate cookie"); + val oldId = cookieIdMap.put(cookie, id) + if (oldId != null) Log.e(LOG_TAG, "Add a duplicate cookie") } else { - Log.e(LOG_TAG, "An error occurred when insert a cookie"); + Log.e(LOG_TAG, "An error occurred when insert a cookie") } } - public void update(Cookie from, Cookie to) { - Long id = cookieIdMap.get(from); + fun update(from: Cookie, to: Cookie) { + val id = cookieIdMap[from] if (id == null) { - Log.e(LOG_TAG, "Can't get id when update the cookie"); - return; + Log.e(LOG_TAG, "Can't get id when update the cookie") + return } - - ContentValues values = toContentValues(to); - String whereClause = COLUMN_ID + " = ?"; - String[] whereArgs = {id.toString()}; - int count = db.update(TABLE_COOKIE, values, whereClause, whereArgs); + val values = toContentValues(to) + val whereClause = "$COLUMN_ID = ?" + val whereArgs = arrayOf(id.toString()) + val count = db.update(TABLE_COOKIE, values, whereClause, whereArgs) if (count != 1) { - Log.e(LOG_TAG, "Bad result when update cookie: " + count); + Log.e(LOG_TAG, "Bad result when update cookie: $count") } // Update it in cookie-id map - cookieIdMap.remove(from); - cookieIdMap.put(to, id); + cookieIdMap.remove(from) + cookieIdMap[to] = id } - public void remove(Cookie cookie) { - Long id = cookieIdMap.get(cookie); + fun remove(cookie: Cookie) { + val id = cookieIdMap[cookie] if (id == null) { - Log.e(LOG_TAG, "Can't get id when remove the cookie"); - return; + Log.e(LOG_TAG, "Can't get id when remove the cookie") + return } - - String whereClause = COLUMN_ID + " = ?"; - String[] whereArgs = {id.toString()}; - int count = db.delete(TABLE_COOKIE, whereClause, whereArgs); + val whereClause = "$COLUMN_ID = ?" + val whereArgs = arrayOf(id.toString()) + val count = db.delete(TABLE_COOKIE, whereClause, whereArgs) if (count != 1) { - Log.e(LOG_TAG, "Bad result when remove cookie: " + count); + Log.e(LOG_TAG, "Bad result when remove cookie: $count") } // Remove it from cookie-id map - cookieIdMap.remove(cookie); + cookieIdMap.remove(cookie) } - public void clear() { - db.delete(TABLE_COOKIE, null, null); - cookieIdMap.clear(); + fun clear() { + db.delete(TABLE_COOKIE, null, null) + cookieIdMap.clear() } - public void close() { - db.close(); - helper.close(); + fun close() { + db.close() + helper.close() } -} + + companion object { + private val LOG_TAG = CookieDatabase::class.java.simpleName + private const val VERSION_1 = 1 + private const val TABLE_COOKIE = "OK_HTTP_3_COOKIE" + private const val COLUMN_ID = "_id" + private const val COLUMN_NAME = "NAME" + private const val COLUMN_VALUE = "VALUE" + private const val COLUMN_EXPIRES_AT = "EXPIRES_AT" + private const val COLUMN_DOMAIN = "DOMAIN" + private const val COLUMN_PATH = "PATH" + private const val COLUMN_SECURE = "SECURE" + private const val COLUMN_HTTP_ONLY = "HTTP_ONLY" + private const val COLUMN_PERSISTENT = "PERSISTENT" + private const val COLUMN_HOST_ONLY = "HOST_ONLY" + private const val DB_VERSION = VERSION_1 + private fun getCookie(cursor: Cursor, now: Long): Cookie? { + val name = SqlUtils.getString(cursor, COLUMN_NAME, null) + val value = SqlUtils.getString(cursor, COLUMN_VALUE, null) + val expiresAt = SqlUtils.getLong(cursor, COLUMN_EXPIRES_AT, 0) + val domain = SqlUtils.getString(cursor, COLUMN_DOMAIN, null) + val path = SqlUtils.getString(cursor, COLUMN_PATH, null) + val secure = SqlUtils.getBoolean(cursor, COLUMN_SECURE, false) + val httpOnly = SqlUtils.getBoolean(cursor, COLUMN_HTTP_ONLY, false) + val persistent = SqlUtils.getBoolean(cursor, COLUMN_PERSISTENT, false) + val hostOnly = SqlUtils.getBoolean(cursor, COLUMN_HOST_ONLY, false) + if (name == null || domain == null || path == null) { + return null + } + + // Check non-persistent or expired + if (!persistent || expiresAt <= now) { + return null + } + val builder = Cookie.Builder() + builder.name(name) + builder.value(value) + if (hostOnly) { + builder.hostOnlyDomain(domain) + } else { + builder.domain(domain) + } + builder.path(path) + builder.expiresAt(expiresAt) + if (secure) builder.secure() + if (httpOnly) builder.httpOnly() + return builder.build() + } + } + + init { + helper = MSQLiteBuilder() + .version(VERSION_1) + .createTable(TABLE_COOKIE) + .insertColumn(TABLE_COOKIE, COLUMN_NAME, String::class.java) + .insertColumn(TABLE_COOKIE, COLUMN_VALUE, String::class.java) + .insertColumn(TABLE_COOKIE, COLUMN_EXPIRES_AT, Long::class.javaPrimitiveType) + .insertColumn(TABLE_COOKIE, COLUMN_DOMAIN, String::class.java) + .insertColumn(TABLE_COOKIE, COLUMN_PATH, String::class.java) + .insertColumn(TABLE_COOKIE, COLUMN_SECURE, Boolean::class.javaPrimitiveType) + .insertColumn(TABLE_COOKIE, COLUMN_HTTP_ONLY, Boolean::class.javaPrimitiveType) + .insertColumn(TABLE_COOKIE, COLUMN_PERSISTENT, Boolean::class.javaPrimitiveType) + .insertColumn(TABLE_COOKIE, COLUMN_HOST_ONLY, Boolean::class.javaPrimitiveType) + .build(context, name, DB_VERSION) + db = helper.writableDatabase + } +} \ No newline at end of file diff --git a/app/src/main/java/com/hippo/network/CookieRepository.kt b/app/src/main/java/com/hippo/network/CookieRepository.kt index eb7c7b095..471de86f7 100644 --- a/app/src/main/java/com/hippo/network/CookieRepository.kt +++ b/app/src/main/java/com/hippo/network/CookieRepository.kt @@ -13,183 +13,169 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.hippo.network -package com.hippo.network; +import android.content.Context +import com.hippo.yorozuya.ObjectUtils +import okhttp3.Cookie +import okhttp3.CookieJar +import okhttp3.HttpUrl +import java.util.regex.Pattern -/* - * Created by Hippo on 2017/9/4. - */ +open class CookieRepository(context: Context, name: String) : CookieJar { + private val db: CookieDatabase + private val map: MutableMap -import android.content.Context; - -import androidx.annotation.NonNull; - -import com.hippo.yorozuya.ObjectUtils; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; - -import okhttp3.Cookie; -import okhttp3.CookieJar; -import okhttp3.HttpUrl; - -public class CookieRepository implements CookieJar { - - /** - * Quick and dirty pattern to differentiate IP addresses from hostnames. This is an approximation - * of Android's private InetAddress#isNumeric API. - *

- * This matches IPv6 addresses as a hex string containing at least one colon, and possibly - * including dots after the first colon. It matches IPv4 addresses as strings containing only - * decimal digits and dots. This pattern matches strings like "a:.23" and "54" that are neither IP - * addresses nor hostnames; they will be verified as IP addresses (which is a more strict - * verification). - */ - private static final Pattern VERIFY_AS_IP_ADDRESS = Pattern.compile("([0-9a-fA-F]*:[0-9a-fA-F:.]*)|([\\d.]+)"); - private final CookieDatabase db; - private final Map map; - - public CookieRepository(Context context, String name) { - db = new CookieDatabase(context, name); - map = db.getAllCookies(); - } - - /** - * Returns true if `host` is not a host name and might be an IP address. - */ - private static boolean verifyAsIpAddress(String host) { - return VERIFY_AS_IP_ADDRESS.matcher(host).matches(); - } - - // okhttp3.Cookie.domainMatch(HttpUrl, String) - protected static boolean domainMatch(HttpUrl url, String domain) { - String urlHost = url.host(); - - if (urlHost.equals(domain)) { - return true; // As in 'example.com' matching 'example.com'. - } - - return urlHost.endsWith(domain) - && urlHost.charAt(urlHost.length() - domain.length() - 1) == '.' - && !verifyAsIpAddress(urlHost); // As in 'example.com' matching 'www.example.com'. - } - - public synchronized void addCookie(Cookie cookie) { + @Synchronized + fun addCookie(cookie: Cookie) { // For cookie database - Cookie toAdd = null; - Cookie toUpdate = null; - Cookie toRemove = null; - - CookieSet set = map.get(cookie.domain()); + var toAdd: Cookie? = null + var toUpdate: Cookie? = null + var toRemove: Cookie? = null + var set = map[cookie.domain] if (set == null) { - set = new CookieSet(); - map.put(cookie.domain(), set); + set = CookieSet() + map[cookie.domain] = set } - - if (cookie.expiresAt() <= System.currentTimeMillis()) { - toRemove = set.remove(cookie); + if (cookie.expiresAt <= System.currentTimeMillis()) { + toRemove = set.remove(cookie) // If the cookie is not persistent, it's not in database - if (toRemove != null && !toRemove.persistent()) { - toRemove = null; + if (toRemove != null && !toRemove.persistent) { + toRemove = null } } else { - toAdd = cookie; - toUpdate = set.add(cookie); + toAdd = cookie + toUpdate = set.add(cookie) // If the cookie is not persistent, it's not in database - if (!toAdd.persistent()) toAdd = null; - if (toUpdate != null && !toUpdate.persistent()) toUpdate = null; + if (!toAdd.persistent) toAdd = null + if (toUpdate != null && !toUpdate.persistent) toUpdate = null // Remove the cookie if it updates to null if (toAdd == null && toUpdate != null) { - toRemove = toUpdate; - toUpdate = null; + toRemove = toUpdate + toUpdate = null } } - if (toRemove != null) { - db.remove(toRemove); + db.remove(toRemove) } if (toAdd != null) { if (toUpdate != null) { - db.update(toUpdate, toAdd); + db.update(toUpdate, toAdd) } else { - db.add(toAdd); + db.add(toAdd) } } } - public String getCookieHeader(HttpUrl url) { - List cookies = getCookies(url); - StringBuilder cookieHeader = new StringBuilder(); - for (int i = 0, size = cookies.size(); i < size; i++) { + fun getCookieHeader(url: HttpUrl): String { + val cookies = getCookies(url) + val cookieHeader = StringBuilder() + var i = 0 + val size = cookies.size + while (i < size) { if (i > 0) { - cookieHeader.append("; "); + cookieHeader.append("; ") } - Cookie cookie = cookies.get(i); - cookieHeader.append(cookie.name()).append('=').append(cookie.value()); + val cookie = cookies[i] + cookieHeader.append(cookie.name).append('=').append(cookie.value) + i++ } - return cookieHeader.toString(); + return cookieHeader.toString() } - public synchronized List getCookies(HttpUrl url) { - List accepted = new ArrayList<>(); - List expired = new ArrayList<>(); - - for (Map.Entry entry : map.entrySet()) { - String domain = entry.getKey(); - CookieSet cookieSet = entry.getValue(); + @Synchronized + fun getCookies(url: HttpUrl): List { + val accepted: MutableList = ArrayList() + val expired: MutableList = ArrayList() + for ((domain, cookieSet) in map) { if (domainMatch(url, domain)) { - cookieSet.get(url, accepted, expired); + cookieSet[url, accepted, expired] } } - - for (Cookie cookie : expired) { - if (cookie.persistent()) { - db.remove(cookie); + for (cookie in expired) { + if (cookie.persistent) { + db.remove(cookie) } } // RFC 6265 Section-5.4 step 2, sort the cookie-list // Cookies with longer paths are listed before cookies with shorter paths. // Ignore creation-time, we don't store them. - Collections.sort(accepted, (o1, o2) -> o2.path().length() - o1.path().length()); - - return accepted; + accepted.sortWith { o1: Cookie, o2: Cookie -> o2.path.length - o1.path.length } + return accepted } - public boolean contains(HttpUrl url, String name) { - for (Cookie cookie : getCookies(url)) { - if (ObjectUtils.equal(cookie.name(), name)) { - return true; + fun contains(url: HttpUrl, name: String?): Boolean { + for (cookie in getCookies(url)) { + if (ObjectUtils.equal(cookie.name, name)) { + return true } } - return false; + return false } /** - * Remove all cookies in this {@code CookieRepository}. + * Remove all cookies in this `CookieRepository`. */ - public synchronized void clear() { - map.clear(); - db.clear(); + @Synchronized + fun clear() { + map.clear() + db.clear() } - public synchronized void close() { - db.close(); + @Synchronized + fun close() { + db.close() } - @Override - public void saveFromResponse(@NonNull HttpUrl httpUrl, List list) { - for (Cookie cookie : list) { - addCookie(cookie); + override fun saveFromResponse(url: HttpUrl, cookies: List) { + for (cookie in cookies) { + addCookie(cookie) } } - @NonNull - @Override - public List loadForRequest(@NonNull HttpUrl httpUrl) { - return getCookies(httpUrl); + override fun loadForRequest(url: HttpUrl): List { + return getCookies(url) } -} + + companion object { + /** + * Quick and dirty pattern to differentiate IP addresses from hostnames. This is an approximation + * of Android's private InetAddress#isNumeric API. + * + * + * This matches IPv6 addresses as a hex string containing at least one colon, and possibly + * including dots after the first colon. It matches IPv4 addresses as strings containing only + * decimal digits and dots. This pattern matches strings like "a:.23" and "54" that are neither IP + * addresses nor hostnames; they will be verified as IP addresses (which is a more strict + * verification). + */ + private val VERIFY_AS_IP_ADDRESS = + Pattern.compile("([0-9a-fA-F]*:[0-9a-fA-F:.]*)|([\\d.]+)") + + /** + * Returns true if `host` is not a host name and might be an IP address. + */ + private fun verifyAsIpAddress(host: String): Boolean { + return VERIFY_AS_IP_ADDRESS.matcher(host).matches() + } + + // okhttp3.Cookie.domainMatch(HttpUrl, String) + @JvmStatic + protected fun domainMatch(url: HttpUrl, domain: String?): Boolean { + val urlHost = url.host + return if (urlHost == domain) { + true // As in 'example.com' matching 'example.com'. + } else urlHost.endsWith(domain!!) + && urlHost[urlHost.length - domain.length - 1] == '.' && !verifyAsIpAddress( + urlHost + ) + // As in 'example.com' matching 'www.example.com'. + } + } + + init { + db = CookieDatabase(context, name) + map = db.allCookies + } +} \ No newline at end of file diff --git a/app/src/main/java/com/hippo/network/CookieSet.kt b/app/src/main/java/com/hippo/network/CookieSet.kt index bd8e4a39b..38f8dc633 100644 --- a/app/src/main/java/com/hippo/network/CookieSet.kt +++ b/app/src/main/java/com/hippo/network/CookieSet.kt @@ -13,94 +13,75 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.hippo.network -package com.hippo.network; +import com.hippo.util.HashCodeUtils +import com.hippo.yorozuya.ObjectUtils +import okhttp3.Cookie +import okhttp3.HttpUrl -/* - * Created by Hippo on 2017/9/4. - */ - -import com.hippo.util.HashCodeUtils; -import com.hippo.yorozuya.ObjectUtils; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import okhttp3.Cookie; -import okhttp3.HttpUrl; - -class CookieSet { - - private final Map map = new HashMap<>(); +internal class CookieSet { + private val map: MutableMap = HashMap() /** - * Adds a cookie to this {@code CookieSet}. + * Adds a cookie to this `CookieSet`. * Returns a previous cookie with - * the same name, domain and path or {@code null}. + * the same name, domain and path or `null`. */ - public Cookie add(Cookie cookie) { - return map.put(new Key(cookie), cookie); + fun add(cookie: Cookie): Cookie? { + return map.put(Key(cookie), cookie) } /** * Removes a cookie with the same name, * domain and path as the cookie. - * Returns the removed cookie or {@code null}. + * Returns the removed cookie or `null`. */ - public Cookie remove(Cookie cookie) { - return map.remove(new Key(cookie)); + fun remove(cookie: Cookie): Cookie? { + return map.remove(Key(cookie)) } /** - * Get cookies for the url. Fill {@code accepted} and {@code expired}. + * Get cookies for the url. Fill `accepted` and `expired`. */ - public void get(HttpUrl url, List accepted, List expired) { - long now = System.currentTimeMillis(); - Iterator> iterator = map.entrySet().iterator(); + operator fun get(url: HttpUrl?, accepted: MutableList, expired: MutableList) { + val now = System.currentTimeMillis() + val iterator: MutableIterator> = map.entries.iterator() while (iterator.hasNext()) { - Cookie cookie = iterator.next().getValue(); - if (cookie.expiresAt() <= now) { - iterator.remove(); - expired.add(cookie); - } else if (cookie.matches(url)) { - accepted.add(cookie); + val cookie = iterator.next().value + if (cookie.expiresAt <= now) { + iterator.remove() + expired.add(cookie) + } else if (cookie.matches(url!!)) { + accepted.add(cookie) } } } - static class Key { - - private final String name; - private final String domain; - private final String path; - - public Key(Cookie cookie) { - this.name = cookie.name(); - this.domain = cookie.domain(); - this.path = cookie.path(); + internal class Key(cookie: Cookie) { + private val name: String + private val domain: String + private val path: String + override fun equals(other: Any?): Boolean { + if (other === this) { + return true + } + if (other is Key) { + return ObjectUtils.equal(other.name, name) && + ObjectUtils.equal(other.domain, domain) && + ObjectUtils.equal(other.path, path) + } + return false } - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (obj instanceof Key) { - Key key = (Key) obj; - return ObjectUtils.equal(key.name, this.name) && - ObjectUtils.equal(key.domain, this.domain) && - ObjectUtils.equal(key.path, this.path); - } - - return false; + override fun hashCode(): Int { + return HashCodeUtils.hashCode(name, domain, path) } - @Override - public int hashCode() { - return HashCodeUtils.hashCode(name, domain, path); + init { + name = cookie.name + domain = cookie.domain + path = cookie.path } } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/hippo/network/InetValidator.kt b/app/src/main/java/com/hippo/network/InetValidator.kt index 6403369d3..caf1d55a2 100644 --- a/app/src/main/java/com/hippo/network/InetValidator.kt +++ b/app/src/main/java/com/hippo/network/InetValidator.kt @@ -13,55 +13,47 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.hippo.network -package com.hippo.network; +import java.util.regex.Pattern -import java.util.regex.Matcher; -import java.util.regex.Pattern; +object InetValidator { + private const val IPV4_REGEX = "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" + private val IPV4_PATTERN = Pattern.compile(IPV4_REGEX) -public final class InetValidator { - - private static final String IPV4_REGEX = - "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$"; - - private static final Pattern IPV4_PATTERN = Pattern.compile(IPV4_REGEX); - - private InetValidator() { - } - - public static boolean isValidInet4Address(String inet4Address) { + @JvmStatic + fun isValidInet4Address(inet4Address: String?): Boolean { if (null == inet4Address) { - return false; + return false } - - Matcher matcher = IPV4_PATTERN.matcher(inet4Address); + val matcher = IPV4_PATTERN.matcher(inet4Address) if (!matcher.find()) { - return false; + return false } // verify that address subgroups are legal - for (int i = 1; i <= 4; i++) { - String ipSegment = matcher.group(i); - if (ipSegment == null || ipSegment.length() == 0) { - return false; + for (i in 1..4) { + val ipSegment = matcher.group(i) + if (ipSegment == null || ipSegment.isEmpty()) { + return false } - int iIpSegment; - try { - iIpSegment = Integer.parseInt(ipSegment); - } catch (NumberFormatException e) { - return false; + val iIpSegment: Int = try { + ipSegment.toInt() + } catch (e: NumberFormatException) { + return false } if (iIpSegment > 255) { - return false; + return false } - if (ipSegment.length() > 1 && ipSegment.startsWith("0")) { - return false; + if (ipSegment.length > 1 && ipSegment.startsWith("0")) { + return false } } - return true; + return true } - public static boolean isValidInetPort(int inetPort) { - return inetPort >= 0 && inetPort <= 65535; + @JvmStatic + fun isValidInetPort(inetPort: Int): Boolean { + return inetPort in 0..65535 } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/hippo/network/StatusCodeException.kt b/app/src/main/java/com/hippo/network/StatusCodeException.kt index f371ff7b2..08e340e0e 100644 --- a/app/src/main/java/com/hippo/network/StatusCodeException.kt +++ b/app/src/main/java/com/hippo/network/StatusCodeException.kt @@ -13,78 +13,54 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.hippo.network -package com.hippo.network; +import android.content.Context +import android.util.SparseArray +import com.hippo.ehviewer.R -import android.content.Context; -import android.content.res.Resources; -import android.util.SparseArray; +class StatusCodeException(val responseCode: Int) : Exception() { + override val message: String = ERROR_MESSAGE_ARRAY[responseCode, DEFAULT_ERROR_MESSAGE] -import com.hippo.ehviewer.R; + val isIdentifiedResponseCode: Boolean + get() = DEFAULT_ERROR_MESSAGE != message -public class StatusCodeException extends Exception { - - private static final SparseArray ERROR_MESSAGE_ARRAY = new SparseArray<>(24); - private static final String DEFAULT_ERROR_MESSAGE = "Error response code"; - - private final int mResponseCode; - private final String mMessage; - - public StatusCodeException(int responseCode) { - mResponseCode = responseCode; - mMessage = ERROR_MESSAGE_ARRAY.get(responseCode, DEFAULT_ERROR_MESSAGE); + override fun getLocalizedMessage(): String { + return message } - public StatusCodeException(int responseCode, String message) { - mResponseCode = responseCode; - mMessage = message; + companion object { + private val ERROR_MESSAGE_ARRAY = SparseArray(24) + private const val DEFAULT_ERROR_MESSAGE = "Error response code" + + @JvmStatic + fun initialize(context: Context) { + val resources = context.applicationContext.resources + ERROR_MESSAGE_ARRAY.append(400, resources.getString(R.string.error_status_code_400)) + ERROR_MESSAGE_ARRAY.append(401, resources.getString(R.string.error_status_code_401)) + ERROR_MESSAGE_ARRAY.append(402, resources.getString(R.string.error_status_code_402)) + ERROR_MESSAGE_ARRAY.append(403, resources.getString(R.string.error_status_code_403)) + ERROR_MESSAGE_ARRAY.append(404, resources.getString(R.string.error_status_code_404)) + ERROR_MESSAGE_ARRAY.append(405, resources.getString(R.string.error_status_code_405)) + ERROR_MESSAGE_ARRAY.append(406, resources.getString(R.string.error_status_code_406)) + ERROR_MESSAGE_ARRAY.append(407, resources.getString(R.string.error_status_code_407)) + ERROR_MESSAGE_ARRAY.append(408, resources.getString(R.string.error_status_code_408)) + ERROR_MESSAGE_ARRAY.append(409, resources.getString(R.string.error_status_code_409)) + ERROR_MESSAGE_ARRAY.append(410, resources.getString(R.string.error_status_code_410)) + ERROR_MESSAGE_ARRAY.append(411, resources.getString(R.string.error_status_code_411)) + ERROR_MESSAGE_ARRAY.append(412, resources.getString(R.string.error_status_code_412)) + ERROR_MESSAGE_ARRAY.append(413, resources.getString(R.string.error_status_code_413)) + ERROR_MESSAGE_ARRAY.append(414, resources.getString(R.string.error_status_code_414)) + ERROR_MESSAGE_ARRAY.append(415, resources.getString(R.string.error_status_code_415)) + ERROR_MESSAGE_ARRAY.append(416, resources.getString(R.string.error_status_code_416)) + ERROR_MESSAGE_ARRAY.append(417, resources.getString(R.string.error_status_code_417)) + ERROR_MESSAGE_ARRAY.append(500, resources.getString(R.string.error_status_code_500)) + ERROR_MESSAGE_ARRAY.append(501, resources.getString(R.string.error_status_code_501)) + ERROR_MESSAGE_ARRAY.append(502, resources.getString(R.string.error_status_code_502)) + ERROR_MESSAGE_ARRAY.append(503, resources.getString(R.string.error_status_code_503)) + ERROR_MESSAGE_ARRAY.append(504, resources.getString(R.string.error_status_code_504)) + ERROR_MESSAGE_ARRAY.append(505, resources.getString(R.string.error_status_code_505)) + } } - public static void initialize(Context context) { - Resources resources = context.getApplicationContext().getResources(); - - ERROR_MESSAGE_ARRAY.append(400, resources.getString(R.string.error_status_code_400)); - ERROR_MESSAGE_ARRAY.append(401, resources.getString(R.string.error_status_code_401)); - ERROR_MESSAGE_ARRAY.append(402, resources.getString(R.string.error_status_code_402)); - ERROR_MESSAGE_ARRAY.append(403, resources.getString(R.string.error_status_code_403)); - ERROR_MESSAGE_ARRAY.append(404, resources.getString(R.string.error_status_code_404)); - ERROR_MESSAGE_ARRAY.append(405, resources.getString(R.string.error_status_code_405)); - ERROR_MESSAGE_ARRAY.append(406, resources.getString(R.string.error_status_code_406)); - ERROR_MESSAGE_ARRAY.append(407, resources.getString(R.string.error_status_code_407)); - ERROR_MESSAGE_ARRAY.append(408, resources.getString(R.string.error_status_code_408)); - ERROR_MESSAGE_ARRAY.append(409, resources.getString(R.string.error_status_code_409)); - ERROR_MESSAGE_ARRAY.append(410, resources.getString(R.string.error_status_code_410)); - ERROR_MESSAGE_ARRAY.append(411, resources.getString(R.string.error_status_code_411)); - ERROR_MESSAGE_ARRAY.append(412, resources.getString(R.string.error_status_code_412)); - ERROR_MESSAGE_ARRAY.append(413, resources.getString(R.string.error_status_code_413)); - ERROR_MESSAGE_ARRAY.append(414, resources.getString(R.string.error_status_code_414)); - ERROR_MESSAGE_ARRAY.append(415, resources.getString(R.string.error_status_code_415)); - ERROR_MESSAGE_ARRAY.append(416, resources.getString(R.string.error_status_code_416)); - ERROR_MESSAGE_ARRAY.append(417, resources.getString(R.string.error_status_code_417)); - - ERROR_MESSAGE_ARRAY.append(500, resources.getString(R.string.error_status_code_500)); - ERROR_MESSAGE_ARRAY.append(501, resources.getString(R.string.error_status_code_501)); - ERROR_MESSAGE_ARRAY.append(502, resources.getString(R.string.error_status_code_502)); - ERROR_MESSAGE_ARRAY.append(503, resources.getString(R.string.error_status_code_503)); - ERROR_MESSAGE_ARRAY.append(504, resources.getString(R.string.error_status_code_504)); - ERROR_MESSAGE_ARRAY.append(505, resources.getString(R.string.error_status_code_505)); - } - - public int getResponseCode() { - return mResponseCode; - } - - public boolean isIdentifiedResponseCode() { - return !DEFAULT_ERROR_MESSAGE.equals(mMessage); - } - - @Override - public String getMessage() { - return mMessage; - } - - @Override - public String getLocalizedMessage() { - return getMessage(); - } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/hippo/network/UrlBuilder.kt b/app/src/main/java/com/hippo/network/UrlBuilder.kt index 099d72c3b..9cab7a6ef 100644 --- a/app/src/main/java/com/hippo/network/UrlBuilder.kt +++ b/app/src/main/java/com/hippo/network/UrlBuilder.kt @@ -13,45 +13,32 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.hippo.network -package com.hippo.network; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -public class UrlBuilder { - - public String mRootUrl; - public Map mQueryMap = new HashMap<>(); - - public UrlBuilder(String rootUrl) { - mRootUrl = rootUrl; +class UrlBuilder(private var mRootUrl: String) { + private var mQueryMap: MutableMap = HashMap() + fun addQuery(key: String, value: Any) { + mQueryMap[key] = value } - public void addQuery(String key, Object value) { - mQueryMap.put(key, value); - } - - public String build() { - if (mQueryMap.size() == 0) { - return mRootUrl; + fun build(): String { + return if (mQueryMap.isEmpty()) { + mRootUrl } else { - StringBuilder sb = new StringBuilder(mRootUrl); - sb.append("?"); - - Iterator iter = mQueryMap.keySet().iterator(); + val sb = StringBuilder(mRootUrl) + sb.append("?") + val iter: Iterator = mQueryMap.keys.iterator() if (iter.hasNext()) { - String key = iter.next(); - Object value = mQueryMap.get(key); - sb.append(key).append("=").append(value); + val key = iter.next() + val value = mQueryMap[key] + sb.append(key).append("=").append(value) } while (iter.hasNext()) { - String key = iter.next(); - Object value = mQueryMap.get(key); - sb.append("&").append(key).append("=").append(value); + val key = iter.next() + val value = mQueryMap[key] + sb.append("&").append(key).append("=").append(value) } - return sb.toString(); + sb.toString() } } -} +} \ No newline at end of file