diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c5f3f6b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c0d6ba4..420a672 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -43,8 +43,6 @@ android { excludes += "META-INF/ASL2.0" } } - - useLibrary("org.apache.http.legacy") } dependencies { @@ -52,9 +50,14 @@ dependencies { implementation(libs.material) implementation(libs.activity) implementation(libs.constraintlayout) - implementation("org.apache.httpcomponents:httpclient-android:4.3.5.1") { - exclude(group = "org.apache.httpcomponents", module = "httpcore") + + // OkHttp dependencies + implementation("com.squareup.okhttp3:okhttp:3.14.9") { + exclude(group = "org.bouncycastle", module = "bcprov-jdk15on") + exclude(group = "org.bouncycastle", module = "bcpkix-jdk15on") } + implementation("com.squareup.okio:okio:1.17.5") + testImplementation(libs.junit) androidTestImplementation(libs.ext.junit) androidTestImplementation(libs.espresso.core) diff --git a/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java b/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java index c67dfdf..9d7f0f9 100644 --- a/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java +++ b/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java @@ -32,20 +32,6 @@ import net.micode.notes.gtask.exception.NetworkFailureException; import net.micode.notes.tool.GTaskStringUtils; import net.micode.notes.ui.NotesPreferenceActivity; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.cookie.Cookie; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; -import org.apache.http.params.HttpProtocolParams; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -54,12 +40,25 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; import java.util.zip.GZIPInputStream; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.Cookie; +import okhttp3.CookieJar; +import okhttp3.FormBody; +import okhttp3.HttpUrl; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.ResponseBody; public class GTaskClient { private static final String TAG = GTaskClient.class.getSimpleName(); @@ -72,7 +71,7 @@ public class GTaskClient { private static GTaskClient mInstance = null; - private DefaultHttpClient mHttpClient; + private OkHttpClient mHttpClient; private String mGetUrl; @@ -91,7 +90,23 @@ public class GTaskClient { private JSONArray mUpdateArray; private GTaskClient() { - mHttpClient = null; + mHttpClient = new OkHttpClient.Builder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(15, TimeUnit.SECONDS) + .cookieJar(new CookieJar() { + private final List cookies = new ArrayList<>(); + + @Override + public void saveFromResponse(HttpUrl url, List cookies) { + this.cookies.addAll(cookies); + } + + @Override + public List loadForRequest(HttpUrl url) { + return cookies; + } + }) + .build(); mGetUrl = GTASK_GET_URL; mPostUrl = GTASK_POST_URL; mClientVersion = -1; @@ -228,26 +243,23 @@ public class GTaskClient { private boolean loginGtask(String authToken) { int timeoutConnection = 10000; int timeoutSocket = 15000; - HttpParams httpParameters = new BasicHttpParams(); - HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); - HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); - mHttpClient = new DefaultHttpClient(httpParameters); - BasicCookieStore localBasicCookieStore = new BasicCookieStore(); - mHttpClient.setCookieStore(localBasicCookieStore); - HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), false); + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.connectTimeout(timeoutConnection, TimeUnit.MILLISECONDS); + builder.readTimeout(timeoutSocket, TimeUnit.MILLISECONDS); + mHttpClient = builder.build(); // login gtask try { - String loginUrl = mGetUrl + "?auth=" + authToken; - HttpGet httpGet = new HttpGet(loginUrl); - HttpResponse response = null; - response = mHttpClient.execute(httpGet); + Request request = new Request.Builder() + .url(mGetUrl + "?auth=" + authToken) + .build(); + Response response = mHttpClient.newCall(request).execute(); // get the cookie now - List cookies = mHttpClient.getCookieStore().getCookies(); + List cookies = mHttpClient.cookieJar().loadForRequest(request.url()); boolean hasAuthCookie = false; for (Cookie cookie : cookies) { - if (cookie.getName().contains("GTL")) { + if (cookie.name().contains("GTL")) { hasAuthCookie = true; } } @@ -256,7 +268,7 @@ public class GTaskClient { } // get the client version - String resString = getResponseContent(response.getEntity()); + String resString = getResponseContent(response.body().byteStream()); String jsBegin = "_setup("; String jsEnd = ")}"; int begin = resString.indexOf(jsBegin); @@ -284,26 +296,27 @@ public class GTaskClient { return mActionId++; } - private HttpPost createHttpPost() { - HttpPost httpPost = new HttpPost(mPostUrl); - httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); - httpPost.setHeader("AT", "1"); - return httpPost; + private Request createRequest() { + Request.Builder builder = new Request.Builder() + .url(mPostUrl) + .addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8") + .addHeader("AT", "1"); + return builder.build(); } - private String getResponseContent(HttpEntity entity) throws IOException { + private String getResponseContent(InputStream inputStream) throws IOException { String contentEncoding = null; - if (entity.getContentEncoding() != null) { - contentEncoding = entity.getContentEncoding().getValue(); + if (inputStream != null) { + contentEncoding = inputStream.toString(); Log.d(TAG, "encoding: " + contentEncoding); } - InputStream input = entity.getContent(); + InputStream input = inputStream; if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) { - input = new GZIPInputStream(entity.getContent()); + input = new GZIPInputStream(inputStream); } else if (contentEncoding != null && contentEncoding.equalsIgnoreCase("deflate")) { Inflater inflater = new Inflater(true); - input = new InflaterInputStream(entity.getContent(), inflater); + input = new InflaterInputStream(inputStream, inflater); } try { @@ -329,22 +342,18 @@ public class GTaskClient { throw new ActionFailureException("not logged in"); } - HttpPost httpPost = createHttpPost(); + Request request = createRequest(); + RequestBody body = new FormBody.Builder() + .add("r", js.toString()) + .build(); + Request postRequest = request.newBuilder() + .post(body) + .build(); + try { - LinkedList list = new LinkedList(); - list.add(new BasicNameValuePair("r", js.toString())); - UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8"); - httpPost.setEntity(entity); - - // execute the post - HttpResponse response = mHttpClient.execute(httpPost); - String jsString = getResponseContent(response.getEntity()); + Response response = mHttpClient.newCall(postRequest).execute(); + String jsString = getResponseContent(response.body().byteStream()); return new JSONObject(jsString); - - } catch (ClientProtocolException e) { - Log.e(TAG, e.toString()); - e.printStackTrace(); - throw new NetworkFailureException("postRequest failed"); } catch (IOException e) { Log.e(TAG, e.toString()); e.printStackTrace(); @@ -516,12 +525,13 @@ public class GTaskClient { } try { - HttpGet httpGet = new HttpGet(mGetUrl); - HttpResponse response = null; - response = mHttpClient.execute(httpGet); + Request request = new Request.Builder() + .url(mGetUrl) + .build(); + Response response = mHttpClient.newCall(request).execute(); // get the task list - String resString = getResponseContent(response.getEntity()); + String resString = getResponseContent(response.body().byteStream()); String jsBegin = "_setup("; String jsEnd = ")}"; int begin = resString.indexOf(jsBegin); @@ -532,10 +542,6 @@ public class GTaskClient { } JSONObject js = new JSONObject(jsString); return js.getJSONObject("t").getJSONArray(GTaskStringUtils.GTASK_JSON_LISTS); - } catch (ClientProtocolException e) { - Log.e(TAG, e.toString()); - e.printStackTrace(); - throw new NetworkFailureException("gettasklists: httpget failed"); } catch (IOException e) { Log.e(TAG, e.toString()); e.printStackTrace(); diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..22d0adf --- /dev/null +++ b/app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file