From a65e192f0fb4388fc33d8e9bf1807ac540f3003d Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Mon, 12 Aug 2019 13:03:20 +0200 Subject: [PATCH] [JNI] Allow android to know that an article is a redirect. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Android need to handle the redirection by doing a redirection in the web view, not by providing the content of the targeted article. This is already what we do in kiwix-serve or ios. The API should be far better by returning a Entry but for now, we just change the given url if the article is a redirection. --- src/android/kiwixreader.cpp | 17 ++++++++++------- .../org/kiwix/kiwixlib/JNIKiwixReader.java | 16 +++++++++++++++- src/android/utils.h | 7 +++++++ 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/android/kiwixreader.cpp b/src/android/kiwixreader.cpp index 1196f82c5..91dcec78b 100644 --- a/src/android/kiwixreader.cpp +++ b/src/android/kiwixreader.cpp @@ -225,7 +225,7 @@ JNIEXPORT jstring JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getMimeType( } JNIEXPORT jbyteArray JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getContent( - JNIEnv* env, jobject obj, jstring url, jobject titleObj, jobject mimeTypeObj, jobject sizeObj) + JNIEnv* env, jobject obj, jobject url, jobject titleObj, jobject mimeTypeObj, jobject sizeObj) { /* Default values */ setStringObjValue("", titleObj, env); @@ -234,21 +234,24 @@ JNIEXPORT jbyteArray JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getContent( jbyteArray data = env->NewByteArray(0); /* Retrieve the content */ - std::string cUrl = jni2c(url, env); + std::string cUrl = getStringObjValue(url, env); unsigned int cSize = 0; try { auto entry = READER->getEntryFromEncodedPath(cUrl); + bool isRedirect = entry.isRedirect(); entry = entry.getFinalEntry(); cSize = entry.getSize(); setIntObjValue(cSize, sizeObj, env); - - data = env->NewByteArray(cSize); - env->SetByteArrayRegion( - data, 0, cSize, reinterpret_cast(entry.getBlob().data())); - setStringObjValue(entry.getMimetype(), mimeTypeObj, env); setStringObjValue(entry.getTitle(), titleObj, env); + if (isRedirect) { + setStringObjValue(entry.getPath(), url, env); + } else { + data = env->NewByteArray(cSize); + env->SetByteArrayRegion( + data, 0, cSize, reinterpret_cast(entry.getBlob().data())); + } } catch (std::exception& e) { __android_log_print(ANDROID_LOG_ERROR, "kiwix", "Unable to get content for url: %s", cUrl.c_str()); __android_log_print(ANDROID_LOG_ERROR, "kiwix", e.what()); diff --git a/src/android/org/kiwix/kiwixlib/JNIKiwixReader.java b/src/android/org/kiwix/kiwixlib/JNIKiwixReader.java index e405ef0f4..ea3a3d4b3 100644 --- a/src/android/org/kiwix/kiwixlib/JNIKiwixReader.java +++ b/src/android/org/kiwix/kiwixlib/JNIKiwixReader.java @@ -38,7 +38,21 @@ public class JNIKiwixReader public native String getMimeType(String url); - public native byte[] getContent(String url, + /** + * Get the content of a article. + * + * Return a byte array of the content of the article. + * Set the title, mimeType to the title and mimeType of the article. + * Set the size to the size of the returned array. + * + * If the entry doesn't exist : + * - return a empty byte array + * - set all arguments (except url) to empty/0. + * If the entry exist but is a redirection : + * - return an empty byte array + * - set all arguments (including url) to information of the targeted article. + */ + public native byte[] getContent(JNIKiwixString url, JNIKiwixString title, JNIKiwixString mimeType, JNIKiwixInt size); diff --git a/src/android/utils.h b/src/android/utils.h index 3c164e353..aeb5a4d35 100644 --- a/src/android/utils.h +++ b/src/android/utils.h @@ -114,6 +114,13 @@ inline std::string jni2c(const jstring& val, JNIEnv* env) inline int jni2c(const jint val) { return (int)val; } /* Method to deal with variable passed by reference */ +inline std::string getStringObjValue(const jobject obj, JNIEnv* env) +{ + jclass objClass = env->GetObjectClass(obj); + jfieldID objFid = env->GetFieldID(objClass, "value", "Ljava/lang/String;"); + jstring jstr = (jstring)env->GetObjectField(obj, objFid); + return jni2c(jstr, env); +} inline void setStringObjValue(const std::string& value, const jobject obj, JNIEnv* env)