Remove token, use ETag to prevent multiple queries

This commit is contained in:
topjohnwu 2017-01-11 17:37:35 +08:00
parent 5363b0f810
commit 61e2c3444a
6 changed files with 60 additions and 51 deletions

View File

@ -4,7 +4,7 @@ import android.content.Context;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Logger; import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.WebRequest; import com.topjohnwu.magisk.utils.WebService;
import java.util.Date; import java.util.Date;
@ -22,7 +22,7 @@ public class Repo extends BaseModule {
public void update() throws CacheModException { public void update() throws CacheModException {
Logger.dev("Repo: Re-fetch prop"); Logger.dev("Repo: Re-fetch prop");
String props = WebRequest.makeWebServiceCall(mManifestUrl, WebRequest.GET, true); String props = WebService.request(mManifestUrl, WebService.GET, true);
String lines[] = props.split("\\n"); String lines[] = props.split("\\n");
parseProps(lines); parseProps(lines);
} }

View File

@ -56,7 +56,7 @@ public class Async {
@Override @Override
protected Void doInBackground(Void... voids) { protected Void doInBackground(Void... voids) {
String jsonStr = WebRequest.makeWebServiceCall(UPDATE_JSON, WebRequest.GET); String jsonStr = WebService.request(UPDATE_JSON, WebService.GET);
try { try {
JSONObject json = new JSONObject(jsonStr); JSONObject json = new JSONObject(jsonStr);
JSONObject magisk = json.getJSONObject("magisk"); JSONObject magisk = json.getJSONObject("magisk");

View File

@ -31,6 +31,7 @@ public class ModuleHelper {
private static final String FILE_KEY = "RepoMap"; private static final String FILE_KEY = "RepoMap";
private static final String REPO_KEY = "repomap"; private static final String REPO_KEY = "repomap";
private static final String VERSION_KEY = "version"; private static final String VERSION_KEY = "version";
private static final String ETAG_KEY = "ETag";
private static final int DATABASE_VER = 1; private static final int DATABASE_VER = 1;
private static ValueSortedMap<String, Repo> repoMap = new ValueSortedMap<>(); private static ValueSortedMap<String, Repo> repoMap = new ValueSortedMap<>();
@ -57,10 +58,11 @@ public class ModuleHelper {
public static void createRepoMap(Context context) { public static void createRepoMap(Context context) {
Logger.dev("ModuleHelper: Loading repos"); Logger.dev("ModuleHelper: Loading repos");
SharedPreferences prefs = context.getSharedPreferences(FILE_KEY, Context.MODE_PRIVATE);
repoMap.clear(); repoMap.clear();
Gson gson = new Gson(); Gson gson = new Gson();
SharedPreferences prefs = context.getSharedPreferences(FILE_KEY, Context.MODE_PRIVATE);
String jsonString; String jsonString;
int cachedVersion = prefs.getInt(VERSION_KEY, 0); int cachedVersion = prefs.getInt(VERSION_KEY, 0);
@ -74,20 +76,31 @@ public class ModuleHelper {
ValueSortedMap<String, Repo> cached = null; ValueSortedMap<String, Repo> cached = null;
if (jsonString != null) { if (jsonString != null) {
cached = gson.fromJson(jsonString, new TypeToken< ValueSortedMap<String, Repo> >(){}.getType()); cached = gson.fromJson(jsonString, new TypeToken<ValueSortedMap<String, Repo>>(){}.getType());
} }
if (cached == null) { if (cached == null) {
cached = new ValueSortedMap<>(); cached = new ValueSortedMap<>();
} }
// Making a request to url and getting response // Get cached ETag to add in the request header
jsonString = WebRequest.makeWebServiceCall(context.getString(R.string.url_main), WebRequest.GET); String etag = prefs.getString(ETAG_KEY, "");
HashMap<String, String> header = new HashMap<>();
header.put("If-None-Match", etag);
if (jsonString != null && !jsonString.isEmpty()) { // Making a request to main URL for repo info
// Have internet access jsonString = WebService.request(
context.getString(R.string.url_main), WebService.GET, null, header, false);
if (!jsonString.isEmpty()) {
try { try {
JSONArray jsonArray = new JSONArray(jsonString); JSONArray jsonArray = new JSONArray(jsonString);
// If it gets to this point, the response is valid, update ETag
etag = WebService.getLastResponseHeader().get(ETAG_KEY).get(0);
// Maybe bug in Android build tools, sometimes the ETag has crap in it...
etag = etag.substring(etag.indexOf('\"'), etag.lastIndexOf('\"') + 1);
// Update repo info
for (int i = 0; i < jsonArray.length(); i++) { for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonobject = jsonArray.getJSONObject(i); JSONObject jsonobject = jsonArray.getJSONObject(i);
String id = jsonobject.getString("description"); String id = jsonobject.getString("description");
@ -106,7 +119,7 @@ public class ModuleHelper {
Logger.dev("ModuleHelper: Create new repo " + id); Logger.dev("ModuleHelper: Create new repo " + id);
repo = new Repo(context, name, updatedDate); repo = new Repo(context, name, updatedDate);
} else { } else {
Logger.dev("ModuleHelper: Cached repo " + id); Logger.dev("ModuleHelper: Update cached repo " + id);
repo.update(updatedDate); repo.update(updatedDate);
} }
if (repo.getId() != null) { if (repo.getId() != null) {
@ -118,13 +131,15 @@ public class ModuleHelper {
e.printStackTrace(); e.printStackTrace();
} }
} else { } else {
// Use cached if no internet // Use cached if no internet or no updates
Logger.dev("ModuleHelper: No updates, use cached");
repoMap.putAll(cached); repoMap.putAll(cached);
} }
prefs.edit() prefs.edit()
.putInt(VERSION_KEY, DATABASE_VER) .putInt(VERSION_KEY, DATABASE_VER)
.putString(REPO_KEY, gson.toJson(repoMap)) .putString(REPO_KEY, gson.toJson(repoMap))
.putString(ETAG_KEY, etag)
.apply(); .apply();
Logger.dev("ModuleHelper: Repo load done"); Logger.dev("ModuleHelper: Repo load done");

View File

@ -10,7 +10,6 @@ import android.net.Uri;
import android.os.Environment; import android.os.Environment;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Base64;
import android.widget.Toast; import android.widget.Toast;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
@ -19,20 +18,8 @@ import com.topjohnwu.magisk.receivers.DownloadReceiver;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.List; import java.util.List;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class Utils { public class Utils {
public static boolean isDownloading = false; public static boolean isDownloading = false;

View File

@ -8,21 +8,17 @@ import java.io.OutputStreamWriter;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.HashMap; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
public class WebRequest { public class WebService {
static String response = null;
public final static int GET = 1; public final static int GET = 1;
public final static int POST = 2; public final static int POST = 2;
//Constructor with no parameter private static Map<String, List<String>> responseHeader;
public WebRequest() {
}
/** /**
* Making web service call * Making web service call
@ -30,15 +26,12 @@ public class WebRequest {
* @url - url to make request * @url - url to make request
* @requestmethod - http request method * @requestmethod - http request method
*/ */
public static String makeWebServiceCall(String url, int requestmethod) { public static String request(String url, int method) {
return makeWebServiceCall(url, requestmethod, null, false); return request(url, method, null, null, false);
} }
public static String makeWebServiceCall(String url, int requestmethod, boolean addNewLines) { public static String request(String url, int method, boolean newline) {
return makeWebServiceCall(url, requestmethod, null, addNewLines); return request(url, method, null, null, newline);
} }
/** /**
@ -47,26 +40,35 @@ public class WebRequest {
* @url - url to make request * @url - url to make request
* @requestmethod - http request method * @requestmethod - http request method
* @params - http request params * @params - http request params
* @header - http request header
* @newline - true to append a newline each line
*/ */
public static String makeWebServiceCall(String urladdress, int requestmethod, public static String request(String urlAddress, int method,
HashMap<String, String> params, boolean addNewLines) { Map<String, String> params, Map<String, String> header,
Logger.dev("WebRequest: Service call " + urladdress); boolean newline) {
Logger.dev("WebService: Service call " + urlAddress);
URL url; URL url;
String response = ""; StringBuilder response = new StringBuilder();
try { try {
url = new URL(urladdress); url = new URL(urlAddress);
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000); conn.setReadTimeout(15000);
conn.setConnectTimeout(15000); conn.setConnectTimeout(15000);
conn.setDoInput(true); conn.setDoInput(true);
if (requestmethod == POST) { if (method == POST) {
conn.setRequestMethod("POST"); conn.setRequestMethod("POST");
} else if (requestmethod == GET) { } else if (method == GET) {
conn.setRequestMethod("GET"); conn.setRequestMethod("GET");
} }
if (header != null) {
for (Map.Entry<String, String> entry : header.entrySet()) {
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
}
if (params != null) { if (params != null) {
OutputStream os = conn.getOutputStream(); OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter( BufferedWriter writer = new BufferedWriter(
@ -98,20 +100,25 @@ public class WebRequest {
String line; String line;
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = br.readLine()) != null) { while ((line = br.readLine()) != null) {
if (addNewLines) { if (newline) {
response += line + "\n"; response.append(line).append("\n");
} else { } else {
response += line; response.append(line);
} }
} }
responseHeader = conn.getHeaderFields();
} else { } else {
response = ""; responseHeader = null;
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return response; return response.toString();
}
public static Map<String, List<String>> getLastResponseHeader() {
return responseHeader;
} }
} }

View File

@ -111,7 +111,7 @@
<string name="check_release_notes">Check release notes</string> <string name="check_release_notes">Check release notes</string>
<!--URL Templates--> <!--URL Templates-->
<string name="url_main" translatable="false">https://api.github.com/orgs/Magisk-Modules-Repo/repos?access_token=8f3c379fbeb80754b45b02486482584893af142a</string> <string name="url_main" translatable="false">https://api.github.com/orgs/Magisk-Modules-Repo/repos</string>
<string name="file_url" translatable="false">https://raw.githubusercontent.com/Magisk-Modules-Repo/%1$s/master/%2$s</string> <string name="file_url" translatable="false">https://raw.githubusercontent.com/Magisk-Modules-Repo/%1$s/master/%2$s</string>
<string name="zip_url" translatable="false">https://github.com/Magisk-Modules-Repo/%1$s/archive/master.zip</string> <string name="zip_url" translatable="false">https://github.com/Magisk-Modules-Repo/%1$s/archive/master.zip</string>