Skip to content

Commit

Permalink
Switch to okhttp for http connections, use TLS1.2 on API<=21 (#5658)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikehardy authored and timrae committed Jan 30, 2020
1 parent 1c8eee7 commit d402073
Show file tree
Hide file tree
Showing 12 changed files with 351 additions and 308 deletions.
1 change: 0 additions & 1 deletion AnkiDroid/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ android {
buildConfigField "String", "ACRA_URL", '"https://ankidroid.org/acra/report"'
}
}
useLibrary 'org.apache.http.legacy'

testOptions {
animationsDisabled true
Expand Down
3 changes: 0 additions & 3 deletions AnkiDroid/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,6 @@
<uses-library
android:name="com.sec.android.app.multiwindow"
android:required="false" />
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />

<meta-data
android:name="com.sec.android.support.multiwindow"
Expand Down
12 changes: 6 additions & 6 deletions AnkiDroid/src/main/java/com/ichi2/async/Connection.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

import java.io.IOException;

import okhttp3.Response;
import timber.log.Timber;

public class Connection extends BaseAsyncTask<Connection.Payload, Object, Connection.Payload> {
Expand Down Expand Up @@ -199,12 +200,11 @@ private Payload doOneInBackground(Payload data) {
}


@SuppressWarnings("deprecation") // tracking HTTP transport change in github already
private Payload doInBackgroundLogin(Payload data) {
String username = (String) data.data[0];
String password = (String) data.data[1];
HttpSyncer server = new RemoteServer(this, null);
org.apache.http.HttpResponse ret;
Response ret;
try {
ret = server.hostKey(username, password);
} catch (UnknownHttpResponseException e) {
Expand All @@ -223,16 +223,16 @@ private Payload doInBackgroundLogin(Payload data) {
String hostkey = null;
boolean valid = false;
if (ret != null) {
data.returnType = ret.getStatusLine().getStatusCode();
Timber.d("doInBackgroundLogin - response from server: %d, (%s)", data.returnType, ret.getStatusLine().getReasonPhrase());
data.returnType = ret.code();
Timber.d("doInBackgroundLogin - response from server: %d, (%s)", data.returnType, ret.message());
if (data.returnType == 200) {
try {
JSONObject jo = (new JSONObject(server.stream2String(ret.getEntity().getContent())));
JSONObject jo = (new JSONObject(ret.body().string()));
hostkey = jo.getString("key");
valid = (hostkey != null) && (hostkey.length() > 0);
} catch (JSONException e) {
valid = false;
} catch (IllegalStateException | IOException e) {
} catch (IllegalStateException | IOException | NullPointerException e) {
throw new RuntimeException(e);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/****************************************************************************************
* Copyright (c) 2019 Mike Hardy <github@mikehardy.net> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
* Foundation; either version 3 of the License, or (at your option) any later *
* version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************/

package com.ichi2.libanki.sync;

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;


// Note that in current versions of OkHTTP this is unnecessary as they support
// Decorators / hooks more easily with the builder API, allowing upload transfer tracking
// without a separate object. I believe we will have to move to API21+ for that to be possible
public class CountingFileRequestBody extends RequestBody {

private static final int SEGMENT_SIZE = 2048; // okio.Segment.SIZE

private final File file;
private final ProgressListener listener;
private final String contentType;

public CountingFileRequestBody(File file, String contentType, ProgressListener listener) {
this.file = file;
this.contentType = contentType;
this.listener = listener;
}

@Override
public long contentLength() {
return file.length();
}

@Override
public MediaType contentType() {
return MediaType.parse(contentType);
}

@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(file);
long read;

while ((read = source.read(sink.buffer(), SEGMENT_SIZE)) != -1) {
sink.flush();
this.listener.transferred(read);
}
} finally {
Util.closeQuietly(source);
}
}

public interface ProgressListener {
void transferred(long num);
}
}
31 changes: 18 additions & 13 deletions AnkiDroid/src/main/java/com/ichi2/libanki/sync/FullSyncer.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
import java.util.HashMap;
import java.util.Locale;

import okhttp3.Response;
import okhttp3.ResponseBody;
import timber.log.Timber;

@SuppressWarnings({"PMD.AvoidThrowingRawExceptionTypes","PMD.NPathComplexity"})
Expand Down Expand Up @@ -73,19 +75,21 @@ public String syncURL() {


@Override
@SuppressWarnings("deprecation") // tracking HTTP transport change in github already
public Object[] download() throws UnknownHttpResponseException {
InputStream cont;
ResponseBody body = null;
try {
org.apache.http.HttpResponse ret = super.req("download");
if (ret == null) {
Response ret = super.req("download");
if (ret == null || ret.body() == null) {
return null;
}
cont = ret.getEntity().getContent();
} catch (IllegalStateException e1) {
body = ret.body();
cont = body.byteStream();
} catch (IllegalArgumentException e1) {
if (body != null) {
body.close();
}
throw new RuntimeException(e1);
} catch (IOException e1) {
return null;
}
String path;
if (mCol != null) {
Expand All @@ -111,6 +115,8 @@ public Object[] download() throws UnknownHttpResponseException {
} catch (IOException e) {
Timber.e(e, "Full sync failed to download collection.");
return new Object[] { "sdAccessError" };
} finally {
body.close();
}

// check the received file is ok
Expand Down Expand Up @@ -141,7 +147,6 @@ public Object[] download() throws UnknownHttpResponseException {


@Override
@SuppressWarnings("deprecation") // tracking HTTP transport change in github already
public Object[] upload() throws UnknownHttpResponseException {
// make sure it's ok before we try to upload
mCon.publishProgress(R.string.sync_check_upload_file);
Expand All @@ -154,19 +159,19 @@ public Object[] upload() throws UnknownHttpResponseException {
// apply some adjustments, then upload
mCol.beforeUpload();
String filePath = mCol.getPath();
org.apache.http.HttpResponse ret;
Response ret;
mCon.publishProgress(R.string.sync_uploading_message);
try {
ret = super.req("upload", new FileInputStream(filePath));
if (ret == null) {
if (ret == null || ret.body() == null) {
return null;
}
int status = ret.getStatusLine().getStatusCode();
int status = ret.code();
if (status != 200) {
// error occurred
return new Object[] { "error", status, ret.getStatusLine().getReasonPhrase() };
return new Object[] { "error", status, ret.message() };
} else {
return new Object[] { super.stream2String(ret.getEntity().getContent()) };
return new Object[] { ret.body().string() };
}
} catch (IllegalStateException | IOException e) {
throw new RuntimeException(e);
Expand Down
Loading

0 comments on commit d402073

Please sign in to comment.