use of com.ichi2.anki.exception.UnknownHttpResponseException in project AnkiChinaAndroid by ankichinateam.
the class FullSyncer method upload.
@Override
public Object[] upload(long restSpace) throws UnknownHttpResponseException, NoEnoughServerSpaceException {
// make sure it's ok before we try to upload
mCon.publishProgress(R.string.sync_check_upload_file);
if (!"ok".equalsIgnoreCase(mCol.getDb().queryString("PRAGMA integrity_check"))) {
return new Object[] { "dbError" };
}
if (!mCol.basicCheck()) {
return new Object[] { "dbError" };
}
// apply some adjustments, then upload
mCol.beforeUpload();
String filePath = mCol.getPath();
double totalSize = FileUtil.getFileOrFilesSize(filePath, FileUtil.SIZETYPE_B);
Timber.i("full sync path size:%f", totalSize);
if (restSpace < totalSize && Consts.loginAnkiChina()) {
throw new NoEnoughServerSpaceException(restSpace, (long) totalSize);
}
Response ret;
mCon.publishProgress(R.string.sync_uploading_message);
try {
ret = super.req("upload", new FileInputStream(filePath));
if (ret == null || ret.body() == null) {
return null;
}
int status = ret.code();
if (status != 200) {
// error occurred
return new Object[] { "error", status, ret.message() };
} else {
return new Object[] { ret.body().string() };
}
} catch (IllegalStateException | IOException e) {
throw new RuntimeException(e);
}
}
use of com.ichi2.anki.exception.UnknownHttpResponseException in project AnkiChinaAndroid by ankichinateam.
the class FullSyncer method download.
@Override
public Object[] download() throws UnknownHttpResponseException {
InputStream cont;
ResponseBody body = null;
try {
Response ret = super.req("download");
if (ret == null || ret.body() == null) {
return null;
}
body = ret.body();
cont = body.byteStream();
} catch (IllegalArgumentException e1) {
if (body != null) {
body.close();
}
throw new RuntimeException(e1);
}
String path;
if (mCol != null) {
Timber.i("Closing collection for full sync");
// Usual case where collection is non-null
path = mCol.getPath();
mCol.close();
mCol = null;
} else {
// Allow for case where collection is completely unreadable
Timber.w("Collection was unexpectedly null when doing full sync download");
path = CollectionHelper.getCollectionPath(AnkiDroidApp.getInstance());
}
String tpath = path + ".tmp";
try {
super.writeToFile(cont, tpath);
Timber.d("Full Sync - Downloaded temp file");
FileInputStream fis = new FileInputStream(tpath);
if ("upgradeRequired".equals(super.stream2String(fis, 15))) {
Timber.w("Full Sync - 'Upgrade Required' message received");
return new Object[] { "upgradeRequired" };
}
} catch (FileNotFoundException e) {
Timber.e(e, "Failed to create temp file when downloading collection.");
throw new RuntimeException(e);
} 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
mCon.publishProgress(R.string.sync_check_download_file);
DB tempDb = null;
try {
tempDb = new DB(tpath);
if (!"ok".equalsIgnoreCase(tempDb.queryString("PRAGMA integrity_check"))) {
Timber.e("Full sync - downloaded file corrupt");
return new Object[] { "remoteDbError" };
}
} catch (SQLiteDatabaseCorruptException e) {
Timber.e("Full sync - downloaded file corrupt");
return new Object[] { "remoteDbError" };
} finally {
if (tempDb != null) {
tempDb.close();
}
}
Timber.d("Full Sync: Downloaded file was not corrupt");
// overwrite existing collection
File newFile = new File(tpath);
if (newFile.renameTo(new File(path))) {
Timber.i("Full Sync Success: Overwritten collection with downloaded file");
return new Object[] { "success" };
} else {
Timber.w("Full Sync: Error overwriting collection with downloaded file");
return new Object[] { "overwriteError" };
}
}
use of com.ichi2.anki.exception.UnknownHttpResponseException in project Anki-Android by ankidroid.
the class HttpSyncer method req.
/**
* Note: Return value must be closed
*/
@SuppressWarnings("CharsetObjectCanBeUsed")
public Response req(String method, InputStream fobj, int comp) throws UnknownHttpResponseException {
File tmpFileBuffer = null;
try {
String bdry = "--" + BOUNDARY;
StringWriter buf = new StringWriter();
// post vars
mPostVars.put("c", comp != 0 ? 1 : 0);
for (Map.Entry<String, Object> entry : mPostVars.entrySet()) {
buf.write(bdry + "\r\n");
buf.write(String.format(Locale.US, "Content-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", entry.getKey(), entry.getValue()));
}
tmpFileBuffer = File.createTempFile("syncer", ".tmp", new File(AnkiDroidApp.getCacheStorageDirectory()));
FileOutputStream fos = new FileOutputStream(tmpFileBuffer);
BufferedOutputStream bos = new BufferedOutputStream(fos);
GZIPOutputStream tgt;
// payload as raw data or json
if (fobj != null) {
// header
buf.write(bdry + "\r\n");
buf.write("Content-Disposition: form-data; name=\"data\"; filename=\"data\"\r\nContent-Type: application/octet-stream\r\n\r\n");
buf.close();
bos.write(buf.toString().getBytes("UTF-8"));
// write file into buffer, optionally compressing
int len;
BufferedInputStream bfobj = new BufferedInputStream(fobj);
byte[] chunk = new byte[65536];
if (comp != 0) {
tgt = new GZIPOutputStream(bos);
while ((len = bfobj.read(chunk)) >= 0) {
tgt.write(chunk, 0, len);
}
tgt.close();
bos = new BufferedOutputStream(new FileOutputStream(tmpFileBuffer, true));
} else {
while ((len = bfobj.read(chunk)) >= 0) {
bos.write(chunk, 0, len);
}
}
bos.write(("\r\n" + bdry + "--\r\n").getBytes("UTF-8"));
} else {
buf.close();
bos.write(buf.toString().getBytes("UTF-8"));
bos.write((bdry + "--\r\n").getBytes("UTF-8"));
}
bos.flush();
bos.close();
// connection headers
String url = Uri.parse(syncURL()).buildUpon().appendPath(method).toString();
Request.Builder requestBuilder = new Request.Builder();
requestBuilder.url(parseUrl(url));
// Set our request up to count upstream traffic including headers
requestBuilder.post(new CountingFileRequestBody(tmpFileBuffer, ANKI_POST_TYPE.toString(), num -> {
bytesSent.addAndGet(num);
publishProgress();
}));
Request httpPost = requestBuilder.build();
bytesSent.addAndGet(httpPost.headers().byteCount());
publishProgress();
try {
OkHttpClient httpClient = getHttpClient();
Response httpResponse = httpClient.newCall(httpPost).execute();
// we assume badAuthRaises flag from Anki Desktop always False
// so just throw new RuntimeException if response code not 200 or 403
Timber.d("TLSVersion in use is: %s", (httpResponse.handshake() != null ? httpResponse.handshake().tlsVersion() : "unknown"));
// Count downstream traffic including headers
bytesReceived.addAndGet(httpResponse.headers().byteCount());
try {
bytesReceived.addAndGet(httpResponse.body().contentLength());
} catch (NullPointerException npe) {
Timber.d(npe, "Unexpected null response body");
}
publishProgress();
assertOk(httpResponse);
return httpResponse;
} catch (SSLException e) {
Timber.e(e, "SSLException while building HttpClient");
throw new RuntimeException("SSLException while building HttpClient", e);
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
} catch (IOException e) {
Timber.e(e, "BasicHttpSyncer.sync: IOException");
throw new RuntimeException(e);
} finally {
if (tmpFileBuffer != null && tmpFileBuffer.exists()) {
tmpFileBuffer.delete();
}
}
}
use of com.ichi2.anki.exception.UnknownHttpResponseException in project Anki-Android by ankidroid.
the class RemoteMediaServer method begin.
public JSONObject begin() throws UnknownHttpResponseException, MediaSyncException {
try {
mPostVars = HashUtil.HashMapInit(2);
mPostVars.put("k", mHKey);
mPostVars.put("v", String.format(Locale.US, "ankidroid,%s,%s", VersionUtils.getPkgVersionName(), Utils.platDesc()));
Response resp = super.req("begin", HttpSyncer.getInputStream(Utils.jsonToString(new JSONObject())));
JSONObject jresp = new JSONObject(resp.body().string());
JSONObject ret = _dataOnly(jresp, JSONObject.class);
mSKey = ret.getString("sk");
return ret;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
use of com.ichi2.anki.exception.UnknownHttpResponseException in project Anki-Android by ankidroid.
the class RemoteMediaServer method downloadFiles.
/**
* args: files
* <br>
* This method returns a ZipFile with the OPEN_DELETE flag, ensuring that the file on disk will
* be automatically deleted when the stream is closed.
*/
public ZipFile downloadFiles(List<String> top) throws UnknownHttpResponseException {
Response resp = null;
try {
resp = super.req("downloadFiles", HttpSyncer.getInputStream(Utils.jsonToString(new JSONObject().put("files", new JSONArray(top)))));
String zipPath = mCol.getPath().replaceFirst("collection\\.anki2$", "tmpSyncFromServer.zip");
// retrieve contents and save to file on disk:
super.writeToFile(resp.body().byteStream(), zipPath);
return new ZipFile(new File(zipPath), ZipFile.OPEN_READ | ZipFile.OPEN_DELETE);
} catch (IOException | NullPointerException e) {
Timber.e(e, "Failed to download requested media files");
throw new RuntimeException(e);
} finally {
if (resp != null && resp.body() != null) {
resp.body().close();
}
}
}
Aggregations