Search in sources :

Example 6 with UnknownHttpResponseException

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);
    }
}
Also used : Response(okhttp3.Response) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) NoEnoughServerSpaceException(com.ichi2.anki.exception.NoEnoughServerSpaceException)

Example 7 with UnknownHttpResponseException

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" };
    }
}
Also used : FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) FileNotFoundException(java.io.FileNotFoundException) SQLiteDatabaseCorruptException(android.database.sqlite.SQLiteDatabaseCorruptException) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) ResponseBody(okhttp3.ResponseBody) Response(okhttp3.Response) File(java.io.File) DB(com.ichi2.libanki.DB)

Example 8 with UnknownHttpResponseException

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();
        }
    }
}
Also used : BufferedInputStream(java.io.BufferedInputStream) Uri(android.net.Uri) HashMap(java.util.HashMap) Random(java.util.Random) BufferedOutputStream(java.io.BufferedOutputStream) HttpFetcher(com.ichi2.anki.web.HttpFetcher) ByteArrayInputStream(java.io.ByteArrayInputStream) Locale(java.util.Locale) Map(java.util.Map) Connection(com.ichi2.async.Connection) Response(okhttp3.Response) Utils(com.ichi2.libanki.Utils) MediaType(okhttp3.MediaType) OutputStream(java.io.OutputStream) Request(okhttp3.Request) HashUtil(com.ichi2.utils.HashUtil) StringWriter(java.io.StringWriter) FileOutputStream(java.io.FileOutputStream) CustomSyncServer(com.ichi2.anki.web.CustomSyncServer) IOException(java.io.IOException) UnknownHttpResponseException(com.ichi2.anki.exception.UnknownHttpResponseException) JSONObject(com.ichi2.utils.JSONObject) InputStreamReader(java.io.InputStreamReader) File(java.io.File) Timber(timber.log.Timber) AtomicLong(java.util.concurrent.atomic.AtomicLong) SSLException(javax.net.ssl.SSLException) Nullable(androidx.annotation.Nullable) OkHttpClient(okhttp3.OkHttpClient) SharedPreferences(android.content.SharedPreferences) AnkiDroidApp(com.ichi2.anki.AnkiDroidApp) Consts(com.ichi2.libanki.Consts) GZIPOutputStream(java.util.zip.GZIPOutputStream) BufferedReader(java.io.BufferedReader) HttpUrl(okhttp3.HttpUrl) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InputStream(java.io.InputStream) OkHttpClient(okhttp3.OkHttpClient) Request(okhttp3.Request) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) SSLException(javax.net.ssl.SSLException) Response(okhttp3.Response) StringWriter(java.io.StringWriter) GZIPOutputStream(java.util.zip.GZIPOutputStream) BufferedInputStream(java.io.BufferedInputStream) FileOutputStream(java.io.FileOutputStream) JSONObject(com.ichi2.utils.JSONObject) File(java.io.File) HashMap(java.util.HashMap) Map(java.util.Map) BufferedOutputStream(java.io.BufferedOutputStream)

Example 9 with UnknownHttpResponseException

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);
    }
}
Also used : Response(okhttp3.Response) JSONObject(com.ichi2.utils.JSONObject) IOException(java.io.IOException)

Example 10 with UnknownHttpResponseException

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();
        }
    }
}
Also used : Response(okhttp3.Response) JSONObject(com.ichi2.utils.JSONObject) ZipFile(java.util.zip.ZipFile) JSONArray(com.ichi2.utils.JSONArray) IOException(java.io.IOException) File(java.io.File) ZipFile(java.util.zip.ZipFile)

Aggregations

IOException (java.io.IOException)23 JSONObject (com.ichi2.utils.JSONObject)22 Response (okhttp3.Response)20 UnknownHttpResponseException (com.ichi2.anki.exception.UnknownHttpResponseException)8 NoEnoughServerSpaceException (com.ichi2.anki.exception.NoEnoughServerSpaceException)7 File (java.io.File)7 JSONException (com.ichi2.utils.JSONException)6 FileInputStream (java.io.FileInputStream)6 MediaSyncException (com.ichi2.anki.exception.MediaSyncException)5 HostNum (com.ichi2.libanki.sync.HostNum)5 RemoteServer (com.ichi2.libanki.sync.RemoteServer)5 HttpSyncer (com.ichi2.libanki.sync.HttpSyncer)4 ZipFile (java.util.zip.ZipFile)4 JSONArray (com.ichi2.utils.JSONArray)3 FileNotFoundException (java.io.FileNotFoundException)3 InputStream (java.io.InputStream)3 SharedPreferences (android.content.SharedPreferences)2 SQLiteDatabaseCorruptException (android.database.sqlite.SQLiteDatabaseCorruptException)2 Uri (android.net.Uri)2 Pair (android.util.Pair)2