已关闭
【ArkWeb】WebviewController API接口适配 Web组件属性和事件接口适配 #282
quguiren创建于 2025年10月13日关闭于 2025年10月16日
【ArkWeb】WebviewController API接口适配 Web组件属性和事件接口适配 #282
已关闭
共 22 个文件变更+3392-11
| @@ -59,6 +59,7 @@ Note:If the text contains special characters, please escape them according to th | |||
| 59 | <policyitem type="license" name="BSD-3-Clause" path=".*" desc="不影响兼容性"/> | 59 | <policyitem type="license" name="BSD-3-Clause" path=".*" desc="不影响兼容性"/> |
| 60 | <policyitem type="license" name="curl" path="net/http/ios/curl_slist.cpp" desc="不影响兼容性"/> | 60 | <policyitem type="license" name="curl" path="net/http/ios/curl_slist.cpp" desc="不影响兼容性"/> |
| 61 | <policyitem type="license" name="curl" path="net/http/ios/curl_slist.h" desc="不影响兼容性"/> | 61 | <policyitem type="license" name="curl" path="net/http/ios/curl_slist.h" desc="不影响兼容性"/> |
| 62 | + <policyitem type="copyright" name="Huawei Technologies Co., Ltd." path=".*" desc="copyright"/> | ||
| 62 | </policy> | 63 | </policy> |
| 63 | </policylist> | 64 | </policylist> |
| 64 | <filefilterlist> | 65 | <filefilterlist> |
| @@ -28,6 +28,8 @@ template("plugin_web_webview_static") { | |||
| 28 | "//commomlibrary/c_utils/base/include", | 28 | "//commomlibrary/c_utils/base/include", |
| 29 | "//plugins/interfaces/native", | 29 | "//plugins/interfaces/native", |
| 30 | ] | 30 | ] |
| 31 | + include_dirs += | ||
| 32 | + [ "//foundation/arkui/ace_engine/adapter/ios/capability/web/" ] | ||
| 31 | 33 | ||
| 32 | sources = web_source | 34 | sources = web_source |
| 33 | sources += [ | 35 | sources += [ |
| @@ -36,12 +38,14 @@ template("plugin_web_webview_static") { | |||
| 36 | "js_web_webview.cpp", | 38 | "js_web_webview.cpp", |
| 37 | "napi_parse_utils.cpp", | 39 | "napi_parse_utils.cpp", |
| 38 | "napi_web_message_ext.cpp", | 40 | "napi_web_message_ext.cpp", |
| 41 | + "napi_web_scheme_handler_request.cpp", | ||
| 39 | "web_cookie_manager.cpp", | 42 | "web_cookie_manager.cpp", |
| 40 | "web_cookie_manager_callback.cpp", | 43 | "web_cookie_manager_callback.cpp", |
| 41 | "web_download_delegate.cpp", | 44 | "web_download_delegate.cpp", |
| 42 | "web_download_item.cpp", | 45 | "web_download_item.cpp", |
| 43 | "web_download_manager.cpp", | 46 | "web_download_manager.cpp", |
| 44 | "web_message_port.cpp", | 47 | "web_message_port.cpp", |
| 48 | + "web_scheme_handler_request.cpp", | ||
| 45 | "web_storage.cpp", | 49 | "web_storage.cpp", |
| 46 | "web_storage_callback.cpp", | 50 | "web_storage_callback.cpp", |
| 47 | "webview_async_work_callback.cpp", | 51 | "webview_async_work_callback.cpp", |
| @@ -14,6 +14,14 @@ | |||
| 14 | import("//build/ohos.gni") | 14 | import("//build/ohos.gni") |
| 15 | import("//plugins/web/webview/web_webview.gni") | 15 | import("//plugins/web/webview/web_webview.gni") |
| 16 | 16 | ||
| 17 | +java_library("android_asset_android_java") { | ||
| 18 | + java_files = [ | ||
| 19 | + "src/ohos/ace/plugin/webviewplugin/androidasset/AndroidAssetPlugin.java", | ||
| 20 | + ] | ||
| 21 | + subsystem_name = "plugins" | ||
| 22 | + part_name = "web_webview" | ||
| 23 | +} | ||
| 24 | + | ||
| 17 | java_library("cookie_manager_android_java") { | 25 | java_library("cookie_manager_android_java") { |
| 18 | java_files = | 26 | java_files = |
| 19 | [ "src/ohos/ace/plugin/webviewplugin/webcookie/WebCookiePlugin.java" ] | 27 | [ "src/ohos/ace/plugin/webviewplugin/webcookie/WebCookiePlugin.java" ] |
| @@ -30,6 +38,7 @@ java_library("web_storage_android_java") { | |||
| 30 | 38 | ||
| 31 | ohos_combine_jars("web_webview_java") { | 39 | ohos_combine_jars("web_webview_java") { |
| 32 | deps = [ | 40 | deps = [ |
| 41 | + ":android_asset_android_java", | ||
| 33 | ":cookie_manager_android_java", | 42 | ":cookie_manager_android_java", |
| 34 | ":web_storage_android_java", | 43 | ":web_storage_android_java", |
| 35 | ] | 44 | ] |
| @@ -40,6 +49,7 @@ ohos_combine_jars("web_webview_java") { | |||
| 40 | 49 | ||
| 41 | ohos_source_set("web_webview_android_jni") { | 50 | ohos_source_set("web_webview_android_jni") { |
| 42 | sources = [ | 51 | sources = [ |
| 52 | + "jni/android_asset_helper_jni.cpp", | ||
| 43 | "jni/geolocation_permissions_android.cpp", | 53 | "jni/geolocation_permissions_android.cpp", |
| 44 | "jni/geolocation_permissions_jni.cpp", | 54 | "jni/geolocation_permissions_jni.cpp", |
| 45 | "jni/web_cookie_manager_android.cpp", | 55 | "jni/web_cookie_manager_android.cpp", |
| @@ -50,6 +60,7 @@ ohos_source_set("web_webview_android_jni") { | |||
| 50 | "jni/web_download_item_jni.cpp", | 60 | "jni/web_download_item_jni.cpp", |
| 51 | "jni/web_download_manager_android.cpp", | 61 | "jni/web_download_manager_android.cpp", |
| 52 | "jni/web_message_port_android.cpp", | 62 | "jni/web_message_port_android.cpp", |
| 63 | + "jni/web_scheme_handler_jni.cpp", | ||
| 53 | "jni/web_storage_android.cpp", | 64 | "jni/web_storage_android.cpp", |
| 54 | "jni/web_storage_jni.cpp", | 65 | "jni/web_storage_jni.cpp", |
| 55 | "jni/webview_controller_android.cpp", | 66 | "jni/webview_controller_android.cpp", |
| @@ -0,0 +1,85 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +namespace OHOS::Plugin { | ||
| 25 | +namespace { | ||
| 26 | +const char WEB_WEBVIEW_CLASS_NAME[] = "ohos/ace/plugin/webviewplugin/androidasset/AndroidAssetPlugin"; | ||
| 27 | + | ||
| 28 | +static const JNINativeMethod METHODS[] = { | ||
| 29 | + { "nativeInit", "()V", reinterpret_cast<void*>(AndroidAssetHelperJni::NativeInit) }, | ||
| 30 | +}; | ||
| 31 | +static const char METHOD_EXISTS_VIRTUAL_ASSET[] = "existsVirtualAsset"; | ||
| 32 | + | ||
| 33 | +static const char SIGNATURE_EXISTS_VIRTUAL_ASSET[] = "(Ljava/lang/String;)Z"; | ||
| 34 | +struct { | ||
| 35 | + jmethodID existsVirtualAsset; | ||
| 36 | + jobject globalRef; | ||
| 37 | +} g_webWebviewClass; | ||
| 38 | +} // namespace | ||
| 39 | + | ||
| 40 | +bool AndroidAssetHelperJni::Register(void* env) | ||
| 41 | +{ | ||
| 42 | + auto* jniEnv = static_cast<JNIEnv*>(env); | ||
| 43 | + CHECK_NULL_RETURN(jniEnv, false); | ||
| 44 | + jclass cls = jniEnv->FindClass(WEB_WEBVIEW_CLASS_NAME); | ||
| 45 | + CHECK_NULL_RETURN(cls, false); | ||
| 46 | + bool ret = jniEnv->RegisterNatives(cls, METHODS, sizeof(METHODS) / sizeof(METHODS[0])) == 0; | ||
| 47 | + jniEnv->DeleteLocalRef(cls); | ||
| 48 | + if (!ret) { | ||
| 49 | + LOGE("AndroidAssetHelperJni JNI: RegisterNatives fail."); | ||
| 50 | + } | ||
| 51 | + return ret; | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +void AndroidAssetHelperJni::NativeInit(JNIEnv* env, jobject jobj) | ||
| 55 | +{ | ||
| 56 | + CHECK_NULL_VOID(env); | ||
| 57 | + g_webWebviewClass.globalRef = env->NewGlobalRef(jobj); | ||
| 58 | + CHECK_NULL_VOID(g_webWebviewClass.globalRef); | ||
| 59 | + jclass cls = env->GetObjectClass(jobj); | ||
需要调用DeleteLocalRef接口释放? ![]() ![]() | |||
| 60 | + CHECK_NULL_VOID(cls); | ||
| 61 | + g_webWebviewClass.existsVirtualAsset = env->GetMethodID(cls, METHOD_EXISTS_VIRTUAL_ASSET, | ||
| 62 | + SIGNATURE_EXISTS_VIRTUAL_ASSET); | ||
| 63 | + env->DeleteLocalRef(cls); | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +bool AndroidAssetHelperJni::ExistsVirtualAsset(const std::string& url) | ||
| 67 | +{ | ||
| 68 | + auto env = ARKUI_X_Plugin_GetJniEnv(); | ||
| 69 | + if (!(env) || !(g_webWebviewClass.globalRef) || !(g_webWebviewClass.existsVirtualAsset)) { | ||
| 70 | + LOGE("AndroidAssetHelperJni JNI: call ExistsVirtualAsset env fail"); | ||
| 71 | + return false; | ||
异常场景,增加日志,方便问题定位。 ![]() ![]() | |||
| 72 | + } | ||
| 73 | + jstring jUrl = env->NewStringUTF(url.c_str()); | ||
| 74 | + CHECK_NULL_RETURN(jUrl, false); | ||
| 75 | + jboolean isExists = env->CallBooleanMethod(g_webWebviewClass.globalRef, g_webWebviewClass.existsVirtualAsset, | ||
| 76 | + jUrl); | ||
| 77 | + if (env->ExceptionCheck()) { | ||
| 78 | + LOGE("AndroidAssetHelperJni JNI: call ExistsVirtualAsset has exception"); | ||
| 79 | + env->ExceptionDescribe(); | ||
| 80 | + env->ExceptionClear(); | ||
| 81 | + } | ||
| 82 | + env->DeleteLocalRef(jUrl); | ||
| 83 | + return isExists; | ||
| 84 | +} | ||
| 85 | +} // namespace OHOS::Plugin | ||
| @@ -0,0 +1,33 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | +namespace OHOS::Plugin { | ||
| 23 | +class AndroidAssetHelperJni final { | ||
| 24 | +public: | ||
| 25 | + AndroidAssetHelperJni() = delete; | ||
| 26 | + ~AndroidAssetHelperJni() = delete; | ||
| 27 | + static bool Register(void* env); | ||
| 28 | + static void NativeInit(JNIEnv* env, jobject jobj); | ||
| 29 | + static bool ExistsVirtualAsset(const std::string& url); | ||
| 30 | +}; | ||
| 31 | +} // namespace OHOS::Plugin | ||
| 32 | + | ||
| 33 | + | ||
| @@ -0,0 +1,596 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace OHOS::Plugin { | ||
| 26 | +static constexpr const int PARAM_COUNT_ZERO = 0; | ||
| 27 | +static constexpr const int PARAM_COUNT_ONE = 1; | ||
| 28 | +static constexpr const int PARAM_COUNT_TWO = 2; | ||
| 29 | +static constexpr const int PARAM_COUNT_THREE = 3; | ||
| 30 | +static constexpr const int PARAM_COUNT_FOUR = 4; | ||
| 31 | +std::map<std::string, ArkWeb_SchemeHandler*> WebSchemeHandlerJni::g_schemeRequestHandlerMap_; | ||
| 32 | +ArkWeb_SchemeHandler* WebSchemeHandlerJni::handler_ = nullptr; | ||
| 33 | +ArkWeb_ResourceRequest* WebSchemeHandlerJni::resourceRequest_ = nullptr; | ||
| 34 | +bool WebSchemeHandlerJni::isIntercept_ = false; | ||
| 35 | +namespace { | ||
| 36 | +const char WEB_WEBVIEW_CLASS_NAME[] = "ohos/ace/adapter/capability/web/AceWebPluginBase"; | ||
| 37 | +static const JNINativeMethod METHODS[] = { | ||
| 38 | + { "nativeInitSchemeHandler", "()V", reinterpret_cast<void*>(WebSchemeHandlerJni::NativeInit) }, | ||
| 39 | + { "onSchemeHandlerRequestStart", "(Ljava/lang/String;Ljava/lang/Object;)Z", | ||
| 40 | + reinterpret_cast<void*>(WebSchemeHandlerJni::OnSchemeHandlerRequestStart) }, | ||
| 41 | + { "onSchemeHandlerRequestStop", "(Ljava/lang/String;Ljava/lang/Object;)V", | ||
| 42 | + reinterpret_cast<void*>(WebSchemeHandlerJni::OnSchemeHandlerRequestStop) }, | ||
| 43 | +}; | ||
| 44 | + | ||
| 45 | +struct { | ||
| 46 | + jobject globalRef; | ||
| 47 | +} g_webWebviewClass; | ||
g_webWebviewClass这个类需要么? ![]() ![]() | |||
| 48 | +} // namespace | ||
| 49 | + | ||
| 50 | +bool WebSchemeHandlerJni::Register(void* env) | ||
| 51 | +{ | ||
| 52 | + auto* jniEnv = static_cast<JNIEnv*>(env); | ||
| 53 | + CHECK_NULL_RETURN(jniEnv, false); | ||
| 54 | + jclass cls = jniEnv->FindClass(WEB_WEBVIEW_CLASS_NAME); | ||
| 55 | + CHECK_NULL_RETURN(cls, false); | ||
| 56 | + bool ret = jniEnv->RegisterNatives(cls, METHODS, sizeof(METHODS) / sizeof(METHODS[0])) == 0; | ||
| 57 | + jniEnv->DeleteLocalRef(cls); | ||
| 58 | + if (!ret) { | ||
| 59 | + LOGE("WebSchemeHandlerJni JNI: RegisterNatives fail."); | ||
| 60 | + return false; | ||
| 61 | + } | ||
| 62 | + return true; | ||
| 63 | +} | ||
| 64 | + | ||
| 65 | +void WebSchemeHandlerJni::NativeInit(JNIEnv* env, jobject jobj) | ||
| 66 | +{ | ||
| 67 | + CHECK_NULL_VOID(env); | ||
| 68 | +} | ||
| 69 | + | ||
| 70 | +std::string WebSchemeHandlerJni::GetUTFString(JNIEnv* env, jstring jstr) | ||
| 71 | +{ | ||
| 72 | + CHECK_NULL_RETURN(env, ""); | ||
| 73 | + CHECK_NULL_RETURN(jstr, ""); | ||
| 74 | + const char* pString = env->GetStringUTFChars(jstr, nullptr); | ||
| 75 | + CHECK_NULL_RETURN(pString, ""); | ||
| 76 | + std::string str(pString); | ||
| 77 | + env->ReleaseStringUTFChars(jstr, pString); | ||
| 78 | + return str; | ||
| 79 | +} | ||
| 80 | + | ||
| 81 | +bool WebSchemeHandlerJni::OnSchemeHandlerRequestStart( | ||
| 82 | + JNIEnv* env, jclass jcls, jstring scheme, jobject schemeRequestHandler) | ||
| 83 | +{ | ||
| 84 | + CHECK_NULL_RETURN(env, false); | ||
| 85 | + CHECK_NULL_RETURN(scheme, false); | ||
| 86 | + std::string strScheme = WebSchemeHandlerJni::GetUTFString(env, scheme); | ||
| 87 | + auto it = g_schemeRequestHandlerMap_.find(strScheme); | ||
| 88 | + if (it == g_schemeRequestHandlerMap_.end()) { | ||
| 89 | + LOGE("WebSchemeHandlerJni::OnSchemeHandlerRequestStart: No handler found for scheme %{public}s", | ||
| 90 | + strScheme.c_str()); | ||
| 91 | + return false; | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + handler_ = it->second; | ||
| 95 | + CHECK_NULL_RETURN(handler_, false); | ||
| 96 | + bool intercept = false; | ||
| 97 | + if (handler_->on_request_start != nullptr) { | ||
| 98 | + resourceRequest_ = CreateArkResourceRequest(env, schemeRequestHandler); | ||
| 99 | + CHECK_NULL_RETURN(resourceRequest_, false); | ||
| 100 | + ArkWeb_ResourceHandler* resourceHandler = new (std::nothrow) ArkWeb_ResourceHandler(env, schemeRequestHandler); | ||
| 101 | + CHECK_NULL_RETURN(resourceHandler, false); | ||
| 102 | + handler_->on_request_start(handler_, resourceRequest_, resourceHandler, &intercept); | ||
| 103 | + SetIsIntercept(intercept); | ||
| 104 | + DestroyArkResourceRequest(resourceRequest_); | ||
| 105 | + delete resourceHandler; | ||
| 106 | + resourceHandler = nullptr; | ||
| 107 | + } | ||
| 108 | + return intercept; | ||
| 109 | +} | ||
| 110 | + | ||
| 111 | +void WebSchemeHandlerJni::OnSchemeHandlerRequestStop( | ||
| 112 | + JNIEnv* env, jclass jcls, jstring scheme, jobject schemeRequestHandler) | ||
| 113 | +{ | ||
| 114 | + CHECK_NULL_VOID(env); | ||
| 115 | + CHECK_NULL_VOID(scheme); | ||
| 116 | + std::string strScheme = WebSchemeHandlerJni::GetUTFString(env, scheme); | ||
| 117 | + auto it = g_schemeRequestHandlerMap_.find(strScheme); | ||
| 118 | + if (it == g_schemeRequestHandlerMap_.end()) { | ||
| 119 | + LOGE("WebSchemeHandlerJni::OnSchemeHandlerRequestStop: No handler found for scheme %{public}s", | ||
| 120 | + strScheme.c_str()); | ||
| 121 | + return; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + handler_ = it->second; | ||
| 125 | + CHECK_NULL_VOID(handler_); | ||
| 126 | + if (handler_->on_request_stop != nullptr) { | ||
| 127 | + resourceRequest_ = CreateArkResourceRequest(env, schemeRequestHandler); | ||
| 128 | + CHECK_NULL_VOID(resourceRequest_); | ||
| 129 | + handler_->on_request_stop(handler_, resourceRequest_); | ||
| 130 | + DestroyArkResourceRequest(resourceRequest_); | ||
| 131 | + } | ||
| 132 | +} | ||
| 133 | + | ||
| 134 | +template<typename T> | ||
| 135 | +static bool IsNullAndRelease(T obj, ArkWeb_ResourceRequest*& request) | ||
| 136 | +{ | ||
| 137 | + if (obj == nullptr) { | ||
| 138 | + if (request != nullptr) { | ||
| 139 | + delete request; | ||
| 140 | + request = nullptr; | ||
| 141 | + } | ||
| 142 | + return true; | ||
| 143 | + } | ||
| 144 | + return false; | ||
| 145 | +} | ||
| 146 | + | ||
| 147 | +bool WebSchemeHandlerJni::GetStringFromJava(JNIEnv* env, jclass clazz, jobject jobj, ArkWeb_ResourceRequest*& request, | ||
| 148 | + const char* methodName, std::string& outStr) | ||
| 149 | +{ | ||
| 150 | + jmethodID methodId = env->GetMethodID(clazz, methodName, "()Ljava/lang/String;"); | ||
| 151 | + if (IsNullAndRelease(methodId, request)) { | ||
| 152 | + return false; | ||
| 153 | + } | ||
| 154 | + jstring jstr = static_cast<jstring>(env->CallObjectMethod(jobj, methodId)); | ||
| 155 | + if (IsNullAndRelease(jstr, request)) { | ||
| 156 | + return false; | ||
| 157 | + } | ||
| 158 | + outStr = WebSchemeHandlerJni::GetUTFString(env, jstr); | ||
| 159 | + env->DeleteLocalRef(jstr); | ||
| 160 | + return true; | ||
| 161 | +} | ||
| 162 | + | ||
| 163 | +bool WebSchemeHandlerJni::GetBooleanFromJava(JNIEnv* env, jclass clazz, jobject jobj, ArkWeb_ResourceRequest*& request, | ||
| 164 | + const char* methodName, bool& outBool) | ||
| 165 | +{ | ||
| 166 | + jmethodID methodId = env->GetMethodID(clazz, methodName, "()Z"); | ||
| 167 | + if (IsNullAndRelease(methodId, request)) { | ||
| 168 | + return false; | ||
| 169 | + } | ||
| 170 | + outBool = static_cast<bool>(env->CallBooleanMethod(jobj, methodId)); | ||
| 171 | + return true; | ||
| 172 | +} | ||
| 173 | + | ||
| 174 | +ArkWeb_ResourceRequest* WebSchemeHandlerJni::CreateArkResourceRequest(JNIEnv* env, jobject jRequest) | ||
| 175 | +{ | ||
| 176 | + CHECK_NULL_RETURN(env, nullptr); | ||
| 177 | + ArkWeb_ResourceRequest* request = new (std::nothrow) ArkWeb_ResourceRequest(); | ||
| 178 | + CHECK_NULL_RETURN(request, nullptr); | ||
| 179 | + jclass schemeRequestClass = env->GetObjectClass(jRequest); | ||
| 180 | + if (IsNullAndRelease(schemeRequestClass, request)) { | ||
| 181 | + return nullptr; | ||
L return 前要释放request,不然泄漏 ![]() ![]() liuxiao_310 2025年10月13日 评论: 2025年10月13日 评论: | |||
| 182 | + } | ||
| 183 | + if (!GetStringFromJava(env, schemeRequestClass, jRequest, request, "getRequestUrl", request->url_)) { | ||
| 184 | + return nullptr; | ||
| 185 | + } | ||
| 186 | + if (!GetStringFromJava(env, schemeRequestClass, jRequest, request, "getMethod", request->method_)) { | ||
| 187 | + return nullptr; | ||
| 188 | + } | ||
| 189 | + if (!GetBooleanFromJava(env, schemeRequestClass, jRequest, request, "isRequestGesture", request->hasGesture_)) { | ||
| 190 | + return nullptr; | ||
| 191 | + } | ||
| 192 | + if (!GetBooleanFromJava(env, schemeRequestClass, jRequest, request, "isMainFrame", request->isMainFrame_)) { | ||
| 193 | + return nullptr; | ||
| 194 | + } | ||
| 195 | + if (!GetBooleanFromJava(env, schemeRequestClass, jRequest, request, "isRedirect", request->isRedirect_)) { | ||
| 196 | + return nullptr; | ||
| 197 | + } | ||
| 198 | + jmethodID getRequestHeaderId = env->GetMethodID(schemeRequestClass, "getRequestHeader", "()Ljava/util/Map;"); | ||
| 199 | + if (IsNullAndRelease(getRequestHeaderId, request)) { | ||
| 200 | + return nullptr; | ||
| 201 | + } | ||
| 202 | + jobject jHeadersMap = env->CallObjectMethod(jRequest, getRequestHeaderId); | ||
| 203 | + if (IsNullAndRelease(jHeadersMap, request)) { | ||
| 204 | + return nullptr; | ||
| 205 | + } | ||
| 206 | + std::map<std::string, std::string> headers = GetRequestHeader(env, jHeadersMap); | ||
| 207 | + request->headerList_ = WebHeaderList(headers.begin(), headers.end()); | ||
| 208 | + if (env->ExceptionCheck()) { | ||
| 209 | + env->ExceptionDescribe(); | ||
| 210 | + env->ExceptionClear(); | ||
| 211 | + } | ||
| 212 | + return request; | ||
| 213 | +} | ||
| 214 | + | ||
| 215 | +void WebSchemeHandlerJni::DestroyArkResourceRequest(ArkWeb_ResourceRequest* request) | ||
| 216 | +{ | ||
| 217 | + if (request != nullptr) { | ||
| 218 | + delete request; | ||
| 219 | + request = nullptr; | ||
| 220 | + } | ||
| 221 | +} | ||
| 222 | + | ||
| 223 | +void WebSchemeHandlerJni::IterateAndFillHeaders(JNIEnv* env, jobject iterator, const jmethodID* methodIds, | ||
| 224 | + std::map<std::string, std::string>& headers) | ||
| 225 | +{ | ||
| 226 | + while (env->CallBooleanMethod(iterator, methodIds[PARAM_COUNT_ZERO])) { | ||
| 227 | + jobject entry = env->CallObjectMethod(iterator, methodIds[PARAM_COUNT_ONE]); | ||
| 228 | + jobject key = env->CallObjectMethod(entry, methodIds[PARAM_COUNT_TWO]); | ||
| 229 | + jobject value = env->CallObjectMethod(entry, methodIds[PARAM_COUNT_THREE]); | ||
| 230 | + if (key != nullptr && value != nullptr) { | ||
| 231 | + const char* keyStr = env->GetStringUTFChars(static_cast<jstring>(key), nullptr); | ||
建议在转换前使用使用 env->IsInstanceOf等方式检查对象类型,避免导致GetStringUTFChars调用时崩溃 ![]() ![]() | |||
| 232 | + const char* valueStr = env->GetStringUTFChars(static_cast<jstring>(value), nullptr); | ||
| 233 | + if (keyStr != nullptr && valueStr != nullptr) { | ||
| 234 | + headers[keyStr] = valueStr; | ||
| 235 | + } | ||
| 236 | + if (keyStr != nullptr) { | ||
| 237 | + env->ReleaseStringUTFChars(static_cast<jstring>(key), keyStr); | ||
| 238 | + } | ||
| 239 | + if (valueStr != nullptr) { | ||
| 240 | + env->ReleaseStringUTFChars(static_cast<jstring>(value), valueStr); | ||
| 241 | + } | ||
| 242 | + } | ||
| 243 | + env->DeleteLocalRef(key); | ||
| 244 | + env->DeleteLocalRef(value); | ||
| 245 | + env->DeleteLocalRef(entry); | ||
| 246 | + } | ||
| 247 | +} | ||
| 248 | + | ||
| 249 | +bool WebSchemeHandlerJni::GetIteratorAndEntryMethodIds( | ||
| 250 | + JNIEnv* env, jclass iteratorClass, jclass entryClass, jmethodID* methodIds) | ||
| 251 | +{ | ||
| 252 | + if (methodIds == nullptr) { | ||
| 253 | + return false; | ||
| 254 | + } | ||
| 255 | + methodIds[PARAM_COUNT_ZERO] = env->GetMethodID(iteratorClass, "hasNext", "()Z"); | ||
数组下标访问前,先进行数组大小判断。 ![]() ![]() | |||
| 256 | + methodIds[PARAM_COUNT_ONE] = env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;"); | ||
| 257 | + methodIds[PARAM_COUNT_TWO] = env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;"); | ||
| 258 | + methodIds[PARAM_COUNT_THREE] = env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;"); | ||
| 259 | + return (methodIds[PARAM_COUNT_ZERO] != nullptr) && (methodIds[PARAM_COUNT_ONE] != nullptr) && | ||
| 260 | + (methodIds[PARAM_COUNT_TWO] != nullptr) && (methodIds[PARAM_COUNT_THREE] != nullptr); | ||
| 261 | +} | ||
| 262 | + | ||
| 263 | +std::map<std::string, std::string> WebSchemeHandlerJni::GetRequestHeader(JNIEnv* env, jobject jHeadersMap) | ||
| 264 | +{ | ||
| 265 | + std::map<std::string, std::string> headers; | ||
| 266 | + CHECK_NULL_RETURN(env, headers); | ||
| 267 | + CHECK_NULL_RETURN(jHeadersMap, headers); | ||
| 268 | + jobject iterator = WebSchemeHandlerJni::GetHeaderIterator(env, jHeadersMap); | ||
| 269 | + CHECK_NULL_RETURN(iterator, headers); | ||
| 270 | + | ||
| 271 | + jclass iteratorClass = env->FindClass("java/util/Iterator"); | ||
| 272 | + jclass entryClass = env->FindClass("java/util/Map$Entry"); | ||
| 273 | + if (iteratorClass == nullptr || entryClass == nullptr) { | ||
| 274 | + env->DeleteLocalRef(iterator); | ||
| 275 | + env->DeleteLocalRef(iteratorClass); | ||
| 276 | + env->DeleteLocalRef(entryClass); | ||
| 277 | + return headers; | ||
| 278 | + } | ||
| 279 | + | ||
| 280 | + jmethodID methodIds[PARAM_COUNT_FOUR] = { nullptr }; | ||
| 281 | + if (GetIteratorAndEntryMethodIds(env, iteratorClass, entryClass, methodIds)) { | ||
| 282 | + IterateAndFillHeaders(env, iterator, methodIds, headers); | ||
| 283 | + } | ||
| 284 | + | ||
| 285 | + if (env->ExceptionCheck()) { | ||
| 286 | + env->ExceptionDescribe(); | ||
| 287 | + env->ExceptionClear(); | ||
| 288 | + } | ||
| 289 | + env->DeleteLocalRef(iterator); | ||
| 290 | + env->DeleteLocalRef(iteratorClass); | ||
| 291 | + env->DeleteLocalRef(entryClass); | ||
| 292 | + return headers; | ||
| 293 | +} | ||
| 294 | + | ||
| 295 | +jobject WebSchemeHandlerJni::GetHeaderIterator(JNIEnv* env, jobject jHeadersMap) | ||
| 296 | +{ | ||
| 297 | + CHECK_NULL_RETURN(env, nullptr); | ||
| 298 | + CHECK_NULL_RETURN(jHeadersMap, nullptr); | ||
| 299 | + jclass mapClass = env->FindClass("java/util/Map"); | ||
| 300 | + CHECK_NULL_RETURN(mapClass, nullptr); | ||
| 301 | + jmethodID entrySetId = env->GetMethodID(mapClass, "entrySet", "()Ljava/util/Set;"); | ||
| 302 | + if (entrySetId == nullptr) { | ||
| 303 | + env->DeleteLocalRef(mapClass); | ||
| 304 | + return nullptr; | ||
| 305 | + } | ||
| 306 | + jobject entrySet = env->CallObjectMethod(jHeadersMap, entrySetId); | ||
| 307 | + if (entrySet == nullptr) { | ||
| 308 | + env->DeleteLocalRef(mapClass); | ||
| 309 | + return nullptr; | ||
| 310 | + } | ||
| 311 | + | ||
| 312 | + jclass setClass = env->FindClass("java/util/Set"); | ||
| 313 | + if (setClass == nullptr) { | ||
| 314 | + env->DeleteLocalRef(entrySet); | ||
| 315 | + env->DeleteLocalRef(mapClass); | ||
| 316 | + return nullptr; | ||
| 317 | + } | ||
| 318 | + jmethodID iteratorId = env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;"); | ||
| 319 | + if (iteratorId == nullptr) { | ||
| 320 | + env->DeleteLocalRef(entrySet); | ||
| 321 | + env->DeleteLocalRef(mapClass); | ||
| 322 | + env->DeleteLocalRef(setClass); | ||
| 323 | + return nullptr; | ||
| 324 | + } | ||
| 325 | + jobject iterator = env->CallObjectMethod(entrySet, iteratorId); | ||
| 326 | + env->DeleteLocalRef(entrySet); | ||
| 327 | + env->DeleteLocalRef(mapClass); | ||
| 328 | + env->DeleteLocalRef(setClass); | ||
| 329 | + return iterator; | ||
| 330 | +} | ||
| 331 | + | ||
| 332 | +ArkWeb_SchemeHandler* WebSchemeHandlerJni::CreateArkSchemeHandler() | ||
| 333 | +{ | ||
| 334 | + ArkWeb_SchemeHandler* handler = new (std::nothrow) ArkWeb_SchemeHandler(); | ||
| 335 | + return handler; | ||
| 336 | +} | ||
| 337 | + | ||
| 338 | +void WebSchemeHandlerJni::DeleteArkSchemeHandler(ArkWeb_SchemeHandler* handler) | ||
| 339 | +{ | ||
| 340 | + if (handler != nullptr) { | ||
| 341 | + delete handler; | ||
| 342 | + handler = nullptr; | ||
| 343 | + } | ||
| 344 | +} | ||
| 345 | + | ||
| 346 | +void WebSchemeHandlerJni::SetOnRequestStart(ArkWeb_SchemeHandler* handler, ArkWeb_OnRequestStart callback) | ||
| 347 | +{ | ||
| 348 | + if (handler != nullptr) { | ||
| 349 | + handler->on_request_start = callback; | ||
| 350 | + } | ||
| 351 | +} | ||
| 352 | + | ||
| 353 | +void WebSchemeHandlerJni::SetOnRequestStop(ArkWeb_SchemeHandler* handler, ArkWeb_OnRequestStop callback) | ||
| 354 | +{ | ||
| 355 | + if (handler != nullptr) { | ||
| 356 | + handler->on_request_stop = callback; | ||
| 357 | + } | ||
| 358 | +} | ||
| 359 | + | ||
| 360 | +void WebSchemeHandlerJni::InsertSchemeRequestHandler(std::string& scheme, ArkWeb_SchemeHandler* handler) | ||
| 361 | +{ | ||
| 362 | + if (!scheme.empty() && handler != nullptr) { | ||
| 363 | + g_schemeRequestHandlerMap_[scheme] = handler; | ||
| 364 | + } | ||
| 365 | +} | ||
| 366 | + | ||
| 367 | +void WebSchemeHandlerJni::ClearSchemeRequestHandler() | ||
| 368 | +{ | ||
| 369 | + g_schemeRequestHandlerMap_.clear(); | ||
| 370 | +} | ||
| 371 | + | ||
| 372 | +bool WebSchemeHandlerJni::GetIsIntercept() | ||
| 373 | +{ | ||
| 374 | + return isIntercept_; | ||
| 375 | +} | ||
| 376 | + | ||
| 377 | +void WebSchemeHandlerJni::SetIsIntercept(bool intercept) | ||
| 378 | +{ | ||
| 379 | + isIntercept_ = intercept; | ||
| 380 | +} | ||
| 381 | + | ||
| 382 | +ErrCode ArkWeb_ResourceHandler::SetResponseUrl(const std::string& url) | ||
| 383 | +{ | ||
| 384 | + CHECK_NULL_RETURN(env_, NWebError::PARAM_CHECK_ERROR); | ||
| 385 | + CHECK_NULL_RETURN(schemeRequestHandler_, NWebError::PARAM_CHECK_ERROR); | ||
| 386 | + jclass schemeRequestClass = env_->GetObjectClass(schemeRequestHandler_); | ||
| 387 | + CHECK_NULL_RETURN(schemeRequestClass, NWebError::PARAM_CHECK_ERROR); | ||
| 388 | + jmethodID setResponseUrlMethod = env_->GetMethodID(schemeRequestClass, "setResponseUrl", "(Ljava/lang/String;)V"); | ||
| 389 | + CHECK_NULL_RETURN(setResponseUrlMethod, NWebError::PARAM_CHECK_ERROR); | ||
| 390 | + jstring jsUrl = env_->NewStringUTF(url.c_str()); | ||
| 391 | + CHECK_NULL_RETURN(jsUrl, NWebError::PARAM_CHECK_ERROR); | ||
| 392 | + env_->CallVoidMethod(schemeRequestHandler_, setResponseUrlMethod, jsUrl); | ||
| 393 | + ErrCode ret = NWebError::NO_ERROR; | ||
| 394 | + if (env_->ExceptionCheck()) { | ||
| 395 | + env_->ExceptionDescribe(); | ||
| 396 | + env_->ExceptionClear(); | ||
| 397 | + ret = NWebError::PARAM_CHECK_ERROR; | ||
| 398 | + } | ||
| 399 | + env_->DeleteLocalRef(jsUrl); | ||
| 400 | + return ret; | ||
| 401 | +} | ||
| 402 | + | ||
| 403 | +ErrCode ArkWeb_ResourceHandler::SetResponseErrcode(ArkWeb_NetError errorCode, const std::string& errorDescription) | ||
| 404 | +{ | ||
| 405 | + CHECK_NULL_RETURN(env_, NWebError::PARAM_CHECK_ERROR); | ||
| 406 | + CHECK_NULL_RETURN(schemeRequestHandler_, NWebError::PARAM_CHECK_ERROR); | ||
| 407 | + jclass schemeRequestClass = env_->GetObjectClass(schemeRequestHandler_); | ||
| 408 | + CHECK_NULL_RETURN(schemeRequestClass, NWebError::PARAM_CHECK_ERROR); | ||
| 409 | + jmethodID setResponseErrorMethod = | ||
| 410 | + env_->GetMethodID(schemeRequestClass, "setResponseFail", "(ILjava/lang/String;)V"); | ||
| 411 | + CHECK_NULL_RETURN(setResponseErrorMethod, NWebError::PARAM_CHECK_ERROR); | ||
| 412 | + jstring jsErrorDescription = env_->NewStringUTF(errorDescription.c_str()); | ||
| 413 | + CHECK_NULL_RETURN(jsErrorDescription, NWebError::PARAM_CHECK_ERROR); | ||
| 414 | + env_->CallVoidMethod( | ||
| 415 | + schemeRequestHandler_, setResponseErrorMethod, static_cast<jint>(errorCode), jsErrorDescription); | ||
| 416 | + ErrCode ret = NWebError::NO_ERROR; | ||
| 417 | + if (env_->ExceptionCheck()) { | ||
| 418 | + env_->ExceptionDescribe(); | ||
| 419 | + env_->ExceptionClear(); | ||
| 420 | + ret = NWebError::PARAM_CHECK_ERROR; | ||
| 421 | + } | ||
| 422 | + env_->DeleteLocalRef(jsErrorDescription); | ||
| 423 | + return ret; | ||
| 424 | +} | ||
| 425 | + | ||
| 426 | +ErrCode ArkWeb_ResourceHandler::DidReceiveResponse(const ArkWeb_Response* response) | ||
| 427 | +{ | ||
| 428 | + CHECK_NULL_RETURN(response, NWebError::PARAM_CHECK_ERROR); | ||
| 429 | + CHECK_NULL_RETURN(env_, NWebError::PARAM_CHECK_ERROR); | ||
| 430 | + CHECK_NULL_RETURN(schemeRequestHandler_, NWebError::PARAM_CHECK_ERROR); | ||
| 431 | + jclass schemeRequestClass = env_->GetObjectClass(schemeRequestHandler_); | ||
| 432 | + CHECK_NULL_RETURN(schemeRequestClass, NWebError::PARAM_CHECK_ERROR); | ||
| 433 | + if (SetResponseUrl(response->url_) != NWebError::NO_ERROR) { | ||
| 434 | + return NWebError::PARAM_CHECK_ERROR; | ||
| 435 | + } | ||
| 436 | + | ||
| 437 | + if (SetResponseErrcode(static_cast<ArkWeb_NetError>(response->errorCode_), response->errorDescription_) != | ||
| 438 | + NWebError::NO_ERROR) { | ||
| 439 | + return NWebError::PARAM_CHECK_ERROR; | ||
| 440 | + } | ||
| 441 | + jmethodID setResponseMethod = env_->GetMethodID(schemeRequestClass, "setResponse", | ||
| 442 | + "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/util/HashMap;Ljava/lang/String;)V"); | ||
| 443 | + CHECK_NULL_RETURN(setResponseMethod, NWebError::PARAM_CHECK_ERROR); | ||
| 444 | + jstring jsMimeType = env_->NewStringUTF(response->mimeType_.c_str()); | ||
| 445 | + CHECK_NULL_RETURN(jsMimeType, NWebError::PARAM_CHECK_ERROR); | ||
| 446 | + jstring jsEncoding = env_->NewStringUTF(response->encoding_.c_str()); | ||
| 447 | + if (jsEncoding == nullptr) { | ||
| 448 | + env_->DeleteLocalRef(jsMimeType); | ||
| 449 | + return NWebError::PARAM_CHECK_ERROR; | ||
| 450 | + } | ||
| 451 | + jstring jsReasonPhrase = env_->NewStringUTF(response->statusText_.c_str()); | ||
| 452 | + jstring jsData = env_->NewStringUTF(response->data_.c_str()); | ||
| 453 | + if (jsReasonPhrase == nullptr || jsData == nullptr) { | ||
| 454 | + env_->DeleteLocalRef(jsMimeType); | ||
| 455 | + env_->DeleteLocalRef(jsEncoding); | ||
| 456 | + if (jsReasonPhrase != nullptr) { | ||
| 457 | + env_->DeleteLocalRef(jsReasonPhrase); | ||
| 458 | + } | ||
| 459 | + return NWebError::PARAM_CHECK_ERROR; | ||
| 460 | + } | ||
| 461 | + jobject headers = ConvertMapToJavaMap(env_, response->headers_); | ||
headers 也需要通过DeleteLocalRef释放,否则有内存泄漏 ![]() ![]() | |||
| 462 | + env_->CallVoidMethod(schemeRequestHandler_, setResponseMethod, jsMimeType, jsEncoding, response->status_, | ||
| 463 | + jsReasonPhrase, headers, jsData); | ||
| 464 | + env_->DeleteLocalRef(jsMimeType); | ||
| 465 | + env_->DeleteLocalRef(jsEncoding); | ||
| 466 | + env_->DeleteLocalRef(jsReasonPhrase); | ||
| 467 | + env_->DeleteLocalRef(jsData); | ||
| 468 | + env_->DeleteLocalRef(headers); | ||
| 469 | + if (env_->ExceptionCheck()) { | ||
| 470 | + env_->ExceptionDescribe(); | ||
| 471 | + env_->ExceptionClear(); | ||
| 472 | + } | ||
| 473 | + return NWebError::NO_ERROR; | ||
| 474 | +} | ||
| 475 | + | ||
| 476 | +jobject ArkWeb_ResourceHandler::ConvertMapToJavaMap( | ||
| 477 | + JNIEnv* env, const std::unordered_map<std::string, std::string>& headersMap) | ||
| 478 | +{ | ||
| 479 | + CHECK_NULL_RETURN(env, nullptr); | ||
| 480 | + jclass hashMapClass = env->FindClass("java/util/HashMap"); | ||
| 481 | + CHECK_NULL_RETURN(hashMapClass, nullptr); | ||
| 482 | + jmethodID hashMapConstructor = env->GetMethodID(hashMapClass, "<init>", "()V"); | ||
| 483 | + jmethodID hashMapPut = | ||
| 484 | + env->GetMethodID(hashMapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); | ||
| 485 | + if (hashMapConstructor == nullptr || hashMapPut == nullptr) { | ||
| 486 | + env->DeleteLocalRef(hashMapClass); | ||
| 487 | + return nullptr; | ||
| 488 | + } | ||
| 489 | + jobject hashMap = env->NewObject(hashMapClass, hashMapConstructor); | ||
| 490 | + for (const auto& entry : headersMap) { | ||
| 491 | + jstring key = env->NewStringUTF(entry.first.c_str()); | ||
| 492 | + jstring value = env->NewStringUTF(entry.second.c_str()); | ||
| 493 | + env->CallObjectMethod(hashMap, hashMapPut, key, value); | ||
| 494 | + env->DeleteLocalRef(key); | ||
| 495 | + env->DeleteLocalRef(value); | ||
| 496 | + } | ||
| 497 | + env->DeleteLocalRef(hashMapClass); | ||
| 498 | + return hashMap; | ||
| 499 | +} | ||
| 500 | + | ||
| 501 | +ErrCode ArkWeb_ResourceHandler::DidReceiveData(const uint8_t* buffer, int64_t buflen) | ||
| 502 | +{ | ||
| 503 | + CHECK_NULL_RETURN(buffer, NWebError::PARAM_CHECK_ERROR); | ||
| 504 | + CHECK_NULL_RETURN(buflen > 0, NWebError::PARAM_CHECK_ERROR); | ||
| 505 | + CHECK_NULL_RETURN(env_, NWebError::PARAM_CHECK_ERROR); | ||
| 506 | + CHECK_NULL_RETURN(schemeRequestHandler_, NWebError::PARAM_CHECK_ERROR); | ||
| 507 | + std::string data(reinterpret_cast<const char*>(buffer), static_cast<size_t>(buflen)); | ||
| 508 | + jclass schemeRequestClass = env_->GetObjectClass(schemeRequestHandler_); | ||
| 509 | + CHECK_NULL_RETURN(schemeRequestClass, NWebError::PARAM_CHECK_ERROR); | ||
| 510 | + | ||
| 511 | + jmethodID setResponseDataMethod = env_->GetMethodID(schemeRequestClass, "setResponseData", "(Ljava/lang/String;)V"); | ||
| 512 | + CHECK_NULL_RETURN(setResponseDataMethod, NWebError::PARAM_CHECK_ERROR); | ||
| 513 | + jstring jsResponseData = env_->NewStringUTF(data.c_str()); | ||
| 514 | + CHECK_NULL_RETURN(jsResponseData, NWebError::PARAM_CHECK_ERROR); | ||
| 515 | + env_->CallVoidMethod(schemeRequestHandler_, setResponseDataMethod, jsResponseData); | ||
| 516 | + ErrCode ret = NWebError::NO_ERROR; | ||
| 517 | + if (env_->ExceptionCheck()) { | ||
| 518 | + env_->ExceptionDescribe(); | ||
| 519 | + env_->ExceptionClear(); | ||
| 520 | + ret = NWebError::PARAM_CHECK_ERROR; | ||
| 521 | + } | ||
| 522 | + env_->DeleteLocalRef(jsResponseData); | ||
| 523 | + return ret; | ||
| 524 | +} | ||
| 525 | + | ||
| 526 | +ErrCode ArkWeb_ResourceHandler::DidFinish() | ||
| 527 | +{ | ||
| 528 | + CHECK_NULL_RETURN(env_, NWebError::PARAM_CHECK_ERROR); | ||
| 529 | + CHECK_NULL_RETURN(schemeRequestHandler_, NWebError::PARAM_CHECK_ERROR); | ||
| 530 | + | ||
| 531 | + jclass schemeRequestClass = env_->GetObjectClass(schemeRequestHandler_); | ||
| 532 | + CHECK_NULL_RETURN(schemeRequestClass, NWebError::PARAM_CHECK_ERROR); | ||
| 533 | + | ||
| 534 | + jmethodID setResponseFinishMethod = env_->GetMethodID(schemeRequestClass, "setResponseFinish", "(Z)V"); | ||
| 535 | + CHECK_NULL_RETURN(setResponseFinishMethod, NWebError::PARAM_CHECK_ERROR); | ||
| 536 | + SetFinishFlag(); | ||
| 537 | + env_->CallVoidMethod(schemeRequestHandler_, setResponseFinishMethod, isFinished_); | ||
| 538 | + ErrCode ret = NWebError::NO_ERROR; | ||
| 539 | + if (env_->ExceptionCheck()) { | ||
| 540 | + env_->ExceptionDescribe(); | ||
| 541 | + env_->ExceptionClear(); | ||
| 542 | + ret = NWebError::PARAM_CHECK_ERROR; | ||
| 543 | + } | ||
| 544 | + return ret; | ||
| 545 | +} | ||
| 546 | + | ||
| 547 | +ErrCode ArkWeb_ResourceHandler::DidFailWithError( | ||
| 548 | + ArkWeb_NetError errorCode, const std::string& errorDescription, bool completeIfNoResponse) | ||
| 549 | +{ | ||
| 550 | + CHECK_NULL_RETURN(env_, NWebError::PARAM_CHECK_ERROR); | ||
| 551 | + CHECK_NULL_RETURN(schemeRequestHandler_, NWebError::PARAM_CHECK_ERROR); | ||
| 552 | + | ||
| 553 | + jclass schemeRequestClass = env_->GetObjectClass(schemeRequestHandler_); | ||
| 554 | + CHECK_NULL_RETURN(schemeRequestClass, NWebError::PARAM_CHECK_ERROR); | ||
| 555 | + | ||
| 556 | + jmethodID didFailMethod = env_->GetMethodID(schemeRequestClass, "didFail", "(ILjava/lang/String;Z)V"); | ||
| 557 | + if (didFailMethod == nullptr) { | ||
| 558 | + LOGE("ArkWeb_ResourceHandler::DidFailWithError get didFail method failed"); | ||
| 559 | + return NWebError::PARAM_CHECK_ERROR; | ||
| 560 | + } | ||
| 561 | + jstring jsErrorDescription = env_->NewStringUTF(errorDescription.c_str()); | ||
| 562 | + CHECK_NULL_RETURN(jsErrorDescription, NWebError::PARAM_CHECK_ERROR); | ||
| 563 | + env_->CallVoidMethod(schemeRequestHandler_, didFailMethod, static_cast<int32_t>(errorCode), jsErrorDescription, | ||
| 564 | + completeIfNoResponse); | ||
| 565 | + | ||
| 566 | + ErrCode ret = NWebError::NO_ERROR; | ||
| 567 | + if (env_->ExceptionCheck()) { | ||
| 568 | + env_->ExceptionDescribe(); | ||
| 569 | + env_->ExceptionClear(); | ||
| 570 | + ret = NWebError::PARAM_CHECK_ERROR; | ||
| 571 | + } | ||
| 572 | + env_->DeleteLocalRef(jsErrorDescription); | ||
| 573 | + return ret; | ||
| 574 | +} | ||
| 575 | + | ||
| 576 | +ArkWeb_ResourceHandler::~ArkWeb_ResourceHandler() | ||
| 577 | +{ | ||
| 578 | + if (schemeRequestHandler_ != nullptr && env_ != nullptr) { | ||
| 579 | + env_->DeleteLocalRef(schemeRequestHandler_); | ||
| 580 | + schemeRequestHandler_ = nullptr; | ||
| 581 | + } | ||
| 582 | + if (handler_ != nullptr) { | ||
| 583 | + delete handler_; | ||
| 584 | + handler_ = nullptr; | ||
| 585 | + } | ||
| 586 | +} | ||
| 587 | + | ||
| 588 | +void ArkWeb_ResourceHandler::DestroyArkWebResourceHandler() | ||
| 589 | +{ | ||
| 590 | + isFinished_ = false; | ||
| 591 | + if (schemeRequestHandler_ != nullptr && env_ != nullptr) { | ||
| 592 | + env_->DeleteLocalRef(schemeRequestHandler_); | ||
| 593 | + schemeRequestHandler_ = nullptr; | ||
| 594 | + } | ||
| 595 | +} | ||
| 596 | +} // namespace OHOS::Plugin | ||
| @@ -0,0 +1,169 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | +namespace OHOS::Plugin { | ||
| 30 | +struct ArkWeb_SchemeHandler; | ||
| 31 | +struct ArkWeb_Response; | ||
| 32 | +class ArkWeb_ResourceHandler; | ||
| 33 | +typedef void (*ArkWeb_OnRequestStart)(struct ArkWeb_SchemeHandler* schemeHandler, | ||
| 34 | + struct ArkWeb_ResourceRequest* resourceRequest, ArkWeb_ResourceHandler* resourceHandler, bool* intercept); | ||
| 35 | + | ||
| 36 | +typedef void (*ArkWeb_OnRequestStop)( | ||
| 37 | + struct ArkWeb_SchemeHandler* schemeHandler, struct ArkWeb_ResourceRequest* resourceRequest); | ||
| 38 | +using WebHeaderList = std::vector<std::pair<std::string, std::string>>; | ||
| 39 | + | ||
| 40 | +class WebSchemeHandlerJni final { | ||
| 41 | +public: | ||
| 42 | + WebSchemeHandlerJni() = delete; | ||
| 43 | + ~WebSchemeHandlerJni() = delete; | ||
| 44 | + static bool Register(void* env); | ||
| 45 | + static void NativeInit(JNIEnv* env, jobject jobj); | ||
| 46 | + static bool OnSchemeHandlerRequestStart(JNIEnv* env, jclass jcls, jstring scheme, jobject schemeRequestHandler); | ||
| 47 | + static void OnSchemeHandlerRequestStop(JNIEnv* env, jclass jcls, jstring scheme, jobject schemeRequestHandler); | ||
| 48 | + static ArkWeb_SchemeHandler* CreateArkSchemeHandler(); | ||
| 49 | + static void DeleteArkSchemeHandler(ArkWeb_SchemeHandler* handler); | ||
| 50 | + static void SetOnRequestStart(ArkWeb_SchemeHandler* handler, ArkWeb_OnRequestStart callback); | ||
| 51 | + static void SetOnRequestStop(ArkWeb_SchemeHandler* handler, ArkWeb_OnRequestStop callback); | ||
| 52 | + static void InsertSchemeRequestHandler(std::string& scheme, ArkWeb_SchemeHandler* handler); | ||
| 53 | + static void ClearSchemeRequestHandler(); | ||
| 54 | + static bool GetIsIntercept(); | ||
| 55 | + static void SetIsIntercept(bool intercept); | ||
| 56 | + | ||
| 57 | +private: | ||
| 58 | + static ArkWeb_ResourceRequest* CreateArkResourceRequest(JNIEnv* env, jobject jRequest); | ||
| 59 | + static void DestroyArkResourceRequest(ArkWeb_ResourceRequest* request); | ||
| 60 | + static std::map<std::string, std::string> GetRequestHeader(JNIEnv* env, jobject javaObject); | ||
| 61 | + static std::string GetUTFString(JNIEnv* env, jstring jstr); | ||
| 62 | + static bool GetBooleanFromJava(JNIEnv* env, jclass clazz, jobject jobj, ArkWeb_ResourceRequest*& request, | ||
| 63 | + const char* methodName, bool& outBool); | ||
| 64 | + static bool GetStringFromJava(JNIEnv* env, jclass clazz, jobject jobj, ArkWeb_ResourceRequest*& request, | ||
| 65 | + const char* methodName, std::string& outStr); | ||
| 66 | + static jobject GetHeaderIterator(JNIEnv* env, jobject jHeadersMap); | ||
| 67 | + static void IterateAndFillHeaders(JNIEnv* env, jobject iterator, const jmethodID* methodIds, | ||
| 68 | + std::map<std::string, std::string>& headers); | ||
| 69 | + static bool GetIteratorAndEntryMethodIds( | ||
| 70 | + JNIEnv* env, jclass iteratorClass, jclass entryClass, jmethodID* methodIds); | ||
| 71 | + | ||
| 72 | +public: | ||
| 73 | + static ArkWeb_SchemeHandler* handler_; | ||
| 74 | + static ArkWeb_ResourceRequest* resourceRequest_; | ||
| 75 | +private: | ||
| 76 | + static std::map<std::string, ArkWeb_SchemeHandler*> g_schemeRequestHandlerMap_; | ||
| 77 | + static bool isIntercept_; | ||
| 78 | +}; | ||
| 79 | + | ||
| 80 | +struct ArkWeb_ResourceRequest { | ||
| 81 | +public: | ||
| 82 | + ArkWeb_ResourceRequest() = default; | ||
| 83 | + ~ArkWeb_ResourceRequest() | ||
| 84 | + { | ||
| 85 | + url_ = ""; | ||
| 86 | + method_ = ""; | ||
| 87 | + referrer_ = ""; | ||
| 88 | + isRedirect_ = false; | ||
| 89 | + isMainFrame_ = false; | ||
| 90 | + hasGesture_ = false; | ||
| 91 | + headerList_.clear(); | ||
| 92 | + requestResourceType_ = -1; | ||
| 93 | + frameUrl_ = ""; | ||
| 94 | + }; | ||
| 95 | + | ||
| 96 | +public: | ||
| 97 | + std::string url_ = ""; | ||
| 98 | + std::string method_ = ""; | ||
| 99 | + std::string referrer_ = ""; | ||
| 100 | + bool isRedirect_ = false; | ||
| 101 | + bool isMainFrame_ = false; | ||
| 102 | + bool hasGesture_ = false; | ||
| 103 | + WebHeaderList headerList_; | ||
| 104 | + int32_t requestResourceType_ = -1; | ||
| 105 | + std::string frameUrl_ = ""; | ||
| 106 | +}; | ||
| 107 | + | ||
| 108 | +class ArkWeb_ResourceHandler { | ||
| 109 | +public: | ||
| 110 | + ArkWeb_ResourceHandler(JNIEnv* env, jobject schemeRequestHandler) | ||
| 111 | + : env_(env), schemeRequestHandler_(schemeRequestHandler) | ||
| 112 | + {} | ||
| 113 | + ~ArkWeb_ResourceHandler(); | ||
| 114 | + | ||
| 115 | + ErrCode DidReceiveResponse(const ArkWeb_Response* response); | ||
| 116 | + ErrCode DidReceiveData(const uint8_t* buffer, int64_t buflen); | ||
| 117 | + ErrCode DidFinish(); | ||
| 118 | + ErrCode DidFailWithError(ArkWeb_NetError errorCode, const std::string& errorDescription, bool completeIfNoResponse); | ||
| 119 | + void DestroyArkWebResourceHandler(); | ||
| 120 | + void SetFinishFlag() | ||
| 121 | + { | ||
| 122 | + isFinished_ = true; | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | +private: | ||
| 126 | + jobject ConvertMapToJavaMap(JNIEnv* env, const std::unordered_map<std::string, std::string>& headersMap); | ||
| 127 | + ErrCode SetResponseUrl(const std::string& url); | ||
| 128 | + ErrCode SetResponseErrcode(ArkWeb_NetError errorCode, const std::string& errorDescription); | ||
| 129 | + | ||
| 130 | +private: | ||
| 131 | + bool isFinished_ = false; | ||
| 132 | + JNIEnv* env_ = nullptr; | ||
| 133 | + jobject schemeRequestHandler_ = nullptr; | ||
| 134 | + ArkWeb_ResourceHandler* handler_ = nullptr; | ||
| 135 | +}; | ||
| 136 | + | ||
| 137 | +struct ArkWeb_Response { | ||
| 138 | +public: | ||
| 139 | + ArkWeb_Response() = default; | ||
| 140 | + ~ArkWeb_Response() | ||
| 141 | + { | ||
| 142 | + url_ = ""; | ||
| 143 | + status_ = 0; | ||
| 144 | + statusText_ = ""; | ||
| 145 | + mimeType_ = ""; | ||
| 146 | + encoding_ = ""; | ||
| 147 | + data_ = ""; | ||
| 148 | + headers_.clear(); | ||
| 149 | + errorCode_ = 0; | ||
| 150 | + errorDescription_ = ""; | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + std::string url_ = ""; | ||
| 154 | + int32_t status_ = 0; | ||
| 155 | + std::string statusText_ = ""; | ||
| 156 | + std::string mimeType_ = ""; | ||
| 157 | + std::string encoding_ = ""; | ||
| 158 | + std::string data_ = ""; | ||
| 159 | + std::unordered_map<std::string, std::string> headers_; | ||
| 160 | + int32_t errorCode_ = 0; | ||
| 161 | + std::string errorDescription_ = ""; | ||
| 162 | +}; | ||
| 163 | + | ||
| 164 | +struct ArkWeb_SchemeHandler { | ||
| 165 | + ArkWeb_OnRequestStart on_request_start; | ||
| 166 | + ArkWeb_OnRequestStop on_request_stop; | ||
| 167 | +}; | ||
| 168 | +} // namespace OHOS::Plugin | ||
| 169 | + | ||
| @@ -15,6 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | + | ||
| 18 | 19 | ||
| 19 | 20 | ||
| 20 | 21 | ||
| @@ -217,4 +218,26 @@ void WebviewControllerAndroid::DeleteJavaScriptRegister(const std::string& objNa | |||
| 217 | { | 218 | { |
| 218 | WebviewControllerJni::DeleteJavaScriptRegister(webId_, objName); | 219 | WebviewControllerJni::DeleteJavaScriptRegister(webId_, objName); |
| 219 | } | 220 | } |
| 221 | + | ||
| 222 | +bool WebviewControllerAndroid::SetWebSchemeHandler(const char* scheme, WebSchemeHandler* handler) | ||
| 223 | +{ | ||
| 224 | + CHECK_NULL_RETURN(scheme, false); | ||
| 225 | + CHECK_NULL_RETURN(handler, false); | ||
| 226 | + std::string schemeStr(scheme); | ||
| 227 | + auto arkHandler = WebSchemeHandler::GetArkWebSchemeHandler(handler); | ||
| 228 | + WebSchemeHandlerJni::InsertSchemeRequestHandler(schemeStr, arkHandler); | ||
| 229 | + return WebviewControllerJni::SetWebSchemeHandler(webId_, schemeStr); | ||
| 230 | +} | ||
| 231 | + | ||
| 232 | +bool WebviewControllerAndroid::ClearWebSchemeHandler() | ||
| 233 | +{ | ||
| 234 | + WebSchemeHandlerJni::ClearSchemeRequestHandler(); | ||
| 235 | + WebviewControllerJni::ClearWebSchemeHandler(webId_); | ||
| 236 | + return true; | ||
| 237 | +} | ||
| 238 | + | ||
| 239 | +std::string WebviewControllerAndroid::GetUserAgent() | ||
| 240 | +{ | ||
| 241 | + return WebviewControllerJni::GetUserAgent(webId_); | ||
| 242 | +} | ||
| 220 | } | 243 | } |
| @@ -62,6 +62,9 @@ public: | |||
| 62 | void StartDownload(const std::string& url) override; | 62 | void StartDownload(const std::string& url) override; |
| 63 | void RegisterJavaScriptProxy(const RegisterJavaScriptProxyParam& param) override; | 63 | void RegisterJavaScriptProxy(const RegisterJavaScriptProxyParam& param) override; |
| 64 | void DeleteJavaScriptRegister(const std::string& objName) override; | 64 | void DeleteJavaScriptRegister(const std::string& objName) override; |
| 65 | + bool SetWebSchemeHandler(const char* scheme, WebSchemeHandler* handler) override; | ||
| 66 | + bool ClearWebSchemeHandler() override; | ||
| 67 | + std::string GetUserAgent() override; | ||
| 65 | }; | 68 | }; |
| 66 | } | 69 | } |
| 67 | 70 | ||
| @@ -126,6 +126,12 @@ static const char METHOD_REGISTERJAVASCRIPTPROXY[] = "registerJavaScriptProxy"; | |||
| 126 | 126 | ||
| 127 | static const char METHOD_DELETEJAVASCRIPTREGISTER[] = "deleteJavaScriptRegister"; | 127 | static const char METHOD_DELETEJAVASCRIPTREGISTER[] = "deleteJavaScriptRegister"; |
| 128 | 128 | ||
| 129 | +static const char METHOD_SET_WEB_SCHEME_HANDLER[] = "setWebSchemeHandler"; | ||
| 130 | + | ||
| 131 | +static const char METHOD_CLEAR_WEB_SCHEME_HANDLER[] = "clearWebSchemeHandler"; | ||
| 132 | + | ||
| 133 | +static const char METHOD_GET_USER_AGENT[] = "getUserAgent"; | ||
| 134 | + | ||
| 129 | static const char SIGNATURE_LOADURL[] = "(JLjava/lang/String;Ljava/util/HashMap;)V"; | 135 | static const char SIGNATURE_LOADURL[] = "(JLjava/lang/String;Ljava/util/HashMap;)V"; |
| 130 | 136 | ||
| 131 | static const char SIGNATURE_LOADDATA[] = "(JLjava/util/HashMap;)V"; | 137 | static const char SIGNATURE_LOADDATA[] = "(JLjava/util/HashMap;)V"; |
| @@ -209,6 +215,12 @@ static const char SIGNATURE_REGISTERJAVASCRIPTPROXY[] = | |||
| 209 | 215 | ||
| 210 | static const char SIGNATURE_DELETEJAVASCRIPTREGISTER[] = "(JLjava/lang/String;)V"; | 216 | static const char SIGNATURE_DELETEJAVASCRIPTREGISTER[] = "(JLjava/lang/String;)V"; |
| 211 | 217 | ||
| 218 | +static const char SIGNATURE_SET_WEB_SCHEME_HANDLER[] = "(JLjava/lang/String;)Z"; | ||
| 219 | + | ||
| 220 | +static const char SIGNATURE_CLEAR_WEB_SCHEME_HANDLER[] = "(J)V"; | ||
| 221 | + | ||
| 222 | +static const char SIGNATURE_GET_USER_AGENT[] = "(J)Ljava/lang/String;"; | ||
| 223 | + | ||
| 212 | bool _webDebuggingAccessInit = false; | 224 | bool _webDebuggingAccessInit = false; |
| 213 | 225 | ||
| 214 | struct { | 226 | struct { |
| @@ -253,6 +265,9 @@ struct { | |||
| 253 | jmethodID onWebMessagePortEventExt; | 265 | jmethodID onWebMessagePortEventExt; |
| 254 | jmethodID registerJavaScriptProxy; | 266 | jmethodID registerJavaScriptProxy; |
| 255 | jmethodID deleteJavaScriptRegister; | 267 | jmethodID deleteJavaScriptRegister; |
| 268 | + jmethodID setWebSchemeHandler; | ||
| 269 | + jmethodID clearWebSchemeHandler; | ||
| 270 | + jmethodID getUserAgent; | ||
| 256 | jobject globalRef; | 271 | jobject globalRef; |
| 257 | } g_webWebviewClass; | 272 | } g_webWebviewClass; |
| 258 | } | 273 | } |
| @@ -320,6 +335,11 @@ void WebviewControllerJni::NativeInit(JNIEnv* env, jobject jobj) | |||
| 320 | env->GetMethodID(cls, METHOD_REGISTERJAVASCRIPTPROXY, SIGNATURE_REGISTERJAVASCRIPTPROXY); | 335 | env->GetMethodID(cls, METHOD_REGISTERJAVASCRIPTPROXY, SIGNATURE_REGISTERJAVASCRIPTPROXY); |
| 321 | g_webWebviewClass.deleteJavaScriptRegister = | 336 | g_webWebviewClass.deleteJavaScriptRegister = |
| 322 | env->GetMethodID(cls, METHOD_DELETEJAVASCRIPTREGISTER, SIGNATURE_DELETEJAVASCRIPTREGISTER); | 337 | env->GetMethodID(cls, METHOD_DELETEJAVASCRIPTREGISTER, SIGNATURE_DELETEJAVASCRIPTREGISTER); |
| 338 | + g_webWebviewClass.setWebSchemeHandler = | ||
| 339 | + env->GetMethodID(cls, METHOD_SET_WEB_SCHEME_HANDLER, SIGNATURE_SET_WEB_SCHEME_HANDLER); | ||
| 340 | + g_webWebviewClass.clearWebSchemeHandler = | ||
| 341 | + env->GetMethodID(cls, METHOD_CLEAR_WEB_SCHEME_HANDLER, SIGNATURE_CLEAR_WEB_SCHEME_HANDLER); | ||
| 342 | + g_webWebviewClass.getUserAgent = env->GetMethodID(cls, METHOD_GET_USER_AGENT, SIGNATURE_GET_USER_AGENT); | ||
| 323 | env->DeleteLocalRef(cls); | 343 | env->DeleteLocalRef(cls); |
| 324 | } | 344 | } |
| 325 | 345 | ||
| @@ -1752,4 +1772,58 @@ void WebviewControllerJni::DeleteJavaScriptRegister(int id, const std::string& o | |||
| 1752 | env->ExceptionClear(); | 1772 | env->ExceptionClear(); |
| 1753 | } | 1773 | } |
| 1754 | } | 1774 | } |
| 1775 | + | ||
| 1776 | +bool WebviewControllerJni::SetWebSchemeHandler(int id, const std::string& scheme) | ||
| 1777 | +{ | ||
| 1778 | + auto env = ARKUI_X_Plugin_GetJniEnv(); | ||
| 1779 | + CHECK_NULL_RETURN(env, false); | ||
| 1780 | + CHECK_NULL_RETURN(g_webWebviewClass.globalRef, false); | ||
| 1781 | + CHECK_NULL_RETURN(g_webWebviewClass.setWebSchemeHandler, false); | ||
| 1782 | + jstring jsScheme = env->NewStringUTF(scheme.c_str()); | ||
| 1783 | + bool ret = env->CallBooleanMethod(g_webWebviewClass.globalRef, g_webWebviewClass.setWebSchemeHandler, id, jsScheme); | ||
| 1784 | + env->DeleteLocalRef(jsScheme); | ||
| 1785 | + if (env->ExceptionCheck()) { | ||
| 1786 | + env->ExceptionDescribe(); | ||
| 1787 | + env->ExceptionClear(); | ||
| 1788 | + } | ||
| 1789 | + return ret; | ||
| 1790 | +} | ||
| 1791 | + | ||
| 1792 | +void WebviewControllerJni::ClearWebSchemeHandler(int id) | ||
| 1793 | +{ | ||
| 1794 | + auto env = ARKUI_X_Plugin_GetJniEnv(); | ||
| 1795 | + CHECK_NULL_VOID(env); | ||
| 1796 | + CHECK_NULL_VOID(g_webWebviewClass.globalRef); | ||
| 1797 | + CHECK_NULL_VOID(g_webWebviewClass.clearWebSchemeHandler); | ||
| 1798 | + env->CallVoidMethod(g_webWebviewClass.globalRef, g_webWebviewClass.clearWebSchemeHandler, id); | ||
| 1799 | + if (env->ExceptionCheck()) { | ||
| 1800 | + env->ExceptionDescribe(); | ||
| 1801 | + env->ExceptionClear(); | ||
| 1802 | + } | ||
| 1803 | +} | ||
| 1804 | + | ||
| 1805 | +std::string WebviewControllerJni::GetUserAgent(int id) | ||
| 1806 | +{ | ||
| 1807 | + auto env = ARKUI_X_Plugin_GetJniEnv(); | ||
| 1808 | + CHECK_NULL_RETURN(env, ""); | ||
| 1809 | + CHECK_NULL_RETURN(g_webWebviewClass.globalRef, ""); | ||
| 1810 | + CHECK_NULL_RETURN(g_webWebviewClass.getUserAgent, ""); | ||
| 1811 | + jstring jResult = static_cast<jstring>( | ||
| 1812 | + env->CallObjectMethod(g_webWebviewClass.globalRef, g_webWebviewClass.getUserAgent, id)); | ||
| 1813 | + if (env->ExceptionCheck()) { | ||
| 1814 | + env->ExceptionDescribe(); | ||
| 1815 | + env->ExceptionClear(); | ||
| 1816 | + return ""; | ||
| 1817 | + } | ||
| 1818 | + std::string result = ""; | ||
| 1819 | + const char* content = env->GetStringUTFChars(jResult, nullptr); | ||
| 1820 | + if (content != nullptr) { | ||
| 1821 | + result.assign(content); | ||
| 1822 | + env->ReleaseStringUTFChars(jResult, content); | ||
| 1823 | + } | ||
| 1824 | + if (jResult != nullptr) { | ||
| 1825 | + env->DeleteLocalRef(jResult); | ||
| 1826 | + } | ||
| 1827 | + return result; | ||
| 1828 | +} | ||
| 1755 | } | 1829 | } |
| @@ -95,6 +95,9 @@ public: | |||
| 95 | static jobject ConvertWebStringToJava(JNIEnv* env, std::shared_ptr<Ace::WebJSValue>& ret); | 95 | static jobject ConvertWebStringToJava(JNIEnv* env, std::shared_ptr<Ace::WebJSValue>& ret); |
| 96 | static jobject ConvertWebListToJava(JNIEnv* env, std::shared_ptr<Ace::WebJSValue>& ret); | 96 | static jobject ConvertWebListToJava(JNIEnv* env, std::shared_ptr<Ace::WebJSValue>& ret); |
| 97 | static jobject ConvertWebDictionaryToJava(JNIEnv* env, std::shared_ptr<Ace::WebJSValue>& ret); | 97 | static jobject ConvertWebDictionaryToJava(JNIEnv* env, std::shared_ptr<Ace::WebJSValue>& ret); |
| 98 | + static bool SetWebSchemeHandler(int id, const std::string& scheme); | ||
| 99 | + static void ClearWebSchemeHandler(int id); | ||
| 100 | + static std::string GetUserAgent(int id); | ||
| 98 | }; | 101 | }; |
| 99 | } | 102 | } |
| 100 | 103 | ||
Aweb/webview/android/java/src/ohos/ace/plugin/webviewplugin/androidasset/AndroidAssetPlugin.java+68-0
| @@ -0,0 +1,68 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +package ohos.ace.plugin.webviewplugin.androidasset; | ||
| 17 | + | ||
| 18 | +import android.content.Context; | ||
| 19 | +import android.content.res.AssetManager; | ||
| 20 | + | ||
| 21 | +import java.io.IOException; | ||
| 22 | +import java.io.InputStream; | ||
| 23 | + | ||
| 24 | +/** | ||
| 25 | + * AndroidAssetPlugin is used to manage AndroidAsset | ||
| 26 | + * | ||
| 27 | + * 22 | ||
| 28 | + */ | ||
| 29 | +public class AndroidAssetPlugin { | ||
| 30 | + private static final String LOG_TAG = "AndroidAssetPlugin"; | ||
| 31 | + private static final String ANDROID_VIRTUAL_ASSET_PREFIX = "file:///android_asset/"; | ||
| 32 | + | ||
| 33 | + private final Context context; | ||
| 34 | + | ||
| 35 | + public AndroidAssetPlugin(Context context) { | ||
| 36 | + this.context = context; | ||
| 37 | + nativeInit(); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + /** | ||
| 41 | + * Checks whether a virtual asset exists at the specified URL. | ||
| 42 | + * | ||
| 43 | + * <p>This method verifies if the given URL starts with the expected virtual asset prefix. | ||
| 44 | + * If so, it attempts to open the asset using the { AssetManager}. If the asset can be | ||
| 45 | + * opened without throwing an { IOException}, it is considered to exist.</p> | ||
| 46 | + * | ||
| 47 | + * url The URL of the virtual asset to check. | ||
| 48 | + * { true} if the virtual asset exists; { false} otherwise. | ||
| 49 | + */ | ||
| 50 | + public boolean existsVirtualAsset(String url) { | ||
| 51 | + if (!url.startsWith(ANDROID_VIRTUAL_ASSET_PREFIX)) { | ||
| 52 | + return false; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + AssetManager assetManager = this.context.getAssets(); | ||
| 56 | + String assetPath = url.substring(ANDROID_VIRTUAL_ASSET_PREFIX.length()); | ||
| 57 | + try (InputStream inputStream = assetManager.open(assetPath)) { | ||
| 58 | + return true; | ||
| 59 | + } catch (IOException e) { | ||
| 60 | + return false; | ||
| 61 | + } | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + /** | ||
| 65 | + * Initialize the native environment. | ||
| 66 | + */ | ||
| 67 | + protected final native void nativeInit(); | ||
| 68 | +} | ||
| @@ -234,4 +234,23 @@ void WebviewControllerIOS::DeleteJavaScriptRegister(const std::string& objName) | |||
| 234 | { | 234 | { |
| 235 | deleteJavaScriptRegisterOC(webId_, objName); | 235 | deleteJavaScriptRegisterOC(webId_, objName); |
| 236 | } | 236 | } |
| 237 | + | ||
| 238 | +bool WebviewControllerIOS::SetWebSchemeHandler(const char* scheme, WebSchemeHandler* handler) | ||
| 239 | +{ | ||
| 240 | + if (!handler || !scheme) { | ||
| 241 | + return false; | ||
| 242 | + } | ||
| 243 | + auto arkHandler = WebSchemeHandler::GetArkWebSchemeHandler(handler); | ||
| 244 | + return setWebSchemeHandlerOC(webId_, scheme, arkHandler); | ||
| 245 | +} | ||
| 246 | + | ||
| 247 | +bool WebviewControllerIOS::ClearWebSchemeHandler() | ||
| 248 | +{ | ||
| 249 | + return clearWebSchemeHandlerOC(webId_); | ||
| 250 | +} | ||
| 251 | + | ||
| 252 | +std::string WebviewControllerIOS::GetUserAgent() | ||
| 253 | +{ | ||
| 254 | + return getUserAgentOC(); | ||
| 255 | +} | ||
| 237 | } // namespace OHOS::Plugin | 256 | } // namespace OHOS::Plugin |
| @@ -18,6 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | + | ||
| 21 | 22 | ||
| 22 | namespace OHOS::Plugin { | 23 | namespace OHOS::Plugin { |
| 23 | class WebviewControllerIOS : public WebviewController { | 24 | class WebviewControllerIOS : public WebviewController { |
| @@ -61,6 +62,9 @@ public: | |||
| 61 | void StartDownload(const std::string& url) override; | 62 | void StartDownload(const std::string& url) override; |
| 62 | void RegisterJavaScriptProxy(const RegisterJavaScriptProxyParam& param) override; | 63 | void RegisterJavaScriptProxy(const RegisterJavaScriptProxyParam& param) override; |
| 63 | void DeleteJavaScriptRegister(const std::string& objName) override; | 64 | void DeleteJavaScriptRegister(const std::string& objName) override; |
| 65 | + bool SetWebSchemeHandler(const char* scheme, WebSchemeHandler* handler) override; | ||
| 66 | + bool ClearWebSchemeHandler() override; | ||
| 67 | + std::string GetUserAgent() override; | ||
| 64 | }; | 68 | }; |
| 65 | } // namespace OHOS::Plugin | 69 | } // namespace OHOS::Plugin |
| 66 | 70 | ||
| @@ -30,6 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | 31 | ||
| 32 | 32 | ||
| 33 | + | ||
| 33 | 34 | ||
| 34 | 35 | ||
| 35 | 36 | ||
| @@ -37,7 +38,9 @@ | |||
| 37 | 38 | ||
| 38 | 39 | ||
| 39 | 40 | ||
| 41 | + | ||
| 40 | 42 | ||
| 43 | + | ||
| 41 | 44 | ||
| 42 | 45 | ||
| 43 | 46 | ||
| @@ -51,6 +54,7 @@ | |||
| 51 | 54 | ||
| 52 | 55 | ||
| 53 | 56 | ||
| 57 | + | ||
| 54 | 58 | ||
| 55 | 59 | ||
| 56 | 60 | ||
| @@ -67,9 +71,11 @@ thread_local napi_ref g_classWebMsgPort; | |||
| 67 | thread_local napi_ref g_jsMsgExtClassRef; | 71 | thread_local napi_ref g_jsMsgExtClassRef; |
| 68 | thread_local int32_t g_asyncCallbackInfoId = 0; | 72 | thread_local int32_t g_asyncCallbackInfoId = 0; |
| 69 | constexpr int32_t MAX_COUNT_ID = 1024; | 73 | constexpr int32_t MAX_COUNT_ID = 1024; |
| 74 | +const std::string ANDROID_ASSET = "file:///android_asset/"; | ||
| 75 | +const std::string ARKUIX_PATH_MARKER = "files/arkui-x/"; | ||
| 70 | const std::string HTTP = "http://"; | 76 | const std::string HTTP = "http://"; |
| 71 | const std::string HTTPS = "https://"; | 77 | const std::string HTTPS = "https://"; |
| 72 | -const std::string RESOURCE = "resource://rawfile"; | 78 | +const std::string RESOURCE = "resource://rawfile/"; |
| 73 | const std::string FILE = "file"; | 79 | const std::string FILE = "file"; |
| 74 | constexpr int32_t MAX_WEB_STRING_LENGTH = 40960; | 80 | constexpr int32_t MAX_WEB_STRING_LENGTH = 40960; |
| 75 | constexpr uint32_t URL_MAXIMUM = 2048; | 81 | constexpr uint32_t URL_MAXIMUM = 2048; |
| @@ -79,6 +85,24 @@ const char* rawfile = "resource://rawfile/"; | |||
| 79 | const char* replacement = "file:///"; | 85 | const char* replacement = "file:///"; |
| 80 | std::regex reg("^(https?|file)://[\\w.-/]+(:\\d+)?(/.*)?$"); | 86 | std::regex reg("^(https?|file)://[\\w.-/]+(:\\d+)?(/.*)?$"); |
| 81 | 87 | ||
| 88 | +bool ExistsWebFileUrl(const std::string &webFileUrl) | ||
| 89 | +{ | ||
| 90 | + | ||
| 91 | + if (webFileUrl.substr(INTEGER_ZERO, ANDROID_ASSET.size()) == ANDROID_ASSET) { | ||
| 92 | + return AndroidAssetHelperJni::ExistsVirtualAsset(webFileUrl); | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + | ||
| 96 | + std::string fileProtocolName = "file"; | ||
| 97 | + if (webFileUrl.substr(INTEGER_ZERO, fileProtocolName.size()) == "file") { | ||
| 98 | + std::string filePath = webFileUrl; | ||
| 99 | + std::string fileProtocol = "file:///"; | ||
| 100 | + filePath.erase(INTEGER_ZERO, fileProtocol.size()); | ||
| 101 | + return access(filePath.c_str(), F_OK) != -1; | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + return true; | ||
| 105 | +} | ||
| 82 | 106 | ||
| 83 | bool GetRawFileUrl(const std::string &fileName, std::string &result) | 107 | bool GetRawFileUrl(const std::string &fileName, std::string &result) |
| 84 | { | 108 | { |
| @@ -86,7 +110,19 @@ bool GetRawFileUrl(const std::string &fileName, std::string &result) | |||
| 86 | return false; | 110 | return false; |
| 87 | } | 111 | } |
| 88 | result = NapiWebviewController::appHapPath_ + "/resources/rawfile/" + fileName; | 112 | result = NapiWebviewController::appHapPath_ + "/resources/rawfile/" + fileName; |
| 89 | - LOGE("The parsed url is: %{public}s", result.c_str()); | 113 | + |
| 114 | + | ||
| 115 | + size_t pos = NapiWebviewController::appHapPath_.find(ARKUIX_PATH_MARKER); | ||
| 116 | + if (pos != std::string::npos) { | ||
| 117 | + std::string assetPath = ANDROID_ASSET + | ||
| 118 | + NapiWebviewController::appHapPath_.substr(pos + std::strlen("files/")) + "/resources/rawfile/" + fileName; | ||
| 119 | + if (AndroidAssetHelperJni::ExistsVirtualAsset(assetPath)) { | ||
| 120 | + result = assetPath; | ||
| 121 | + } | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + | ||
| 125 | + LOGD("The parsed url is: %{public}s", result.c_str()); | ||
| 90 | return true; | 126 | return true; |
| 91 | } | 127 | } |
| 92 | 128 | ||
| @@ -307,15 +343,8 @@ napi_value NapiWebviewController::LoadUrl(napi_env env, napi_callback_info info) | |||
| 307 | LOGE("ParseUrl failed"); | 343 | LOGE("ParseUrl failed"); |
| 308 | return nullptr; | 344 | return nullptr; |
| 309 | } | 345 | } |
| 310 | - std::string fileProtocolName = "file"; | 346 | + if (!ExistsWebFileUrl(webSrc)) { |
| 311 | - if (webSrc.substr(INTEGER_ZERO, fileProtocolName.size()) == "file") { | 347 | + BusinessError::ThrowErrorByErrcode(env, INVALID_RESOURCE); |
| 312 | - std::string filePath = webSrc; | ||
| 313 | - std::string fileProtocol = "file:///"; | ||
| 314 | - filePath.erase(INTEGER_ZERO, fileProtocol.size()); | ||
| 315 | - int isFileExist = access(filePath.c_str(), F_OK); | ||
| 316 | - if (isFileExist == -1) { | ||
| 317 | - BusinessError::ThrowErrorByErrcode(env, INVALID_RESOURCE); | ||
| 318 | - } | ||
| 319 | } | 348 | } |
| 320 | if (argc == INTEGER_ONE) { | 349 | if (argc == INTEGER_ONE) { |
| 321 | ErrCode ret = webviewController->LoadUrl(webSrc); | 350 | ErrCode ret = webviewController->LoadUrl(webSrc); |
| @@ -1770,6 +1799,59 @@ napi_value NapiWebviewController::RegisterJavaScriptProxy(napi_env env, napi_cal | |||
| 1770 | return result; | 1799 | return result; |
| 1771 | } | 1800 | } |
| 1772 | 1801 | ||
| 1802 | +napi_value NapiWebviewController::SetWebSchemeHandler(napi_env env, napi_callback_info info) | ||
| 1803 | +{ | ||
| 1804 | + size_t argc = 2; | ||
| 1805 | + napi_value argv[2] = {0}; | ||
| 1806 | + napi_value thisVar = nullptr; | ||
| 1807 | + void* data = nullptr; | ||
| 1808 | + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); | ||
| 1809 | + | ||
| 1810 | + WebviewController *webviewController = nullptr; | ||
| 1811 | + NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webviewController)); | ||
| 1812 | + if (webviewController == nullptr || !webviewController->IsInit()) { | ||
| 1813 | + BusinessError::ThrowErrorByErrcode(env, INIT_ERROR); | ||
| 1814 | + LOGE("create message port failed, napi unwrap webviewController failed"); | ||
| 1815 | + return nullptr; | ||
| 1816 | + } | ||
| 1817 | + | ||
| 1818 | + std::string scheme = ""; | ||
| 1819 | + if (!NapiParseUtils::ParseString(env, argv[0], scheme)) { | ||
| 1820 | + LOGE("NapiWebviewController::SetWebSchemeHandler parse scheme failed"); | ||
| 1821 | + BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR, | ||
| 1822 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "scheme", "string")); | ||
| 1823 | + return nullptr; | ||
| 1824 | + } | ||
| 1825 | + | ||
| 1826 | + WebSchemeHandler* handler = nullptr; | ||
| 1827 | + napi_value obj = argv[1]; | ||
| 1828 | + napi_unwrap(env, obj, (void**)&handler); | ||
| 1829 | + if (!handler) { | ||
| 1830 | + LOGE("NapiWebviewController::SetWebSchemeHandler handler is null"); | ||
| 1831 | + return nullptr; | ||
| 1832 | + } | ||
| 1833 | + if (!webviewController->SetWebSchemeHandler(scheme.c_str(), handler)) { | ||
| 1834 | + LOGE("NapiWebviewController::SetWebSchemeHandler failed"); | ||
| 1835 | + } | ||
| 1836 | + return nullptr; | ||
| 1837 | +} | ||
| 1838 | + | ||
| 1839 | +napi_value NapiWebviewController::ClearWebSchemeHandler(napi_env env, napi_callback_info info) | ||
| 1840 | +{ | ||
| 1841 | + napi_value result = nullptr; | ||
| 1842 | + WebviewController *webviewController = GetWebviewController(env, info); | ||
返回值类型为napi_value,返回nullptr可能导致NAPI运行时异常或未定义行为,返回前调用napi_get_undefined获取结果值,而非直接返回nullptr ![]() ![]() | |||
| 1843 | + if (!webviewController) { | ||
| 1844 | + napi_get_undefined(env, &result); | ||
| 1845 | + return result; | ||
| 1846 | + } | ||
| 1847 | + | ||
| 1848 | + if (!webviewController->ClearWebSchemeHandler()) { | ||
| 1849 | + LOGE("NapiWebviewController::ClearWebSchemeHandler failed"); | ||
| 1850 | + } | ||
| 1851 | + NAPI_CALL(env, napi_get_undefined(env, &result)); | ||
| 1852 | + return result; | ||
| 1853 | +} | ||
| 1854 | + | ||
| 1773 | napi_value NapiWebviewController::DeleteJavaScriptRegister(napi_env env, napi_callback_info info) | 1855 | napi_value NapiWebviewController::DeleteJavaScriptRegister(napi_env env, napi_callback_info info) |
| 1774 | { | 1856 | { |
| 1775 | napi_value thisVar = nullptr; | 1857 | napi_value thisVar = nullptr; |
| @@ -1809,6 +1891,21 @@ napi_value NapiWebviewController::DeleteJavaScriptRegister(napi_env env, napi_ca | |||
| 1809 | return result; | 1891 | return result; |
| 1810 | } | 1892 | } |
| 1811 | 1893 | ||
| 1894 | +napi_value NapiWebviewController::GetUserAgent(napi_env env, napi_callback_info info) | ||
| 1895 | +{ | ||
| 1896 | + napi_value result = nullptr; | ||
| 1897 | + WebviewController *webviewController = GetWebviewController(env, info); | ||
| 1898 | + if (!webviewController) { | ||
| 1899 | + return nullptr; | ||
| 1900 | + } | ||
| 1901 | + | ||
| 1902 | + std::string userAgent = ""; | ||
| 1903 | + userAgent = webviewController->GetUserAgent(); | ||
| 1904 | + napi_create_string_utf8(env, userAgent.c_str(), userAgent.length(), &result); | ||
| 1905 | + | ||
| 1906 | + return result; | ||
| 1907 | +} | ||
| 1908 | + | ||
| 1812 | napi_value NapiWebviewController::Init(napi_env env, napi_value exports) | 1909 | napi_value NapiWebviewController::Init(napi_env env, napi_value exports) |
| 1813 | { | 1910 | { |
| 1814 | napi_property_descriptor properties[] = { | 1911 | napi_property_descriptor properties[] = { |
| @@ -1852,6 +1949,9 @@ napi_value NapiWebviewController::Init(napi_env env, napi_value exports) | |||
| 1852 | DECLARE_NAPI_FUNCTION("registerJavaScriptProxy", NapiWebviewController::RegisterJavaScriptProxy), | 1949 | DECLARE_NAPI_FUNCTION("registerJavaScriptProxy", NapiWebviewController::RegisterJavaScriptProxy), |
| 1853 | DECLARE_NAPI_FUNCTION("deleteJavaScriptRegister", NapiWebviewController::DeleteJavaScriptRegister), | 1950 | DECLARE_NAPI_FUNCTION("deleteJavaScriptRegister", NapiWebviewController::DeleteJavaScriptRegister), |
| 1854 | DECLARE_NAPI_FUNCTION("jsProxy", NapiWebviewController::RegisterJavaScriptProxy), | 1951 | DECLARE_NAPI_FUNCTION("jsProxy", NapiWebviewController::RegisterJavaScriptProxy), |
| 1952 | + DECLARE_NAPI_FUNCTION("setWebSchemeHandler", NapiWebviewController::SetWebSchemeHandler), | ||
| 1953 | + DECLARE_NAPI_FUNCTION("clearWebSchemeHandler", NapiWebviewController::ClearWebSchemeHandler), | ||
| 1954 | + DECLARE_NAPI_FUNCTION("getUserAgent", NapiWebviewController::GetUserAgent), | ||
| 1855 | }; | 1955 | }; |
| 1856 | 1956 | ||
| 1857 | napi_value constructor = nullptr; | 1957 | napi_value constructor = nullptr; |
| @@ -2072,6 +2172,9 @@ static napi_value WebWebviewExport(napi_env env, napi_value exports) | |||
| 2072 | NapiWebDownloadManager::Init(env, exports); | 2172 | NapiWebDownloadManager::Init(env, exports); |
| 2073 | NapiWebDownloadItem::Init(env, exports); | 2173 | NapiWebDownloadItem::Init(env, exports); |
| 2074 | NapiWebMessageExt::Init(env, exports); | 2174 | NapiWebMessageExt::Init(env, exports); |
| 2175 | + NapiWebSchemeHandler::Init(env, exports); | ||
| 2176 | + NapiWebSchemeHandlerRequest::Init(env, exports); | ||
| 2177 | + NapiWebSchemeHandlerResponse::Init(env, exports); | ||
| 2075 | return exports; | 2178 | return exports; |
| 2076 | } | 2179 | } |
| 2077 | 2180 | ||
| @@ -2102,6 +2205,10 @@ static void WebWebviewJniRegister() | |||
| 2102 | ARKUI_X_Plugin_RegisterJavaPlugin(&WebDownloadDelegateJni::Register, webDownloadDelegateClassName); | 2205 | ARKUI_X_Plugin_RegisterJavaPlugin(&WebDownloadDelegateJni::Register, webDownloadDelegateClassName); |
| 2103 | const char webDownloadItemClassName[] = "ohos.ace.adapter.capability.web.AceWebPluginBase"; | 2206 | const char webDownloadItemClassName[] = "ohos.ace.adapter.capability.web.AceWebPluginBase"; |
| 2104 | ARKUI_X_Plugin_RegisterJavaPlugin(&WebDownloadItemJni::Register, webDownloadItemClassName); | 2207 | ARKUI_X_Plugin_RegisterJavaPlugin(&WebDownloadItemJni::Register, webDownloadItemClassName); |
| 2208 | + const char webSchemeRequestClassName[] = "ohos.ace.adapter.capability.web.AceWebPluginBase"; | ||
| 2209 | + ARKUI_X_Plugin_RegisterJavaPlugin(&WebSchemeHandlerJni::Register, webSchemeRequestClassName); | ||
| 2210 | + const char AndroidAssetClassName[] = "ohos.ace.plugin.webviewplugin.androidasset.AndroidAssetPlugin"; | ||
| 2211 | + ARKUI_X_Plugin_RegisterJavaPlugin(&AndroidAssetHelperJni::Register, AndroidAssetClassName); | ||
| 2105 | } | 2212 | } |
| 2106 | 2213 | ||
| 2107 | 2214 | ||
| @@ -4028,4 +4135,102 @@ napi_status NapiWebDownloadItem::DefineProperties(napi_env env, napi_value* obje | |||
| 4028 | }; | 4135 | }; |
| 4029 | return napi_define_properties(env, *object, sizeof(properties) / sizeof(properties[0]), properties); | 4136 | return napi_define_properties(env, *object, sizeof(properties) / sizeof(properties[0]), properties); |
| 4030 | } | 4137 | } |
| 4138 | + | ||
| 4139 | +napi_value NapiWebSchemeHandler::Init(napi_env env, napi_value exports) | ||
| 4140 | +{ | ||
| 4141 | + napi_property_descriptor properties[] = { | ||
| 4142 | + DECLARE_NAPI_FUNCTION("onRequestStart", JS_RequestStart), | ||
| 4143 | + DECLARE_NAPI_FUNCTION("onRequestStop", JS_RequestStop), | ||
| 4144 | + }; | ||
| 4145 | + napi_value webSchemeHandler = nullptr; | ||
| 4146 | + napi_define_class(env, WEB_SCHEME_HANDLER.c_str(), WEB_SCHEME_HANDLER.length(), | ||
| 4147 | + JS_Constructor, nullptr, | ||
| 4148 | + sizeof(properties) / sizeof(properties[0]), properties, &webSchemeHandler); | ||
| 4149 | + napi_set_named_property(env, exports, WEB_SCHEME_HANDLER.c_str(), | ||
| 4150 | + webSchemeHandler); | ||
| 4151 | + return exports; | ||
| 4152 | +} | ||
| 4153 | + | ||
| 4154 | +napi_value NapiWebSchemeHandler::JS_Constructor(napi_env env, napi_callback_info info) | ||
| 4155 | +{ | ||
| 4156 | + napi_value thisVar = nullptr; | ||
| 4157 | + void *data = nullptr; | ||
| 4158 | + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data); | ||
| 4159 | + | ||
| 4160 | + WebSchemeHandler *handler = new WebSchemeHandler(env); | ||
| 4161 | + | ||
| 4162 | + napi_wrap( | ||
| 4163 | + env, thisVar, handler, | ||
| 4164 | + [](napi_env /* env */, void *data, void * /* hint */) { | ||
| 4165 | + WebSchemeHandler *handler = (WebSchemeHandler *)data; | ||
| 4166 | + delete handler; | ||
| 4167 | + }, | ||
| 4168 | + nullptr, nullptr); | ||
| 4169 | + | ||
| 4170 | + return thisVar; | ||
| 4171 | +} | ||
| 4172 | + | ||
| 4173 | +napi_value NapiWebSchemeHandler::JS_RequestStart(napi_env env, napi_callback_info info) | ||
| 4174 | +{ | ||
| 4175 | + size_t argc = 1; | ||
| 4176 | + napi_value argv[1] = {0}; | ||
| 4177 | + napi_value thisVar = nullptr; | ||
| 4178 | + void *data = nullptr; | ||
| 4179 | + WebSchemeHandler *handler = nullptr; | ||
| 4180 | + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); | ||
| 4181 | + | ||
| 4182 | + napi_unwrap(env, thisVar, (void **)&handler); | ||
| 4183 | + if (!handler) { | ||
| 4184 | + LOGE("webSchemeHandler is null"); | ||
| 4185 | + return thisVar; | ||
| 4186 | + } | ||
| 4187 | + | ||
| 4188 | + napi_valuetype valueType = napi_undefined; | ||
| 4189 | + napi_typeof(env, argv[0], &valueType); | ||
| 4190 | + | ||
| 4191 | + if (argc != INTEGER_ONE) { | ||
| 4192 | + BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR, | ||
| 4193 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one")); | ||
| 4194 | + return nullptr; | ||
| 4195 | + } | ||
| 4196 | + if (valueType != napi_function) { | ||
| 4197 | + BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR, | ||
| 4198 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function")); | ||
| 4199 | + return nullptr; | ||
| 4200 | + } | ||
| 4201 | + | ||
| 4202 | + handler->PutRequestStart(env, argv[0]); | ||
| 4203 | + return thisVar; | ||
| 4204 | +} | ||
| 4205 | + | ||
| 4206 | +napi_value NapiWebSchemeHandler::JS_RequestStop(napi_env env, napi_callback_info info) | ||
| 4207 | +{ | ||
| 4208 | + size_t argc = 1; | ||
| 4209 | + napi_value argv[1] = {0}; | ||
| 4210 | + napi_value thisVar = nullptr; | ||
| 4211 | + void *data = nullptr; | ||
| 4212 | + WebSchemeHandler *handler = nullptr; | ||
| 4213 | + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); | ||
| 4214 | + if (argc != INTEGER_ONE) { | ||
| 4215 | + BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR); | ||
| 4216 | + return nullptr; | ||
| 4217 | + } | ||
| 4218 | + | ||
| 4219 | + napi_unwrap(env, thisVar, (void **)&handler); | ||
| 4220 | + if (!handler) { | ||
| 4221 | + LOGE("webSchemeHandler is null"); | ||
| 4222 | + return thisVar; | ||
| 4223 | + } | ||
| 4224 | + | ||
| 4225 | + napi_valuetype valueType = napi_undefined; | ||
| 4226 | + napi_typeof(env, argv[0], &valueType); | ||
| 4227 | + | ||
| 4228 | + if (valueType != napi_function) { | ||
| 4229 | + BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR); | ||
| 4230 | + return nullptr; | ||
| 4231 | + } | ||
| 4232 | + | ||
| 4233 | + handler->PutRequestStop(env, argv[0]); | ||
| 4234 | + return thisVar; | ||
| 4235 | +} | ||
| 4031 | } // namespace OHOS::Plugin | 4236 | } // namespace OHOS::Plugin |
| @@ -143,6 +143,12 @@ private: | |||
| 143 | static napi_value RegisterJavaScriptProxy(napi_env env, napi_callback_info info); | 143 | static napi_value RegisterJavaScriptProxy(napi_env env, napi_callback_info info); |
| 144 | 144 | ||
| 145 | static napi_value DeleteJavaScriptRegister(napi_env env, napi_callback_info info); | 145 | static napi_value DeleteJavaScriptRegister(napi_env env, napi_callback_info info); |
| 146 | + | ||
| 147 | + static napi_value SetWebSchemeHandler(napi_env env, napi_callback_info info); | ||
| 148 | + | ||
| 149 | + static napi_value ClearWebSchemeHandler(napi_env env, napi_callback_info info); | ||
| 150 | + | ||
| 151 | + static napi_value GetUserAgent(napi_env env, napi_callback_info info); | ||
| 146 | }; | 152 | }; |
| 147 | 153 | ||
| 148 | class NapiWebDataBase { | 154 | class NapiWebDataBase { |
| @@ -367,5 +373,16 @@ private: | |||
| 367 | static void CreateGetStoredGeolocationAsyncWork(napi_env env, | 373 | static void CreateGetStoredGeolocationAsyncWork(napi_env env, |
| 368 | const std::shared_ptr<GeolocationPermissionsResultCallbackInfo> &callbackInfo); | 374 | const std::shared_ptr<GeolocationPermissionsResultCallbackInfo> &callbackInfo); |
| 369 | }; | 375 | }; |
| 376 | + | ||
| 377 | +class NapiWebSchemeHandler { | ||
| 378 | +public: | ||
| 379 | + NapiWebSchemeHandler() = default; | ||
| 380 | + ~NapiWebSchemeHandler() = default; | ||
| 381 | + | ||
| 382 | + static napi_value Init(napi_env env, napi_value exports); | ||
| 383 | + static napi_value JS_Constructor(napi_env env, napi_callback_info info); | ||
| 384 | + static napi_value JS_RequestStart(napi_env env, napi_callback_info info); | ||
| 385 | + static napi_value JS_RequestStop(napi_env env, napi_callback_info info); | ||
| 386 | +}; | ||
| 370 | } | 387 | } |
| 371 | 388 | ||
| @@ -0,0 +1,1186 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | +namespace OHOS::Plugin { | ||
| 28 | +static const std::unordered_map<int32_t, std::string> g_netErrorCodeMap = { | ||
| 29 | + {ARKWEB_NET_OK, "NET_OK"}, | ||
| 30 | + {ARKWEB_ERR_IO_PENDING, "ERR_IO_PENDING"}, | ||
| 31 | + {ARKWEB_ERR_FAILED, "ERR_FAILED"}, | ||
| 32 | + {ARKWEB_ERR_ABORTED, "ERR_ABORTED"}, | ||
| 33 | + {ARKWEB_ERR_INVALID_ARGUMENT, "ERR_INVALID_ARGUMENT"}, | ||
| 34 | + {ARKWEB_ERR_INVALID_HANDLE, "ERR_INVALID_HANDLE"}, | ||
| 35 | + {ARKWEB_ERR_FILE_NOT_FOUND, "ERR_FILE_NOT_FOUND"}, | ||
| 36 | + {ARKWEB_ERR_TIMED_OUT, "ERR_TIMED_OUT"}, | ||
| 37 | + {ARKWEB_ERR_FILE_TOO_LARGE, "ERR_FILE_TOO_LARGE"}, | ||
| 38 | + {ARKWEB_ERR_UNEXPECTED, "ERR_UNEXPECTED"}, | ||
| 39 | + {ARKWEB_ERR_ACCESS_DENIED, "ERR_ACCESS_DENIED"}, | ||
| 40 | + {ARKWEB_ERR_NOT_IMPLEMENTED, "ERR_NOT_IMPLEMENTED"}, | ||
| 41 | + {ARKWEB_ERR_INSUFFICIENT_RESOURCES, "ERR_INSUFFICIENT_RESOURCES"}, | ||
| 42 | + {ARKWEB_ERR_OUT_OF_MEMORY, "ERR_OUT_OF_MEMORY"}, | ||
| 43 | + {ARKWEB_ERR_UPLOAD_FILE_CHANGED, "ERR_UPLOAD_FILE_CHANGED"}, | ||
| 44 | + {ARKWEB_ERR_SOCKET_NOT_CONNECTED, "ERR_SOCKET_NOT_CONNECTED"}, | ||
| 45 | + {ARKWEB_ERR_FILE_EXISTS, "ERR_FILE_EXISTS"}, | ||
| 46 | + {ARKWEB_ERR_FILE_PATH_TOO_LONG, "ERR_FILE_PATH_TOO_LONG"}, | ||
| 47 | + {ARKWEB_ERR_FILE_NO_SPACE, "ERR_FILE_NO_SPACE"}, | ||
| 48 | + {ARKWEB_ERR_FILE_VIRUS_INFECTED, "ERR_FILE_VIRUS_INFECTED"}, | ||
| 49 | + {ARKWEB_ERR_BLOCKED_BY_CLIENT, "ERR_BLOCKED_BY_CLIENT"}, | ||
| 50 | + {ARKWEB_ERR_NETWORK_CHANGED, "ERR_NETWORK_CHANGED"}, | ||
| 51 | + {ARKWEB_ERR_BLOCKED_BY_ADMINISTRATOR, "ERR_BLOCKED_BY_ADMINISTRATOR"}, | ||
| 52 | + {ARKWEB_ERR_SOCKET_CONNECTED, "ERR_SOCKET_CONNECTED"}, | ||
| 53 | + {ARKWEB_ERR_UPLOAD_STREAM_REWIND_NOT_SUPPORTED, "ERR_UPLOAD_STREAM_REWIND_NOT_SUPPORTED"}, | ||
| 54 | + {ARKWEB_ERR_CONTEXT_SHUT_DOWN, "ERR_CONTEXT_SHUT_DOWN"}, | ||
| 55 | + {ARKWEB_ERR_BLOCKED_BY_RESPONSE, "ERR_BLOCKED_BY_RESPONSE"}, | ||
| 56 | + {ARKWEB_ERR_CLEARTEXT_NOT_PERMITTED, "ERR_CLEARTEXT_NOT_PERMITTED"}, | ||
| 57 | + {ARKWEB_ERR_BLOCKED_BY_CSP, "ERR_BLOCKED_BY_CSP"}, | ||
| 58 | + {ARKWEB_ERR_H2_OR_QUIC_REQUIRED, "ERR_H2_OR_QUIC_REQUIRED"}, | ||
| 59 | + {ARKWEB_ERR_BLOCKED_BY_ORB, "ERR_BLOCKED_BY_ORB"}, | ||
| 60 | + {ARKWEB_ERR_CONNECTION_CLOSED, "ERR_CONNECTION_CLOSED"}, | ||
| 61 | + {ARKWEB_ERR_CONNECTION_RESET, "ERR_CONNECTION_RESET"}, | ||
| 62 | + {ARKWEB_ERR_CONNECTION_REFUSED, "ERR_CONNECTION_REFUSED"}, | ||
| 63 | + {ARKWEB_ERR_CONNECTION_ABORTED, "ERR_CONNECTION_ABORTED"}, | ||
| 64 | + {ARKWEB_ERR_CONNECTION_FAILED, "ERR_CONNECTION_FAILED"}, | ||
| 65 | + {ARKWEB_ERR_NAME_NOT_RESOLVED, "ERR_NAME_NOT_RESOLVED"}, | ||
| 66 | + {ARKWEB_ERR_INTERNET_DISCONNECTED, "ERR_INTERNET_DISCONNECTED"}, | ||
| 67 | + {ARKWEB_ERR_SSL_PROTOCOL_ERROR, "ERR_SSL_PROTOCOL_ERROR"}, | ||
| 68 | + {ARKWEB_ERR_ADDRESS_INVALID, "ERR_ADDRESS_INVALID"}, | ||
| 69 | + {ARKWEB_ERR_ADDRESS_UNREACHABLE, "ERR_ADDRESS_UNREACHABLE"}, | ||
| 70 | + {ARKWEB_ERR_SSL_CLIENT_AUTH_CERT_NEEDED, "ERR_SSL_CLIENT_AUTH_CERT_NEEDED"}, | ||
| 71 | + {ARKWEB_ERR_TUNNEL_CONNECTION_FAILED, "ERR_TUNNEL_CONNECTION_FAILED"}, | ||
| 72 | + {ARKWEB_ERR_NO_SSL_VERSIONS_ENABLED, "ERR_NO_SSL_VERSIONS_ENABLED"}, | ||
| 73 | + {ARKWEB_ERR_SSL_VERSION_OR_CIPHER_MISMATCH, "ERR_SSL_VERSION_OR_CIPHER_MISMATCH"}, | ||
| 74 | + {ARKWEB_ERR_SSL_RENEGOTIATION_REQUESTED, "ERR_SSL_RENEGOTIATION_REQUESTED"}, | ||
| 75 | + {ARKWEB_ERR_PROXY_AUTH_UNSUPPORTED, "ERR_PROXY_AUTH_UNSUPPORTED"}, | ||
| 76 | + {ARKWEB_ERR_BAD_SSL_CLIENT_AUTH_CERT, "ERR_BAD_SSL_CLIENT_AUTH_CERT"}, | ||
| 77 | + {ARKWEB_ERR_CONNECTION_TIMED_OUT, "ERR_CONNECTION_TIMED_OUT"}, | ||
| 78 | + {ARKWEB_ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, "ERR_HOST_RESOLVER_QUEUE_TOO_LARGE"}, | ||
| 79 | + {ARKWEB_ERR_SOCKS_CONNECTION_FAILED, "ERR_SOCKS_CONNECTION_FAILED"}, | ||
| 80 | + {ARKWEB_ERR_SOCKS_CONNECTION_HOST_UNREACHABLE, "ERR_SOCKS_CONNECTION_HOST_UNREACHABLE"}, | ||
| 81 | + {ARKWEB_ERR_ALPN_NEGOTIATION_FAILED, "ERR_ALPN_NEGOTIATION_FAILED"}, | ||
| 82 | + {ARKWEB_ERR_SSL_NO_RENEGOTIATION, "ERR_SSL_NO_RENEGOTIATION"}, | ||
| 83 | + {ARKWEB_ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES, "ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES"}, | ||
| 84 | + {ARKWEB_ERR_SSL_DECOMPRESSION_FAILURE_ALERT, "ERR_SSL_DECOMPRESSION_FAILURE_ALERT"}, | ||
| 85 | + {ARKWEB_ERR_SSL_BAD_RECORD_MAC_ALERT, "ERR_SSL_BAD_RECORD_MAC_ALERT"}, | ||
| 86 | + {ARKWEB_ERR_PROXY_AUTH_REQUESTED, "ERR_PROXY_AUTH_REQUESTED"}, | ||
| 87 | + {ARKWEB_ERR_PROXY_CONNECTION_FAILED, "ERR_PROXY_CONNECTION_FAILED"}, | ||
| 88 | + {ARKWEB_ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, "ERR_MANDATORY_PROXY_CONFIGURATION_FAILED"}, | ||
| 89 | + {ARKWEB_ERR_PRECONNECT_MAX_SOCKET_LIMIT, "ERR_PRECONNECT_MAX_SOCKET_LIMIT"}, | ||
| 90 | + {ARKWEB_ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED, "ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED"}, | ||
| 91 | + {ARKWEB_ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY, "ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY"}, | ||
| 92 | + {ARKWEB_ERR_PROXY_CERTIFICATE_INVALID, "ERR_PROXY_CERTIFICATE_INVALID"}, | ||
| 93 | + {ARKWEB_ERR_NAME_RESOLUTION_FAILED, "ERR_NAME_RESOLUTION_FAILED"}, | ||
| 94 | + {ARKWEB_ERR_NETWORK_ACCESS_DENIED, "ERR_NETWORK_ACCESS_DENIED"}, | ||
| 95 | + {ARKWEB_ERR_TEMPORARILY_THROTTLED, "ERR_TEMPORARILY_THROTTLED"}, | ||
| 96 | + {ARKWEB_ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT, "ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT"}, | ||
| 97 | + {ARKWEB_ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED, "ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED"}, | ||
| 98 | + {ARKWEB_ERR_MSG_TOO_BIG, "ERR_MSG_TOO_BIG"}, | ||
| 99 | + {ARKWEB_ERR_WS_PROTOCOL_ERROR, "ERR_WS_PROTOCOL_ERROR"}, | ||
| 100 | + {ARKWEB_ERR_ADDRESS_IN_USE, "ERR_ADDRESS_IN_USE"}, | ||
| 101 | + {ARKWEB_ERR_SSL_HANDSHAKE_NOT_COMPLETED, "ERR_SSL_HANDSHAKE_NOT_COMPLETED"}, | ||
| 102 | + {ARKWEB_ERR_SSL_BAD_PEER_PUBLIC_KEY, "ERR_SSL_BAD_PEER_PUBLIC_KEY"}, | ||
| 103 | + {ARKWEB_ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN, "ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN"}, | ||
| 104 | + {ARKWEB_ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, "ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED"}, | ||
| 105 | + {ARKWEB_ERR_SSL_DECRYPT_ERROR_ALERT, "ERR_SSL_DECRYPT_ERROR_ALERT"}, | ||
| 106 | + {ARKWEB_ERR_WS_THROTTLE_QUEUE_TOO_LARGE, "ERR_WS_THROTTLE_QUEUE_TOO_LARGE"}, | ||
| 107 | + {ARKWEB_ERR_SSL_SERVER_CERT_CHANGED, "ERR_SSL_SERVER_CERT_CHANGED"}, | ||
| 108 | + {ARKWEB_ERR_SSL_UNRECOGNIZED_NAME_ALERT, "ERR_SSL_UNRECOGNIZED_NAME_ALERT"}, | ||
| 109 | + {ARKWEB_ERR_SOCKET_SET_RECEIVE_BUFFER_SIZE_ERROR, "ERR_SOCKET_SET_RECEIVE_BUFFER_SIZE_ERROR"}, | ||
| 110 | + {ARKWEB_ERR_SOCKET_SET_SEND_BUFFER_SIZE_ERROR, "ERR_SOCKET_SET_SEND_BUFFER_SIZE_ERROR"}, | ||
| 111 | + {ARKWEB_ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE, "ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE"}, | ||
| 112 | + {ARKWEB_ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE, "ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE"}, | ||
| 113 | + {ARKWEB_ERR_SSL_CLIENT_AUTH_CERT_BAD_FORMAT, "ERR_SSL_CLIENT_AUTH_CERT_BAD_FORMAT"}, | ||
| 114 | + {ARKWEB_ERR_ICANN_NAME_COLLISION, "ERR_ICANN_NAME_COLLISION"}, | ||
| 115 | + {ARKWEB_ERR_SSL_SERVER_CERT_BAD_FORMAT, "ERR_SSL_SERVER_CERT_BAD_FORMAT"}, | ||
| 116 | + {ARKWEB_ERR_CT_STH_PARSING_FAILED, "ERR_CT_STH_PARSING_FAILED"}, | ||
| 117 | + {ARKWEB_ERR_CT_STH_INCOMPLETE, "ERR_CT_STH_INCOMPLETE"}, | ||
| 118 | + {ARKWEB_ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH, "ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH"}, | ||
| 119 | + {ARKWEB_ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED, "ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED"}, | ||
| 120 | + {ARKWEB_ERR_SSL_OBSOLETE_CIPHER, "ERR_SSL_OBSOLETE_CIPHER"}, | ||
| 121 | + {ARKWEB_ERR_WS_UPGRADE, "ERR_WS_UPGRADE"}, | ||
| 122 | + {ARKWEB_ERR_READ_IF_READY_NOT_IMPLEMENTED, "ERR_READ_IF_READY_NOT_IMPLEMENTED"}, | ||
| 123 | + {ARKWEB_ERR_NO_BUFFER_SPACE, "ERR_NO_BUFFER_SPACE"}, | ||
| 124 | + {ARKWEB_ERR_SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS, "ERR_SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS"}, | ||
| 125 | + {ARKWEB_ERR_EARLY_DATA_REJECTED, "ERR_EARLY_DATA_REJECTED"}, | ||
| 126 | + {ARKWEB_ERR_WRONG_VERSION_ON_EARLY_DATA, "ERR_WRONG_VERSION_ON_EARLY_DATA"}, | ||
| 127 | + {ARKWEB_ERR_TLS13_DOWNGRADE_DETECTED, "ERR_TLS13_DOWNGRADE_DETECTED"}, | ||
| 128 | + {ARKWEB_ERR_SSL_KEY_USAGE_INCOMPATIBLE, "ERR_SSL_KEY_USAGE_INCOMPATIBLE"}, | ||
| 129 | + {ARKWEB_ERR_INVALID_ECH_CONFIG_LIST, "ERR_INVALID_ECH_CONFIG_LIST"}, | ||
| 130 | + {ARKWEB_ERR_ECH_NOT_NEGOTIATED, "ERR_ECH_NOT_NEGOTIATED"}, | ||
| 131 | + {ARKWEB_ERR_ECH_FALLBACK_CERTIFICATE_INVALID, "ERR_ECH_FALLBACK_CERTIFICATE_INVALID"}, | ||
| 132 | + {ARKWEB_ERR_CERT_COMMON_NAME_INVALID, "ERR_CERT_COMMON_NAME_INVALID"}, | ||
| 133 | + {ARKWEB_ERR_CERT_DATE_INVALID, "ERR_CERT_DATE_INVALID"}, | ||
| 134 | + {ARKWEB_ERR_CERT_AUTHORITY_INVALID, "ERR_CERT_AUTHORITY_INVALID"}, | ||
| 135 | + {ARKWEB_ERR_CERT_CONTAINS_ERRORS, "ERR_CERT_CONTAINS_ERRORS"}, | ||
| 136 | + {ARKWEB_ERR_CERT_NO_REVOCATION_MECHANISM, "ERR_CERT_NO_REVOCATION_MECHANISM"}, | ||
| 137 | + {ARKWEB_ERR_CERT_UNABLE_TO_CHECK_REVOCATION, "ERR_CERT_UNABLE_TO_CHECK_REVOCATION"}, | ||
| 138 | + {ARKWEB_ERR_CERT_REVOKED, "ERR_CERT_REVOKED"}, | ||
| 139 | + {ARKWEB_ERR_CERT_INVALID, "ERR_CERT_INVALID"}, | ||
| 140 | + {ARKWEB_ERR_CERT_WEAK_SIGNATURE_ALGORITHM, "ERR_CERT_WEAK_SIGNATURE_ALGORITHM"}, | ||
| 141 | + {ARKWEB_ERR_CERT_NON_UNIQUE_NAME, "ERR_CERT_NON_UNIQUE_NAME"}, | ||
| 142 | + {ARKWEB_ERR_CERT_WEAK_KEY, "ERR_CERT_WEAK_KEY"}, | ||
| 143 | + {ARKWEB_ERR_CERT_NAME_CONSTRAINT_VIOLATION, "ERR_CERT_NAME_CONSTRAINT_VIOLATION"}, | ||
| 144 | + {ARKWEB_ERR_CERT_VALIDITY_TOO_LONG, "ERR_CERT_VALIDITY_TOO_LONG"}, | ||
| 145 | + {ARKWEB_ERR_CERTIFICATE_TRANSPARENCY_REQUIRED, "ERR_CERTIFICATE_TRANSPARENCY_REQUIRED"}, | ||
| 146 | + {ARKWEB_ERR_CERT_SYMANTEC_LEGACY, "ERR_CERT_SYMANTEC_LEGACY"}, | ||
| 147 | + {ARKWEB_ERR_CERT_KNOWN_INTERCEPTION_BLOCKED, "ERR_CERT_KNOWN_INTERCEPTION_BLOCKED"}, | ||
| 148 | + {ARKWEB_ERR_SSL_OBSOLETE_VERSION_OR_CIPHER, "ERR_SSL_OBSOLETE_VERSION_OR_CIPHER"}, | ||
| 149 | + {ARKWEB_ERR_CERT_END, "ERR_CERT_END"}, | ||
| 150 | + {ARKWEB_ERR_INVALID_URL, "ERR_INVALID_URL"}, | ||
| 151 | + {ARKWEB_ERR_DISALLOWED_URL_SCHEME, "ERR_DISALLOWED_URL_SCHEME"}, | ||
| 152 | + {ARKWEB_ERR_UNKNOWN_URL_SCHEME, "ERR_UNKNOWN_URL_SCHEME"}, | ||
| 153 | + {ARKWEB_ERR_INVALID_REDIRECT, "ERR_INVALID_REDIRECT"}, | ||
| 154 | + {ARKWEB_ERR_TOO_MANY_REDIRECTS, "ERR_TOO_MANY_REDIRECTS"}, | ||
| 155 | + {ARKWEB_ERR_UNSAFE_REDIRECT, "ERR_UNSAFE_REDIRECT"}, | ||
| 156 | + {ARKWEB_ERR_UNSAFE_PORT, "ERR_UNSAFE_PORT"}, | ||
| 157 | + {ARKWEB_ERR_INVALID_RESPONSE, "ERR_INVALID_RESPONSE"}, | ||
| 158 | + {ARKWEB_ERR_INVALID_CHUNKED_ENCODING, "ERR_INVALID_CHUNKED_ENCODING"}, | ||
| 159 | + {ARKWEB_ERR_METHOD_UNSUPPORTED, "ERR_METHOD_UNSUPPORTED"}, | ||
| 160 | + {ARKWEB_ERR_UNEXPECTED_PROXY_AUTH, "ERR_UNEXPECTED_PROXY_AUTH"}, | ||
| 161 | + {ARKWEB_ERR_EMPTY_RESPONSE, "ERR_EMPTY_RESPONSE"}, | ||
| 162 | + {ARKWEB_ERR_RESPONSE_HEADERS_TOO_BIG, "ERR_RESPONSE_HEADERS_TOO_BIG"}, | ||
| 163 | + {ARKWEB_ERR_PAC_SCRIPT_FAILED, "ERR_PAC_SCRIPT_FAILED"}, | ||
| 164 | + {ARKWEB_ERR_REQUEST_RANGE_NOT_SATISFIABLE, "ERR_REQUEST_RANGE_NOT_SATISFIABLE"}, | ||
| 165 | + {ARKWEB_ERR_MALFORMED_IDENTITY, "ERR_MALFORMED_IDENTITY"}, | ||
| 166 | + {ARKWEB_ERR_CONTENT_DECODING_FAILED, "ERR_CONTENT_DECODING_FAILED"}, | ||
| 167 | + {ARKWEB_ERR_NETWORK_IO_SUSPENDED, "ERR_NETWORK_IO_SUSPENDED"}, | ||
| 168 | + {ARKWEB_ERR_SYN_REPLY_NOT_RECEIVED, "ERR_SYN_REPLY_NOT_RECEIVED"}, | ||
| 169 | + {ARKWEB_ERR_ENCODING_CONVERSION_FAILED, "ERR_ENCODING_CONVERSION_FAILED"}, | ||
| 170 | + {ARKWEB_ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT, "ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT"}, | ||
| 171 | + {ARKWEB_ERR_NO_SUPPORTED_PROXIES, "ERR_NO_SUPPORTED_PROXIES"}, | ||
| 172 | + {ARKWEB_ERR_HTTP2_PROTOCOL_ERROR, "ERR_HTTP2_PROTOCOL_ERROR"}, | ||
| 173 | + {ARKWEB_ERR_INVALID_AUTH_CREDENTIALS, "ERR_INVALID_AUTH_CREDENTIALS"}, | ||
| 174 | + {ARKWEB_ERR_UNSUPPORTED_AUTH_SCHEME, "ERR_UNSUPPORTED_AUTH_SCHEME"}, | ||
| 175 | + {ARKWEB_ERR_ENCODING_DETECTION_FAILED, "ERR_ENCODING_DETECTION_FAILED"}, | ||
| 176 | + {ARKWEB_ERR_MISSING_AUTH_CREDENTIALS, "ERR_MISSING_AUTH_CREDENTIALS"}, | ||
| 177 | + {ARKWEB_ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS, "ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS"}, | ||
| 178 | + {ARKWEB_ERR_MISCONFIGURED_AUTH_ENVIRONMENT, "ERR_MISCONFIGURED_AUTH_ENVIRONMENT"}, | ||
| 179 | + {ARKWEB_ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS, "ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS"}, | ||
| 180 | + {ARKWEB_ERR_RESPONSE_BODY_TOO_BIG_TO_DRAIN, "ERR_RESPONSE_BODY_TOO_BIG_TO_DRAIN"}, | ||
| 181 | + {ARKWEB_ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, "ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH"}, | ||
| 182 | + {ARKWEB_ERR_INCOMPLETE_HTTP2_HEADERS, "ERR_INCOMPLETE_HTTP2_HEADERS"}, | ||
| 183 | + {ARKWEB_ERR_PAC_NOT_IN_DHCP, "ERR_PAC_NOT_IN_DHCP"}, | ||
| 184 | + {ARKWEB_ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, "ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION"}, | ||
| 185 | + {ARKWEB_ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, "ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION"}, | ||
| 186 | + {ARKWEB_ERR_HTTP2_SERVER_REFUSED_STREAM, "ERR_HTTP2_SERVER_REFUSED_STREAM"}, | ||
| 187 | + {ARKWEB_ERR_HTTP2_PING_FAILED, "ERR_HTTP2_PING_FAILED"}, | ||
| 188 | + {ARKWEB_ERR_CONTENT_LENGTH_MISMATCH, "ERR_CONTENT_LENGTH_MISMATCH"}, | ||
| 189 | + {ARKWEB_ERR_INCOMPLETE_CHUNKED_ENCODING, "ERR_INCOMPLETE_CHUNKED_ENCODING"}, | ||
| 190 | + {ARKWEB_ERR_QUIC_PROTOCOL_ERROR, "ERR_QUIC_PROTOCOL_ERROR"}, | ||
| 191 | + {ARKWEB_ERR_RESPONSE_HEADERS_TRUNCATED, "ERR_RESPONSE_HEADERS_TRUNCATED"}, | ||
| 192 | + {ARKWEB_ERR_QUIC_HANDSHAKE_FAILED, "ERR_QUIC_HANDSHAKE_FAILED"}, | ||
| 193 | + {ARKWEB_ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY, "ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY"}, | ||
| 194 | + {ARKWEB_ERR_HTTP2_FLOW_CONTROL_ERROR, "ERR_HTTP2_FLOW_CONTROL_ERROR"}, | ||
| 195 | + {ARKWEB_ERR_HTTP2_FRAME_SIZE_ERROR, "ERR_HTTP2_FRAME_SIZE_ERROR"}, | ||
| 196 | + {ARKWEB_ERR_HTTP2_COMPRESSION_ERROR, "ERR_HTTP2_COMPRESSION_ERROR"}, | ||
| 197 | + {ARKWEB_ERR_PROXY_AUTH_REQUESTED_WITH_NO_CONNECTION, "ERR_PROXY_AUTH_REQUESTED_WITH_NO_CONNECTION"}, | ||
| 198 | + {ARKWEB_ERR_HTTP_1_1_REQUIRED, "ERR_HTTP_1_1_REQUIRED"}, | ||
| 199 | + {ARKWEB_ERR_PROXY_HTTP_1_1_REQUIRED, "ERR_PROXY_HTTP_1_1_REQUIRED"}, | ||
| 200 | + {ARKWEB_ERR_PAC_SCRIPT_TERMINATED, "ERR_PAC_SCRIPT_TERMINATED"}, | ||
| 201 | + {ARKWEB_ERR_INVALID_HTTP_RESPONSE, "ERR_INVALID_HTTP_RESPONSE"}, | ||
| 202 | + {ARKWEB_ERR_CONTENT_DECODING_INIT_FAILED, "ERR_CONTENT_DECODING_INIT_FAILED"}, | ||
| 203 | + {ARKWEB_ERR_HTTP2_RST_STREAM_NO_ERROR_RECEIVED, "ERR_HTTP2_RST_STREAM_NO_ERROR_RECEIVED"}, | ||
| 204 | + {ARKWEB_ERR_HTTP2_PUSHED_STREAM_NOT_AVAILABLE, "ERR_HTTP2_PUSHED_STREAM_NOT_AVAILABLE"}, | ||
| 205 | + {ARKWEB_ERR_HTTP2_CLAIMED_PUSHED_STREAM_RESET_BY_SERVER, "ERR_HTTP2_CLAIMED_PUSHED_STREAM_RESET_BY_SERVER"}, | ||
| 206 | + {ARKWEB_ERR_TOO_MANY_RETRIES, "ERR_TOO_MANY_RETRIES"}, | ||
| 207 | + {ARKWEB_ERR_HTTP2_STREAM_CLOSED, "ERR_HTTP2_STREAM_CLOSED"}, | ||
| 208 | + {ARKWEB_ERR_HTTP2_CLIENT_REFUSED_STREAM, "ERR_HTTP2_CLIENT_REFUSED_STREAM"}, | ||
| 209 | + {ARKWEB_ERR_HTTP2_PUSHED_RESPONSE_DOES_NOT_MATCH, "ERR_HTTP2_PUSHED_RESPONSE_DOES_NOT_MATCH"}, | ||
| 210 | + {ARKWEB_ERR_HTTP_RESPONSE_CODE_FAILURE, "ERR_HTTP_RESPONSE_CODE_FAILURE"}, | ||
| 211 | + {ARKWEB_ERR_QUIC_UNKNOWN_CERT_ROOT, "ERR_QUIC_UNKNOWN_CERT_ROOT"}, | ||
| 212 | + {ARKWEB_ERR_QUIC_GOAWAY_REQUEST_CAN_BE_RETRIED, "ERR_QUIC_GOAWAY_REQUEST_CAN_BE_RETRIED"}, | ||
| 213 | + {ARKWEB_ERR_TOO_MANY_ACCEPT_CH_RESTARTS, "ERR_TOO_MANY_ACCEPT_CH_RESTARTS"}, | ||
| 214 | + {ARKWEB_ERR_INCONSISTENT_IP_ADDRESS_SPACE, "ERR_INCONSISTENT_IP_ADDRESS_SPACE"}, | ||
| 215 | + {ARKWEB_ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_LOCAL_NETWORK_ACCESS_POLICY, | ||
| 216 | + "ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_LOCAL_NETWORK_ACCESS_POLICY"}, | ||
| 217 | + {ARKWEB_ERR_CACHE_MISS, "ERR_CACHE_MISS"}, | ||
| 218 | + {ARKWEB_ERR_CACHE_READ_FAILURE, "ERR_CACHE_READ_FAILURE"}, | ||
| 219 | + {ARKWEB_ERR_CACHE_WRITE_FAILURE, "ERR_CACHE_WRITE_FAILURE"}, | ||
| 220 | + {ARKWEB_ERR_CACHE_OPERATION_UNSUPPORTED, "ERR_CACHE_OPERATION_UNSUPPORTED"}, | ||
| 221 | + {ARKWEB_ERR_CACHE_OPEN_FAILURE, "ERR_CACHE_OPEN_FAILURE"}, | ||
| 222 | + {ARKWEB_ERR_CACHE_CREATE_FAILURE, "ERR_CACHE_CREATE_FAILURE"}, | ||
| 223 | + {ARKWEB_ERR_CACHE_RACE, "ERR_CACHE_RACE"}, | ||
| 224 | + {ARKWEB_ERR_CACHE_CHECKSUM_READ_FAILURE, "ERR_CACHE_CHECKSUM_READ_FAILURE"}, | ||
| 225 | + {ARKWEB_ERR_CACHE_CHECKSUM_MISMATCH, "ERR_CACHE_CHECKSUM_MISMATCH"}, | ||
| 226 | + {ARKWEB_ERR_CACHE_LOCK_TIMEOUT, "ERR_CACHE_LOCK_TIMEOUT"}, | ||
| 227 | + {ARKWEB_ERR_CACHE_AUTH_FAILURE_AFTER_READ, "ERR_CACHE_AUTH_FAILURE_AFTER_READ"}, | ||
| 228 | + {ARKWEB_ERR_CACHE_ENTRY_NOT_SUITABLE, "ERR_CACHE_ENTRY_NOT_SUITABLE"}, | ||
| 229 | + {ARKWEB_ERR_CACHE_DOOM_FAILURE, "ERR_CACHE_DOOM_FAILURE"}, | ||
| 230 | + {ARKWEB_ERR_CACHE_OPEN_OR_CREATE_FAILURE, "ERR_CACHE_OPEN_OR_CREATE_FAILURE"}, | ||
| 231 | + {ARKWEB_ERR_INSECURE_RESPONSE, "ERR_INSECURE_RESPONSE"}, | ||
| 232 | + {ARKWEB_ERR_NO_PRIVATE_KEY_FOR_CERT, "ERR_NO_PRIVATE_KEY_FOR_CERT"}, | ||
| 233 | + {ARKWEB_ERR_ADD_USER_CERT_FAILED, "ERR_ADD_USER_CERT_FAILED"}, | ||
| 234 | + {ARKWEB_ERR_INVALID_SIGNED_EXCHANGE, "ERR_INVALID_SIGNED_EXCHANGE"}, | ||
| 235 | + {ARKWEB_ERR_INVALID_WEB_BUNDLE, "ERR_INVALID_WEB_BUNDLE"}, | ||
| 236 | + {ARKWEB_ERR_TRUST_TOKEN_OPERATION_FAILED, "ERR_TRUST_TOKEN_OPERATION_FAILED"}, | ||
| 237 | + {ARKWEB_ERR_TRUST_TOKEN_OPERATION_SUCCESS_WITHOUT_SENDING_REQUEST, | ||
| 238 | + "ERR_TRUST_TOKEN_OPERATION_SUCCESS_WITHOUT_SENDING_REQUEST"}, | ||
| 239 | + {ARKWEB_ERR_FTP_FAILED, "ERR_FTP_FAILED"}, | ||
| 240 | + {ARKWEB_ERR_FTP_SERVICE_UNAVAILABLE, "ERR_FTP_SERVICE_UNAVAILABLE"}, | ||
| 241 | + {ARKWEB_ERR_FTP_TRANSFER_ABORTED, "ERR_FTP_TRANSFER_ABORTED"}, | ||
| 242 | + {ARKWEB_ERR_FTP_FILE_BUSY, "ERR_FTP_FILE_BUSY"}, | ||
| 243 | + {ARKWEB_ERR_FTP_SYNTAX_ERROR, "ERR_FTP_SYNTAX_ERROR"}, | ||
| 244 | + {ARKWEB_ERR_FTP_COMMAND_UNSUPPORTED, "ERR_FTP_COMMAND_UNSUPPORTED"}, | ||
| 245 | + {ARKWEB_ERR_FTP_BAD_COMMAND_SEQUENCE, "ERR_FTP_BAD_COMMAND_SEQUENCE"}, | ||
| 246 | + {ARKWEB_ERR_PKCS12_IMPORT_BAD_PASSWORD, "ERR_PKCS12_IMPORT_BAD_PASSWORD"}, | ||
| 247 | + {ARKWEB_ERR_PKCS12_IMPORT_FAILED, "ERR_PKCS12_IMPORT_FAILED"}, | ||
| 248 | + {ARKWEB_ERR_IMPORT_CA_CERT_NOT_CA, "ERR_IMPORT_CA_CERT_NOT_CA"}, | ||
| 249 | + {ARKWEB_ERR_IMPORT_CERT_ALREADY_EXISTS, "ERR_IMPORT_CERT_ALREADY_EXISTS"}, | ||
| 250 | + {ARKWEB_ERR_IMPORT_CA_CERT_FAILED, "ERR_IMPORT_CA_CERT_FAILED"}, | ||
| 251 | + {ARKWEB_ERR_IMPORT_SERVER_CERT_FAILED, "ERR_IMPORT_SERVER_CERT_FAILED"}, | ||
| 252 | + {ARKWEB_ERR_PKCS12_IMPORT_INVALID_MAC, "ERR_PKCS12_IMPORT_INVALID_MAC"}, | ||
| 253 | + {ARKWEB_ERR_PKCS12_IMPORT_INVALID_FILE, "ERR_PKCS12_IMPORT_INVALID_FILE"}, | ||
| 254 | + {ARKWEB_ERR_PKCS12_IMPORT_UNSUPPORTED, "ERR_PKCS12_IMPORT_UNSUPPORTED"}, | ||
| 255 | + {ARKWEB_ERR_KEY_GENERATION_FAILED, "ERR_KEY_GENERATION_FAILED"}, | ||
| 256 | + {ARKWEB_ERR_PRIVATE_KEY_EXPORT_FAILED, "ERR_PRIVATE_KEY_EXPORT_FAILED"}, | ||
| 257 | + {ARKWEB_ERR_SELF_SIGNED_CERT_GENERATION_FAILED, "ERR_SELF_SIGNED_CERT_GENERATION_FAILED"}, | ||
| 258 | + {ARKWEB_ERR_CERT_DATABASE_CHANGED, "ERR_CERT_DATABASE_CHANGED"}, | ||
| 259 | + {ARKWEB_ERR_CERT_VERIFIER_CHANGED, "ERR_CERT_VERIFIER_CHANGED"}, | ||
| 260 | + {ARKWEB_ERR_DNS_MALFORMED_RESPONSE, "ERR_DNS_MALFORMED_RESPONSE"}, | ||
| 261 | + {ARKWEB_ERR_DNS_SERVER_REQUIRES_TCP, "ERR_DNS_SERVER_REQUIRES_TCP"}, | ||
| 262 | + {ARKWEB_ERR_DNS_SERVER_FAILED, "ERR_DNS_SERVER_FAILED"}, | ||
| 263 | + {ARKWEB_ERR_DNS_TIMED_OUT, "ERR_DNS_TIMED_OUT"}, | ||
| 264 | + {ARKWEB_ERR_DNS_CACHE_MISS, "ERR_DNS_CACHE_MISS"}, | ||
| 265 | + {ARKWEB_ERR_DNS_SEARCH_EMPTY, "ERR_DNS_SEARCH_EMPTY"}, | ||
| 266 | + {ARKWEB_ERR_DNS_SORT_ERROR, "ERR_DNS_SORT_ERROR"}, | ||
| 267 | + {ARKWEB_ERR_DNS_SECURE_RESOLVER_HOSTNAME_RESOLUTION_FAILED, "ERR_DNS_SECURE_RESOLVER_HOSTNAME_RESOLUTION_FAILED"}, | ||
| 268 | + {ARKWEB_ERR_DNS_NAME_HTTPS_ONLY, "ERR_DNS_NAME_HTTPS_ONLY"}, | ||
| 269 | + {ARKWEB_ERR_DNS_REQUEST_CANCELED, "ERR_DNS_REQUEST_CANCELED"}, | ||
| 270 | + {ARKWEB_ERR_DNS_NO_MATCHING_SUPPORTED_ALPN, "ERR_DNS_NO_MATCHING_SUPPORTED_ALPN"} | ||
| 271 | +}; | ||
| 272 | + | ||
| 273 | +struct NetErrorInfo { | ||
| 274 | + bool isValid; | ||
| 275 | + std::string errorName; | ||
| 276 | + | ||
| 277 | + explicit NetErrorInfo(bool valid = false, const std::string& name = "") : isValid(valid), errorName(name) {} | ||
| 278 | +}; | ||
| 279 | + | ||
| 280 | +NetErrorInfo ValidateAndGetNetErrorName(int32_t code) | ||
| 281 | +{ | ||
| 282 | + auto it = g_netErrorCodeMap.find(code); | ||
| 283 | + if (it != g_netErrorCodeMap.end()) { | ||
| 284 | + return NetErrorInfo(true, it->second); | ||
| 285 | + } | ||
| 286 | + return NetErrorInfo(false, "UNKNOWN_ERROR_CODE"); | ||
| 287 | +} | ||
| 288 | + | ||
| 289 | +napi_value NapiWebSchemeHandlerRequest::Init(napi_env env, napi_value exports) | ||
| 290 | +{ | ||
| 291 | + ExportWebSchemeHandlerRequestClass(env, &exports); | ||
| 292 | + return exports; | ||
| 293 | +} | ||
| 294 | + | ||
| 295 | +void NapiWebSchemeHandlerRequest::ExportWebSchemeHandlerRequestClass(napi_env env, napi_value* exportsPointer) | ||
与下面DefineProperties函数中定义的一致?考虑合并 ![]() ![]() | |||
| 296 | +{ | ||
| 297 | + napi_property_descriptor properties[] = { | ||
| 298 | + DECLARE_NAPI_FUNCTION("getHeader", JS_GetHeader), | ||
| 299 | + DECLARE_NAPI_FUNCTION("getRequestUrl", JS_GetRequestUrl), | ||
| 300 | + DECLARE_NAPI_FUNCTION("getRequestMethod", JS_GetRequestMethod), | ||
| 301 | + DECLARE_NAPI_FUNCTION("getReferrer", JS_GetReferrer), | ||
| 302 | + DECLARE_NAPI_FUNCTION("isRedirect", JS_IsRedirect), | ||
| 303 | + DECLARE_NAPI_FUNCTION("isMainFrame", JS_IsMainFrame), | ||
| 304 | + DECLARE_NAPI_FUNCTION("hasGesture", JS_HasGesture), | ||
| 305 | + DECLARE_NAPI_FUNCTION("getHttpBodyStream", JS_HttpBodyStream), | ||
| 306 | + DECLARE_NAPI_FUNCTION("getRequestResourceType", JS_GetRequestResourceType), | ||
| 307 | + DECLARE_NAPI_FUNCTION("getFrameUrl", JS_GetFrameUrl), | ||
| 308 | + }; | ||
| 309 | + napi_value webSchemeHandlerRequest = nullptr; | ||
| 310 | + napi_define_class(env, WEB_SCHEME_HANDLER_REQUEST.c_str(), WEB_SCHEME_HANDLER_REQUEST.length(), JS_Constructor, | ||
| 311 | + nullptr, sizeof(properties) / sizeof(properties[0]), properties, &webSchemeHandlerRequest); | ||
| 312 | + napi_set_named_property(env, *exportsPointer, WEB_SCHEME_HANDLER_REQUEST.c_str(), webSchemeHandlerRequest); | ||
| 313 | +} | ||
| 314 | + | ||
| 315 | +napi_status NapiWebSchemeHandlerRequest::DefineProperties(napi_env env, napi_value* object) | ||
| 316 | +{ | ||
| 317 | + napi_property_descriptor properties[] = { | ||
| 318 | + DECLARE_NAPI_FUNCTION("getHeader", JS_GetHeader), | ||
| 319 | + DECLARE_NAPI_FUNCTION("getRequestUrl", JS_GetRequestUrl), | ||
| 320 | + DECLARE_NAPI_FUNCTION("getRequestMethod", JS_GetRequestMethod), | ||
| 321 | + DECLARE_NAPI_FUNCTION("getReferrer", JS_GetReferrer), | ||
| 322 | + DECLARE_NAPI_FUNCTION("isRedirect", JS_IsRedirect), | ||
| 323 | + DECLARE_NAPI_FUNCTION("isMainFrame", JS_IsMainFrame), | ||
| 324 | + DECLARE_NAPI_FUNCTION("hasGesture", JS_HasGesture), | ||
| 325 | + DECLARE_NAPI_FUNCTION("getHttpBodyStream", JS_HttpBodyStream), | ||
| 326 | + DECLARE_NAPI_FUNCTION("getRequestResourceType", JS_GetRequestResourceType), | ||
| 327 | + DECLARE_NAPI_FUNCTION("getFrameUrl", JS_GetFrameUrl), | ||
| 328 | + }; | ||
| 329 | + return napi_define_properties(env, *object, sizeof(properties) / sizeof(properties[0]), properties); | ||
| 330 | +} | ||
| 331 | + | ||
| 332 | +napi_value NapiWebSchemeHandlerRequest::JS_Constructor(napi_env env, napi_callback_info cbinfo) | ||
| 333 | +{ | ||
| 334 | + napi_value thisVar = nullptr; | ||
| 335 | + void* data = nullptr; | ||
| 336 | + napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, &data); | ||
| 337 | + | ||
| 338 | + WebSchemeHandlerRequest* request = new (std::nothrow) WebSchemeHandlerRequest(env); | ||
| 339 | + if (request == nullptr) { | ||
| 340 | + return nullptr; | ||
| 341 | + } | ||
| 342 | + | ||
| 343 | + napi_wrap( | ||
| 344 | + env, thisVar, request, | ||
| 345 | + [](napi_env /* env */, void* data, void* /* hint */) { | ||
| 346 | + WebSchemeHandlerRequest* request = reinterpret_cast<WebSchemeHandlerRequest*>(data); | ||
| 347 | + delete request; | ||
| 348 | + }, | ||
| 349 | + nullptr, nullptr); | ||
| 350 | + | ||
| 351 | + return thisVar; | ||
| 352 | +} | ||
| 353 | + | ||
| 354 | +napi_value NapiWebSchemeHandlerRequest::JS_GetHeader(napi_env env, napi_callback_info cbinfo) | ||
| 355 | +{ | ||
| 356 | + napi_value thisVar = nullptr; | ||
| 357 | + void* data = nullptr; | ||
| 358 | + WebSchemeHandlerRequest* request = nullptr; | ||
| 359 | + napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, &data); | ||
| 360 | + | ||
| 361 | + napi_unwrap(env, thisVar, (void**)&request); | ||
| 362 | + if (!request) { | ||
| 363 | + LOGE("NapiWebSchemeHandlerRequest::JS_GetHeader request is nullptr"); | ||
| 364 | + return nullptr; | ||
| 365 | + } | ||
| 366 | + | ||
| 367 | + napi_handle_scope scope; | ||
| 368 | + napi_status status_scope = napi_open_handle_scope(env, &scope); | ||
| 369 | + if (status_scope != napi_ok) { | ||
| 370 | + LOGE("scheme handler RequestStart scope is nullptr"); | ||
| 371 | + return nullptr; | ||
| 372 | + } | ||
| 373 | + WebHeaderList list = request->GetHeaderList(); | ||
| 374 | + napi_value result = nullptr; | ||
| 375 | + napi_create_array(env, &result); | ||
| 376 | + size_t headerSize = list.size(); | ||
| 377 | + for (size_t index = 0; index < headerSize; index++) { | ||
| 378 | + napi_value webHeaderObj = nullptr; | ||
| 379 | + napi_value headerKey = nullptr; | ||
| 380 | + napi_value headerValue = nullptr; | ||
| 381 | + NAPI_CALL(env, napi_create_object(env, &webHeaderObj)); | ||
| 382 | + napi_create_string_utf8(env, list[index].first.c_str(), NAPI_AUTO_LENGTH, &headerKey); | ||
| 383 | + napi_create_string_utf8(env, list[index].second.c_str(), NAPI_AUTO_LENGTH, &headerValue); | ||
| 384 | + napi_set_named_property(env, webHeaderObj, "headerKey", headerKey); | ||
| 385 | + napi_set_named_property(env, webHeaderObj, "headerValue", headerValue); | ||
| 386 | + napi_set_element(env, result, index, webHeaderObj); | ||
| 387 | + } | ||
| 388 | + napi_close_handle_scope(env, scope); | ||
| 389 | + return result; | ||
| 390 | +} | ||
| 391 | + | ||
| 392 | +napi_value NapiWebSchemeHandlerRequest::JS_GetRequestUrl(napi_env env, napi_callback_info cbinfo) | ||
| 393 | +{ | ||
| 394 | + napi_value thisVar = nullptr; | ||
| 395 | + void* data = nullptr; | ||
| 396 | + WebSchemeHandlerRequest* request = nullptr; | ||
| 397 | + napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, &data); | ||
| 398 | + | ||
| 399 | + napi_unwrap(env, thisVar, (void**)&request); | ||
| 400 | + if (!request) { | ||
| 401 | + LOGE("NapiWebSchemeHandlerRequest::JS_GetRequestUrl request is nullptr"); | ||
| 402 | + return nullptr; | ||
| 403 | + } | ||
| 404 | + | ||
| 405 | + napi_value value; | ||
| 406 | + napi_status status = napi_create_string_utf8(env, request->GetUrl().c_str(), NAPI_AUTO_LENGTH, &value); | ||
| 407 | + if (status != napi_ok) { | ||
| 408 | + LOGE("NapiWebSchemeHandlerRequest::JS_GetRequestUrl response get url failed"); | ||
| 409 | + return nullptr; | ||
| 410 | + } | ||
| 411 | + return value; | ||
| 412 | +} | ||
| 413 | + | ||
| 414 | +napi_value NapiWebSchemeHandlerRequest::JS_GetRequestMethod(napi_env env, napi_callback_info cbinfo) | ||
| 415 | +{ | ||
| 416 | + napi_value thisVar = nullptr; | ||
| 417 | + void* data = nullptr; | ||
| 418 | + WebSchemeHandlerRequest* request = nullptr; | ||
| 419 | + napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, &data); | ||
| 420 | + | ||
| 421 | + napi_unwrap(env, thisVar, (void**)&request); | ||
| 422 | + if (!request) { | ||
| 423 | + LOGE("NapiWebSchemeHandlerRequest::JS_GetRequestMethod request is nullptr"); | ||
| 424 | + return nullptr; | ||
| 425 | + } | ||
| 426 | + | ||
| 427 | + napi_value value; | ||
| 428 | + napi_status status = napi_create_string_utf8(env, request->GetMethod().c_str(), NAPI_AUTO_LENGTH, &value); | ||
| 429 | + if (status != napi_ok) { | ||
| 430 | + LOGE("NapiWebSchemeHandlerRequest::JS_GetRequestMethod response get url failed"); | ||
| 431 | + return nullptr; | ||
| 432 | + } | ||
| 433 | + return value; | ||
| 434 | +} | ||
| 435 | + | ||
| 436 | +napi_value NapiWebSchemeHandlerRequest::JS_GetReferrer(napi_env env, napi_callback_info cbinfo) | ||
| 437 | +{ | ||
| 438 | + napi_value thisVar = nullptr; | ||
| 439 | + void* data = nullptr; | ||
| 440 | + WebSchemeHandlerRequest* request = nullptr; | ||
| 441 | + napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, &data); | ||
| 442 | + | ||
| 443 | + napi_unwrap(env, thisVar, (void**)&request); | ||
| 444 | + if (!request) { | ||
| 445 | + LOGE("NapiWebSchemeHandlerRequest::JS_GetReferrer request is nullptr"); | ||
| 446 | + return nullptr; | ||
| 447 | + } | ||
| 448 | + | ||
| 449 | + napi_value value; | ||
| 450 | + napi_status status = napi_create_string_utf8(env, request->GetReferrer().c_str(), NAPI_AUTO_LENGTH, &value); | ||
| 451 | + if (status != napi_ok) { | ||
| 452 | + LOGE("NapiWebSchemeHandlerRequest::JS_GetReferrer response get url failed"); | ||
| 453 | + return nullptr; | ||
| 454 | + } | ||
| 455 | + return value; | ||
| 456 | +} | ||
| 457 | + | ||
| 458 | +napi_value NapiWebSchemeHandlerRequest::JS_IsRedirect(napi_env env, napi_callback_info cbinfo) | ||
| 459 | +{ | ||
| 460 | + napi_value thisVar = nullptr; | ||
| 461 | + void* data = nullptr; | ||
| 462 | + WebSchemeHandlerRequest* request = nullptr; | ||
| 463 | + napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, &data); | ||
| 464 | + | ||
| 465 | + napi_unwrap(env, thisVar, (void**)&request); | ||
| 466 | + if (!request) { | ||
| 467 | + LOGE("NapiWebSchemeHandlerRequest::JS_IsRedirect request is nullptr"); | ||
| 468 | + return nullptr; | ||
| 469 | + } | ||
| 470 | + | ||
| 471 | + napi_value value; | ||
| 472 | + NAPI_CALL(env, napi_get_boolean(env, request->GetIsRedirect(), &value)); | ||
| 473 | + return value; | ||
| 474 | +} | ||
| 475 | + | ||
| 476 | +napi_value NapiWebSchemeHandlerRequest::JS_IsMainFrame(napi_env env, napi_callback_info cbinfo) | ||
| 477 | +{ | ||
| 478 | + napi_value thisVar = nullptr; | ||
| 479 | + void* data = nullptr; | ||
| 480 | + WebSchemeHandlerRequest* request = nullptr; | ||
| 481 | + napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, &data); | ||
| 482 | + | ||
| 483 | + napi_unwrap(env, thisVar, (void**)&request); | ||
| 484 | + if (!request) { | ||
| 485 | + LOGE("NapiWebSchemeHandlerRequest::JS_IsMainFrame request is nullptr"); | ||
| 486 | + return nullptr; | ||
| 487 | + } | ||
| 488 | + | ||
| 489 | + napi_value value; | ||
| 490 | + NAPI_CALL(env, napi_get_boolean(env, request->GetIsMainFrame(), &value)); | ||
| 491 | + return value; | ||
| 492 | +} | ||
| 493 | + | ||
| 494 | +napi_value NapiWebSchemeHandlerRequest::JS_HasGesture(napi_env env, napi_callback_info cbinfo) | ||
| 495 | +{ | ||
| 496 | + napi_value thisVar = nullptr; | ||
| 497 | + void* data = nullptr; | ||
| 498 | + WebSchemeHandlerRequest* request = nullptr; | ||
| 499 | + napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, &data); | ||
| 500 | + | ||
| 501 | + napi_unwrap(env, thisVar, (void**)&request); | ||
| 502 | + if (!request) { | ||
| 503 | + LOGE("NapiWebSchemeHandlerRequest::JS_HasGesture request is nullptr"); | ||
| 504 | + return nullptr; | ||
| 505 | + } | ||
| 506 | + | ||
| 507 | + napi_value value; | ||
| 508 | + NAPI_CALL(env, napi_get_boolean(env, request->GetHasGesture(), &value)); | ||
| 509 | + napi_get_undefined(env, &value); | ||
| 510 | + return value; | ||
| 511 | +} | ||
| 512 | + | ||
| 513 | +napi_value NapiWebSchemeHandlerRequest::JS_HttpBodyStream(napi_env env, napi_callback_info cbinfo) | ||
| 514 | +{ | ||
| 515 | + napi_value value = nullptr; | ||
| 516 | + napi_get_undefined(env, &value); | ||
| 517 | + return value; | ||
| 518 | +} | ||
| 519 | + | ||
| 520 | +napi_value NapiWebSchemeHandlerRequest::JS_GetRequestResourceType(napi_env env, napi_callback_info cbinfo) | ||
| 521 | +{ | ||
| 522 | + napi_value thisVar = nullptr; | ||
| 523 | + void* data = nullptr; | ||
| 524 | + WebSchemeHandlerRequest* request = nullptr; | ||
| 525 | + napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, &data); | ||
| 526 | + | ||
| 527 | + napi_unwrap(env, thisVar, (void**)&request); | ||
| 528 | + if (!request) { | ||
| 529 | + LOGE("NapiWebSchemeHandlerRequest::JS_GetRequestResourceType request is nullptr"); | ||
| 530 | + return nullptr; | ||
| 531 | + } | ||
| 532 | + | ||
| 533 | + napi_value value; | ||
| 534 | + napi_create_int32(env, request->GetRequestResourceType(), &value); | ||
| 535 | + return value; | ||
| 536 | +} | ||
| 537 | + | ||
| 538 | +napi_value NapiWebSchemeHandlerRequest::JS_GetFrameUrl(napi_env env, napi_callback_info cbinfo) | ||
| 539 | +{ | ||
| 540 | + napi_value thisVar = nullptr; | ||
| 541 | + void* data = nullptr; | ||
| 542 | + WebSchemeHandlerRequest* request = nullptr; | ||
| 543 | + napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, &data); | ||
| 544 | + | ||
| 545 | + napi_unwrap(env, thisVar, (void**)&request); | ||
| 546 | + if (!request) { | ||
| 547 | + LOGE("NapiWebSchemeHandlerRequest::JS_GetFrameUrl request is nullptr"); | ||
| 548 | + return nullptr; | ||
| 549 | + } | ||
| 550 | + | ||
| 551 | + napi_value value; | ||
| 552 | + napi_status status = napi_create_string_utf8(env, request->GetFrameUrl().c_str(), NAPI_AUTO_LENGTH, &value); | ||
| 553 | + if (status != napi_ok) { | ||
| 554 | + LOGE("NapiWebSchemeHandlerRequest::JS_GetFrameUrl response get frame url failed"); | ||
| 555 | + return nullptr; | ||
| 556 | + } | ||
| 557 | + return value; | ||
| 558 | +} | ||
| 559 | + | ||
| 560 | +napi_status NapiWebSchemeHandlerRequest::ExportEnumWebResourceType(napi_env env, napi_value* value) | ||
| 561 | +{ | ||
| 562 | + napi_value enumValue = nullptr; | ||
| 563 | + const std::string napiWebResourceTypeEnumName = "WebResourceType"; | ||
| 564 | + return napi_set_named_property(env, *value, napiWebResourceTypeEnumName.c_str(), enumValue); | ||
| 565 | +} | ||
| 566 | + | ||
| 567 | +napi_value NapiWebSchemeHandlerResponse::Init(napi_env env, napi_value exports) | ||
| 568 | +{ | ||
| 569 | + ExportWebSchemeHandlerResponseClass(env, &exports); | ||
| 570 | + return exports; | ||
| 571 | +} | ||
| 572 | + | ||
| 573 | +void NapiWebSchemeHandlerResponse::ExportWebSchemeHandlerResponseClass(napi_env env, napi_value* exportsPointer) | ||
| 574 | +{ | ||
| 575 | + napi_property_descriptor properties[] = { | ||
| 576 | + DECLARE_NAPI_FUNCTION("getUrl", JS_GetUrl), | ||
| 577 | + DECLARE_NAPI_FUNCTION("setUrl", JS_SetUrl), | ||
| 578 | + DECLARE_NAPI_FUNCTION("getStatus", JS_GetStatus), | ||
| 579 | + DECLARE_NAPI_FUNCTION("setStatus", JS_SetStatus), | ||
| 580 | + DECLARE_NAPI_FUNCTION("getStatusText", JS_GetStatusText), | ||
| 581 | + DECLARE_NAPI_FUNCTION("setStatusText", JS_SetStatusText), | ||
| 582 | + DECLARE_NAPI_FUNCTION("getMimeType", JS_GetMimeType), | ||
| 583 | + DECLARE_NAPI_FUNCTION("setMimeType", JS_SetMimeType), | ||
| 584 | + DECLARE_NAPI_FUNCTION("getEncoding", JS_GetEncoding), | ||
| 585 | + DECLARE_NAPI_FUNCTION("setEncoding", JS_SetEncoding), | ||
| 586 | + DECLARE_NAPI_FUNCTION("getHeaderByName", JS_GetHeaderByName), | ||
| 587 | + DECLARE_NAPI_FUNCTION("setHeaderByName", JS_SetHeaderByName), | ||
| 588 | + DECLARE_NAPI_FUNCTION("getNetErrorCode", JS_GetNetErrorCode), | ||
| 589 | + DECLARE_NAPI_FUNCTION("setNetErrorCode", JS_SetNetErrorCode), | ||
| 590 | + }; | ||
| 591 | + napi_value webSchemeHandlerResponse = nullptr; | ||
| 592 | + napi_define_class(env, WEB_SCHEME_HANDLER_RESPONSE.c_str(), WEB_SCHEME_HANDLER_RESPONSE.length(), JS_Constructor, | ||
| 593 | + nullptr, sizeof(properties) / sizeof(properties[0]), properties, &webSchemeHandlerResponse); | ||
| 594 | + napi_set_named_property(env, *exportsPointer, WEB_SCHEME_HANDLER_RESPONSE.c_str(), webSchemeHandlerResponse); | ||
| 595 | +} | ||
| 596 | + | ||
| 597 | +napi_value NapiWebSchemeHandlerResponse::JS_Constructor(napi_env env, napi_callback_info cbinfo) | ||
| 598 | +{ | ||
| 599 | + napi_value thisVar = nullptr; | ||
| 600 | + void* data = nullptr; | ||
| 601 | + napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, &data); | ||
| 602 | + | ||
| 603 | + WebSchemeHandlerResponse* response = new (std::nothrow) WebSchemeHandlerResponse(env); | ||
| 604 | + if (response == nullptr) { | ||
| 605 | + LOGE("NapiWebSchemeHandlerResponse::JS_Constructor response is nullptr"); | ||
| 606 | + NAPI_CALL(env, napi_get_undefined(env, &thisVar)); | ||
| 607 | + return thisVar; | ||
| 608 | + } | ||
| 609 | + | ||
| 610 | + napi_wrap( | ||
| 611 | + env, thisVar, response, | ||
| 612 | + [](napi_env /* env */, void* data, void* /* hint */) { | ||
| 613 | + WebSchemeHandlerResponse* response = (WebSchemeHandlerResponse*)data; | ||
| 614 | + delete response; | ||
| 615 | + }, | ||
| 616 | + nullptr, nullptr); | ||
| 617 | + | ||
| 618 | + return thisVar; | ||
| 619 | +} | ||
| 620 | + | ||
| 621 | +napi_value NapiWebSchemeHandlerResponse::JS_GetUrl(napi_env env, napi_callback_info cbinfo) | ||
| 622 | +{ | ||
| 623 | + size_t argc = 1; | ||
| 624 | + napi_value argv[1] = { 0 }; | ||
| 625 | + napi_value thisVar = nullptr; | ||
| 626 | + void* data = nullptr; | ||
| 627 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 628 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 629 | + | ||
| 630 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 631 | + if (!response) { | ||
| 632 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetUrl response is nullptr"); | ||
| 633 | + return nullptr; | ||
| 634 | + } | ||
| 635 | + | ||
| 636 | + napi_value urlValue; | ||
| 637 | + napi_status status = napi_create_string_utf8(env, response->GetUrl().c_str(), NAPI_AUTO_LENGTH, &urlValue); | ||
| 638 | + if (status != napi_ok) { | ||
| 639 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetUrl response get url failed"); | ||
| 640 | + return nullptr; | ||
| 641 | + } | ||
| 642 | + return urlValue; | ||
| 643 | +} | ||
| 644 | + | ||
| 645 | +napi_value NapiWebSchemeHandlerResponse::JS_SetUrl(napi_env env, napi_callback_info cbinfo) | ||
| 646 | +{ | ||
| 647 | + size_t argc = 1; | ||
| 648 | + napi_value argv[1] = { 0 }; | ||
| 649 | + napi_value thisVar = nullptr; | ||
| 650 | + void* data = nullptr; | ||
| 651 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 652 | + | ||
| 653 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 654 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 655 | + | ||
| 656 | + if (!response) { | ||
| 657 | + LOGE("unwrap WebSchemeHandlerResponse failed"); | ||
| 658 | + return nullptr; | ||
| 659 | + } | ||
| 660 | + std::string url = ""; | ||
| 661 | + if (!NapiParseUtils::ParseString(env, argv[0], url)) { | ||
| 662 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 663 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "url", "string")); | ||
| 664 | + return nullptr; | ||
| 665 | + } | ||
| 666 | + response->SetUrl(url); | ||
| 667 | + return nullptr; | ||
| 668 | +} | ||
| 669 | + | ||
| 670 | +napi_value NapiWebSchemeHandlerResponse::JS_GetStatus(napi_env env, napi_callback_info cbinfo) | ||
| 671 | +{ | ||
| 672 | + size_t argc = 1; | ||
| 673 | + napi_value argv[1] = { 0 }; | ||
| 674 | + napi_value thisVar = nullptr; | ||
| 675 | + void* data = nullptr; | ||
| 676 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 677 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 678 | + | ||
| 679 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 680 | + if (!response) { | ||
| 681 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetStatus response is nullptr"); | ||
| 682 | + return nullptr; | ||
| 683 | + } | ||
| 684 | + | ||
| 685 | + napi_value status; | ||
| 686 | + napi_create_int32(env, response->GetStatus(), &status); | ||
| 687 | + return status; | ||
| 688 | +} | ||
| 689 | + | ||
| 690 | +napi_value NapiWebSchemeHandlerResponse::JS_SetStatus(napi_env env, napi_callback_info cbinfo) | ||
| 691 | +{ | ||
| 692 | + size_t argc = 1; | ||
| 693 | + napi_value argv[1] = { 0 }; | ||
| 694 | + napi_value thisVar = nullptr; | ||
| 695 | + void* data = nullptr; | ||
| 696 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 697 | + | ||
| 698 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 699 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 700 | + | ||
| 701 | + if (!response) { | ||
| 702 | + LOGE("unwrap WebSchemeHandlerResponse failed"); | ||
| 703 | + return nullptr; | ||
| 704 | + } | ||
| 705 | + int32_t status = 0; | ||
| 706 | + if (!NapiParseUtils::ParseInt32(env, argv[0], status)) { | ||
| 707 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 708 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "code", "int")); | ||
| 709 | + LOGE("NapiWebSchemeHandlerResponse::JS_SetStatus parse failed"); | ||
| 710 | + return nullptr; | ||
| 711 | + } | ||
| 712 | + response->SetStatus(status); | ||
| 713 | + return nullptr; | ||
| 714 | +} | ||
| 715 | + | ||
| 716 | +napi_value NapiWebSchemeHandlerResponse::JS_GetStatusText(napi_env env, napi_callback_info cbinfo) | ||
| 717 | +{ | ||
| 718 | + size_t argc = 1; | ||
| 719 | + napi_value argv[1] = { 0 }; | ||
| 720 | + napi_value thisVar = nullptr; | ||
| 721 | + void* data = nullptr; | ||
| 722 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 723 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 724 | + | ||
| 725 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 726 | + if (!response) { | ||
| 727 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetStatusText response is nullptr"); | ||
| 728 | + return nullptr; | ||
| 729 | + } | ||
| 730 | + | ||
| 731 | + napi_value statusText; | ||
| 732 | + napi_status status = napi_create_string_utf8(env, response->GetStatusText().c_str(), NAPI_AUTO_LENGTH, &statusText); | ||
| 733 | + if (status != napi_ok) { | ||
| 734 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetStatusText response get failed"); | ||
| 735 | + return nullptr; | ||
| 736 | + } | ||
| 737 | + return statusText; | ||
| 738 | +} | ||
| 739 | + | ||
| 740 | +napi_value NapiWebSchemeHandlerResponse::JS_SetStatusText(napi_env env, napi_callback_info cbinfo) | ||
| 741 | +{ | ||
| 742 | + size_t argc = 1; | ||
| 743 | + napi_value argv[1] = { 0 }; | ||
| 744 | + napi_value thisVar = nullptr; | ||
| 745 | + void* data = nullptr; | ||
| 746 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 747 | + | ||
| 748 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 749 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 750 | + | ||
| 751 | + if (!response) { | ||
| 752 | + LOGE("unwrap WebSchemeHandlerResponse failed"); | ||
| 753 | + return nullptr; | ||
| 754 | + } | ||
| 755 | + std::string statusText = ""; | ||
| 756 | + if (!NapiParseUtils::ParseString(env, argv[0], statusText)) { | ||
| 757 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 758 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "text", "string")); | ||
| 759 | + return nullptr; | ||
| 760 | + } | ||
| 761 | + response->SetStatusText(statusText); | ||
| 762 | + return nullptr; | ||
| 763 | +} | ||
| 764 | + | ||
| 765 | +napi_value NapiWebSchemeHandlerResponse::JS_GetMimeType(napi_env env, napi_callback_info cbinfo) | ||
| 766 | +{ | ||
| 767 | + size_t argc = 1; | ||
| 768 | + napi_value argv[1] = { 0 }; | ||
| 769 | + napi_value thisVar = nullptr; | ||
| 770 | + void* data = nullptr; | ||
| 771 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 772 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 773 | + | ||
| 774 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 775 | + if (!response) { | ||
| 776 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetMimeType response is nullptr"); | ||
| 777 | + return nullptr; | ||
| 778 | + } | ||
| 779 | + | ||
| 780 | + napi_value mimeType; | ||
| 781 | + napi_status status = napi_create_string_utf8(env, response->GetMimeType().c_str(), NAPI_AUTO_LENGTH, &mimeType); | ||
| 782 | + if (status != napi_ok) { | ||
| 783 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetMimeType response get failed"); | ||
| 784 | + return nullptr; | ||
| 785 | + } | ||
| 786 | + return mimeType; | ||
| 787 | +} | ||
| 788 | + | ||
| 789 | +napi_value NapiWebSchemeHandlerResponse::JS_SetMimeType(napi_env env, napi_callback_info cbinfo) | ||
| 790 | +{ | ||
| 791 | + size_t argc = 1; | ||
| 792 | + napi_value argv[1] = { 0 }; | ||
| 793 | + napi_value thisVar = nullptr; | ||
| 794 | + void* data = nullptr; | ||
| 795 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 796 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 797 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 798 | + | ||
| 799 | + if (!response) { | ||
| 800 | + LOGE("unwrap WebSchemeHandlerResponse failed"); | ||
| 801 | + return nullptr; | ||
| 802 | + } | ||
| 803 | + std::string mimeType = ""; | ||
| 804 | + if (!NapiParseUtils::ParseString(env, argv[0], mimeType)) { | ||
| 805 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 806 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "type", "string")); | ||
| 807 | + return nullptr; | ||
| 808 | + } | ||
| 809 | + response->SetMimeType(mimeType); | ||
| 810 | + return nullptr; | ||
| 811 | +} | ||
| 812 | + | ||
| 813 | +napi_value NapiWebSchemeHandlerResponse::JS_GetEncoding(napi_env env, napi_callback_info cbinfo) | ||
| 814 | +{ | ||
| 815 | + size_t argc = 1; | ||
| 816 | + napi_value argv[1] = { 0 }; | ||
| 817 | + napi_value thisVar = nullptr; | ||
| 818 | + void* data = nullptr; | ||
| 819 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 820 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 821 | + | ||
| 822 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 823 | + if (!response) { | ||
| 824 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetEncoding response is nullptr"); | ||
| 825 | + return nullptr; | ||
| 826 | + } | ||
| 827 | + | ||
| 828 | + napi_value encoding; | ||
| 829 | + napi_status status = napi_create_string_utf8(env, response->GetEncoding().c_str(), NAPI_AUTO_LENGTH, &encoding); | ||
| 830 | + if (status != napi_ok) { | ||
| 831 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetEncoding response get failed"); | ||
| 832 | + return nullptr; | ||
| 833 | + } | ||
| 834 | + return encoding; | ||
| 835 | +} | ||
| 836 | + | ||
| 837 | +napi_value NapiWebSchemeHandlerResponse::JS_SetEncoding(napi_env env, napi_callback_info cbinfo) | ||
| 838 | +{ | ||
| 839 | + size_t argc = 1; | ||
| 840 | + napi_value argv[1] = { 0 }; | ||
| 841 | + napi_value thisVar = nullptr; | ||
| 842 | + void* data = nullptr; | ||
| 843 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 844 | + | ||
| 845 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 846 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 847 | + | ||
| 848 | + if (!response) { | ||
| 849 | + LOGE("unwrap WebSchemeHandlerResponse failed"); | ||
| 850 | + return nullptr; | ||
| 851 | + } | ||
| 852 | + std::string encoding = ""; | ||
| 853 | + if (!NapiParseUtils::ParseString(env, argv[0], encoding)) { | ||
| 854 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 855 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "encoding", "string")); | ||
| 856 | + return nullptr; | ||
| 857 | + } | ||
| 858 | + response->SetEncoding(encoding); | ||
| 859 | + return nullptr; | ||
| 860 | +} | ||
| 861 | + | ||
| 862 | +napi_value NapiWebSchemeHandlerResponse::JS_GetHeaderByName(napi_env env, napi_callback_info cbinfo) | ||
| 863 | +{ | ||
| 864 | + size_t argc = 1; | ||
| 865 | + napi_value argv[1] = { 0 }; | ||
| 866 | + napi_value thisVar = nullptr; | ||
| 867 | + void* data = nullptr; | ||
| 868 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 869 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 870 | + | ||
| 871 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 872 | + if (!response) { | ||
| 873 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetHeaderByName response is nullptr"); | ||
| 874 | + return nullptr; | ||
| 875 | + } | ||
| 876 | + | ||
| 877 | + std::string name; | ||
| 878 | + if (!NapiParseUtils::ParseString(env, argv[0], name)) { | ||
| 879 | + return nullptr; | ||
| 880 | + } | ||
| 881 | + | ||
| 882 | + napi_value headerValue; | ||
| 883 | + std::string value = response->GetHeaderByName(name); | ||
| 884 | + napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &headerValue); | ||
| 885 | + if (status != napi_ok) { | ||
| 886 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetHeaderByName response get failed"); | ||
| 887 | + return nullptr; | ||
| 888 | + } | ||
| 889 | + return headerValue; | ||
| 890 | +} | ||
| 891 | + | ||
| 892 | +napi_value NapiWebSchemeHandlerResponse::JS_SetHeaderByName(napi_env env, napi_callback_info cbinfo) | ||
| 893 | +{ | ||
| 894 | + size_t argc = INTEGER_THREE; | ||
| 895 | + napi_value argv[INTEGER_THREE] = { 0 }; | ||
| 896 | + napi_value thisVar = nullptr; | ||
| 897 | + void* data = nullptr; | ||
| 898 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 899 | + | ||
| 900 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 901 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 902 | + | ||
| 903 | + if (!response) { | ||
| 904 | + LOGE("unwrap WebSchemeHandlerResponse failed"); | ||
| 905 | + return nullptr; | ||
| 906 | + } | ||
| 907 | + std::string name; | ||
| 908 | + std::string value; | ||
| 909 | + bool overwrite = false; | ||
| 910 | + if (argc != INTEGER_THREE) { | ||
| 911 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 912 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "three")); | ||
| 913 | + LOGE("NapiWebSchemeHandlerResponse::JS_SetHeaderByName parse failed"); | ||
| 914 | + return nullptr; | ||
| 915 | + } | ||
| 916 | + if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], name)) { | ||
| 917 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 918 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "name", "string")); | ||
| 919 | + LOGE("NapiWebSchemeHandlerResponse::JS_SetHeaderByName parse failed"); | ||
| 920 | + return nullptr; | ||
| 921 | + } | ||
| 922 | + if (!NapiParseUtils::ParseString(env, argv[INTEGER_ONE], value)) { | ||
| 923 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 924 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "value", "string")); | ||
| 925 | + LOGE("NapiWebSchemeHandlerResponse::JS_SetHeaderByName parse failed"); | ||
| 926 | + return nullptr; | ||
| 927 | + } | ||
| 928 | + if (!NapiParseUtils::ParseBoolean(env, argv[INTEGER_TWO], overwrite)) { | ||
| 929 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 930 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "overwrite", "booleane")); | ||
| 931 | + LOGE("NapiWebSchemeHandlerResponse::JS_SetHeaderByName parse failed"); | ||
| 932 | + return nullptr; | ||
| 933 | + } | ||
| 934 | + response->SetHeaderByName(name, value, overwrite); | ||
| 935 | + return nullptr; | ||
| 936 | +} | ||
| 937 | + | ||
| 938 | +napi_value NapiWebSchemeHandlerResponse::JS_GetNetErrorCode(napi_env env, napi_callback_info cbinfo) | ||
| 939 | +{ | ||
| 940 | + size_t argc = 1; | ||
| 941 | + napi_value argv[1] = { 0 }; | ||
| 942 | + napi_value thisVar = nullptr; | ||
| 943 | + void* data = nullptr; | ||
| 944 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 945 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 946 | + | ||
| 947 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 948 | + if (!response) { | ||
| 949 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetEncoding response is nullptr"); | ||
| 950 | + return nullptr; | ||
| 951 | + } | ||
| 952 | + | ||
| 953 | + napi_value code; | ||
| 954 | + NAPI_CALL(env, napi_create_int32(env, response->GetErrorCode(), &code)); | ||
| 955 | + return code; | ||
| 956 | +} | ||
| 957 | + | ||
| 958 | +napi_value NapiWebSchemeHandlerResponse::JS_SetNetErrorCode(napi_env env, napi_callback_info cbinfo) | ||
| 959 | +{ | ||
| 960 | + size_t argc = INTEGER_ONE; | ||
| 961 | + napi_value argv[INTEGER_ONE] = { 0 }; | ||
| 962 | + napi_value thisVar = nullptr; | ||
| 963 | + void* data = nullptr; | ||
| 964 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 965 | + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data); | ||
| 966 | + | ||
| 967 | + napi_unwrap(env, thisVar, (void**)&response); | ||
| 968 | + if (!response) { | ||
| 969 | + LOGE("NapiWebSchemeHandlerResponse::JS_GetEncoding response is nullptr"); | ||
| 970 | + return nullptr; | ||
| 971 | + } | ||
| 972 | + int32_t code = 0; | ||
| 973 | + if (argc != INTEGER_ONE) { | ||
| 974 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 975 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one")); | ||
| 976 | + return nullptr; | ||
| 977 | + } | ||
| 978 | + if (!NapiParseUtils::ParseInt32(env, argv[0], code)) { | ||
| 979 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 980 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "code", "int")); | ||
| 981 | + return nullptr; | ||
| 982 | + } | ||
| 983 | + NetErrorInfo errorInfo = ValidateAndGetNetErrorName(code); | ||
| 984 | + response->SetErrorCode(code, errorInfo.errorName.c_str()); | ||
| 985 | + return nullptr; | ||
| 986 | +} | ||
| 987 | + | ||
| 988 | +napi_value NapiWebResourceHandler::Init(napi_env env, napi_value exports) | ||
| 989 | +{ | ||
| 990 | + ExportWebResourceHandlerClass(env, &exports); | ||
| 991 | + return exports; | ||
| 992 | +} | ||
| 993 | + | ||
| 994 | +void NapiWebResourceHandler::ExportWebResourceHandlerClass(napi_env env, napi_value* exportsPointer) | ||
| 995 | +{ | ||
| 996 | + napi_property_descriptor properties[] = { | ||
| 997 | + DECLARE_NAPI_FUNCTION("didReceiveResponse", JS_DidReceiveResponse), | ||
| 998 | + DECLARE_NAPI_FUNCTION("didReceiveResponseBody", JS_DidReceiveResponseBody), | ||
| 999 | + DECLARE_NAPI_FUNCTION("didFinish", JS_DidFinish), | ||
| 1000 | + DECLARE_NAPI_FUNCTION("didFail", JS_DidFailWithError), | ||
| 1001 | + }; | ||
| 1002 | + napi_value webResourceHandler = nullptr; | ||
| 1003 | + napi_define_class(env, WEB_RESOURCE_HANDLER.c_str(), WEB_RESOURCE_HANDLER.length(), JS_Constructor, nullptr, | ||
| 1004 | + sizeof(properties) / sizeof(properties[0]), properties, &webResourceHandler); | ||
| 1005 | + napi_set_named_property(env, *exportsPointer, WEB_RESOURCE_HANDLER.c_str(), webResourceHandler); | ||
| 1006 | +} | ||
| 1007 | + | ||
| 1008 | +napi_status NapiWebResourceHandler::DefineProperties(napi_env env, napi_value* object) | ||
| 1009 | +{ | ||
| 1010 | + napi_property_descriptor properties[] = { | ||
| 1011 | + DECLARE_NAPI_FUNCTION("didReceiveResponse", JS_DidReceiveResponse), | ||
| 1012 | + DECLARE_NAPI_FUNCTION("didReceiveResponseBody", JS_DidReceiveResponseBody), | ||
| 1013 | + DECLARE_NAPI_FUNCTION("didFinish", JS_DidFinish), | ||
| 1014 | + DECLARE_NAPI_FUNCTION("didFail", JS_DidFailWithError), | ||
| 1015 | + }; | ||
| 1016 | + return napi_define_properties(env, *object, sizeof(properties) / sizeof(properties[0]), properties); | ||
| 1017 | +} | ||
| 1018 | + | ||
| 1019 | +napi_value NapiWebResourceHandler::JS_Constructor(napi_env env, napi_callback_info info) | ||
| 1020 | +{ | ||
| 1021 | + napi_value thisVar = nullptr; | ||
| 1022 | + void* data = nullptr; | ||
| 1023 | + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data); | ||
| 1024 | + | ||
| 1025 | + WebResourceHandler* handler = new WebResourceHandler(env); | ||
| 1026 | + | ||
| 1027 | + napi_wrap( | ||
| 1028 | + env, thisVar, handler, | ||
| 1029 | + [](napi_env /* env */, void* data, void* /* hint */) { | ||
| 1030 | + WebResourceHandler* handler = (WebResourceHandler*)data; | ||
| 1031 | + delete handler; | ||
| 1032 | + }, | ||
| 1033 | + nullptr, nullptr); | ||
| 1034 | + | ||
| 1035 | + return thisVar; | ||
| 1036 | +} | ||
| 1037 | + | ||
| 1038 | +napi_value NapiWebResourceHandler::JS_DidReceiveResponse(napi_env env, napi_callback_info info) | ||
| 1039 | +{ | ||
| 1040 | + size_t argc = 1; | ||
| 1041 | + napi_value argv[1] = { 0 }; | ||
| 1042 | + napi_value thisVar = nullptr; | ||
| 1043 | + void* data = nullptr; | ||
| 1044 | + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); | ||
| 1045 | + | ||
| 1046 | + if (argc != 1) { | ||
| 1047 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 1048 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one")); | ||
| 1049 | + return nullptr; | ||
| 1050 | + } | ||
| 1051 | + | ||
| 1052 | + WebResourceHandler* resourceHandler = nullptr; | ||
| 1053 | + napi_unwrap(env, thisVar, (void**)&resourceHandler); | ||
| 1054 | + | ||
| 1055 | + if (!resourceHandler) { | ||
| 1056 | + LOGE("JS_DidReceiveResponse unwrap resource handler failed"); | ||
| 1057 | + return nullptr; | ||
| 1058 | + } | ||
| 1059 | + | ||
| 1060 | + WebSchemeHandlerResponse* response = nullptr; | ||
| 1061 | + napi_value obj = argv[0]; | ||
| 1062 | + napi_unwrap(env, obj, (void**)&response); | ||
| 1063 | + if (!response) { | ||
| 1064 | + LOGE("JS_DidReceiveResponse unwrap response failed"); | ||
| 1065 | + return nullptr; | ||
| 1066 | + } | ||
| 1067 | + int32_t ret = resourceHandler->DidReceiveResponse(response->GetArkWebResponse()); | ||
| 1068 | + if (ret != 0) { | ||
| 1069 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::RESOURCE_HANDLER_INVALID); | ||
| 1070 | + } | ||
| 1071 | + return nullptr; | ||
| 1072 | +} | ||
| 1073 | + | ||
| 1074 | +napi_value NapiWebResourceHandler::JS_DidReceiveResponseBody(napi_env env, napi_callback_info info) | ||
| 1075 | +{ | ||
| 1076 | + LOGI("NapiWebResourceHandler::JS_DidReceiveResponseBody enter"); | ||
| 1077 | + size_t argc = 1; | ||
| 1078 | + napi_value argv[1] = { 0 }; | ||
| 1079 | + napi_value thisVar = nullptr; | ||
| 1080 | + void* data = nullptr; | ||
| 1081 | + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); | ||
| 1082 | + | ||
| 1083 | + if (argc != 1) { | ||
| 1084 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 1085 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one")); | ||
| 1086 | + return nullptr; | ||
| 1087 | + } | ||
| 1088 | + | ||
| 1089 | + WebResourceHandler* resourceHandler = nullptr; | ||
| 1090 | + napi_unwrap(env, thisVar, (void**)&resourceHandler); | ||
| 1091 | + | ||
| 1092 | + if (!resourceHandler) { | ||
| 1093 | + LOGE("unwrap resource handler failed"); | ||
| 1094 | + return nullptr; | ||
| 1095 | + } | ||
| 1096 | + bool isArrayBuffer = false; | ||
| 1097 | + NAPI_CALL(env, napi_is_arraybuffer(env, argv[0], &isArrayBuffer)); | ||
| 1098 | + if (!isArrayBuffer) { | ||
| 1099 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR); | ||
| 1100 | + return nullptr; | ||
| 1101 | + } | ||
| 1102 | + | ||
| 1103 | + uint8_t* arrBuf = nullptr; | ||
| 1104 | + size_t byteLength = 0; | ||
| 1105 | + napi_get_arraybuffer_info(env, argv[0], (void**)&arrBuf, &byteLength); | ||
| 1106 | + int32_t ret = resourceHandler->DidReceiveResponseBody(arrBuf, static_cast<int64_t>(byteLength)); | ||
| 1107 | + if (ret != 0) { | ||
| 1108 | + LOGE("JS_DidReceiveResponseBody ret=%{public}d", ret); | ||
| 1109 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::RESOURCE_HANDLER_INVALID); | ||
| 1110 | + } | ||
| 1111 | + return nullptr; | ||
| 1112 | +} | ||
| 1113 | + | ||
| 1114 | +napi_value NapiWebResourceHandler::JS_DidFinish(napi_env env, napi_callback_info info) | ||
| 1115 | +{ | ||
| 1116 | + napi_value thisVar = nullptr; | ||
| 1117 | + void* data = nullptr; | ||
| 1118 | + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data); | ||
| 1119 | + | ||
| 1120 | + WebResourceHandler* resourceHandler = nullptr; | ||
| 1121 | + napi_unwrap(env, thisVar, (void**)&resourceHandler); | ||
| 1122 | + | ||
| 1123 | + if (!resourceHandler) { | ||
| 1124 | + LOGE("unwrap resource handler failed"); | ||
| 1125 | + return nullptr; | ||
| 1126 | + } | ||
| 1127 | + | ||
| 1128 | + int32_t ret = resourceHandler->DidFinish(); | ||
| 1129 | + if (ret != 0) { | ||
| 1130 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::RESOURCE_HANDLER_INVALID); | ||
| 1131 | + LOGE("JS_DidFinish ret=%{public}d", ret); | ||
| 1132 | + } | ||
| 1133 | + return nullptr; | ||
| 1134 | +} | ||
| 1135 | + | ||
| 1136 | +napi_value NapiWebResourceHandler::JS_DidFailWithError(napi_env env, napi_callback_info info) | ||
| 1137 | +{ | ||
| 1138 | + size_t argc = 2; | ||
| 1139 | + napi_value argv[2] = { 0 }; | ||
| 1140 | + napi_value thisVar = nullptr; | ||
| 1141 | + void* data = nullptr; | ||
| 1142 | + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); | ||
| 1143 | + | ||
| 1144 | + WebResourceHandler* resourceHandler = nullptr; | ||
| 1145 | + napi_unwrap(env, thisVar, (void**)&resourceHandler); | ||
| 1146 | + | ||
| 1147 | + if (!resourceHandler) { | ||
| 1148 | + LOGE("unwrap resource handler failed"); | ||
| 1149 | + return nullptr; | ||
| 1150 | + } | ||
| 1151 | + | ||
| 1152 | + int32_t errorCode; | ||
| 1153 | + static constexpr int LEVEL_COUNT = 2; | ||
| 1154 | + if (!NapiParseUtils::ParseInt32(env, argv[0], errorCode)) { | ||
| 1155 | + LOGE("JS_DidFailWithError unwrap error code failed"); | ||
| 1156 | + if (argc < LEVEL_COUNT) { | ||
| 1157 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR, | ||
| 1158 | + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "code", "int")); | ||
| 1159 | + } else { | ||
| 1160 | + NWebError::BusinessError::ThrowErrorByErrcode( | ||
| 1161 | + env, NWebError::INVALID_NET_ERROR, NWebError::GetErrMsgByErrCode(NWebError::INVALID_NET_ERROR)); | ||
| 1162 | + } | ||
| 1163 | + | ||
| 1164 | + return nullptr; | ||
| 1165 | + } | ||
| 1166 | + | ||
| 1167 | + NetErrorInfo errorInfo = ValidateAndGetNetErrorName(errorCode); | ||
| 1168 | + if (argc >= LEVEL_COUNT && (!errorInfo.isValid || errorCode == ARKWEB_NET_OK)) { | ||
| 1169 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::INVALID_NET_ERROR, | ||
| 1170 | + NWebError::GetErrMsgByErrCode(NWebError::INVALID_NET_ERROR)); | ||
| 1171 | + return nullptr; | ||
| 1172 | + } | ||
| 1173 | + | ||
| 1174 | + bool completeIfNoResponse = false; | ||
| 1175 | + if (!NapiParseUtils::ParseBoolean(env, argv[1], completeIfNoResponse)) { | ||
| 1176 | + LOGE("JS_DidFailWithError unwrap error completeIfNoResponse failed"); | ||
| 1177 | + } | ||
| 1178 | + int32_t ret = resourceHandler->DidFailWithError( | ||
| 1179 | + static_cast<ArkWeb_NetError>(errorCode), errorInfo.errorName.c_str(), completeIfNoResponse); | ||
| 1180 | + if (ret != 0) { | ||
| 1181 | + NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::RESOURCE_HANDLER_INVALID); | ||
| 1182 | + LOGE("JS_DidFailWithError ret=%{public}d", ret); | ||
| 1183 | + } | ||
| 1184 | + return nullptr; | ||
| 1185 | +} | ||
| 1186 | +} // namespace OHOS::Plugin | ||
| @@ -0,0 +1,98 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +namespace OHOS::Plugin { | ||
| 25 | +const std::string WEB_SCHEME_HANDLER = "WebSchemeHandler"; | ||
| 26 | +const std::string WEB_SCHEME_HANDLER_REQUEST = "WebSchemeHandlerRequest"; | ||
| 27 | +const std::string WEB_SCHEME_HANDLER_RESPONSE = "WebSchemeHandlerResponse"; | ||
| 28 | +const std::string WEB_RESOURCE_HANDLER = "WebResourceHandler"; | ||
| 29 | +const std::string WEB_HTTP_BODY_STREAM = "WebHttpBodyStream"; | ||
| 30 | +const std::string WEB_NET_ERROR_CODE = "WebNetErrorCode"; | ||
| 31 | +class NapiWebSchemeHandlerRequest { | ||
| 32 | +public: | ||
| 33 | + NapiWebSchemeHandlerRequest() = default; | ||
| 34 | + ~NapiWebSchemeHandlerRequest() = default; | ||
| 35 | + | ||
| 36 | + static napi_value Init(napi_env env, napi_value exports); | ||
| 37 | + static void ExportWebSchemeHandlerRequestClass(napi_env, napi_value* exportsPointer); | ||
| 38 | + static napi_status DefineProperties(napi_env env, napi_value* object); | ||
| 39 | + | ||
| 40 | + static napi_value JS_Constructor(napi_env env, napi_callback_info cbinfo); | ||
| 41 | + static napi_value JS_GetHeader(napi_env env, napi_callback_info cbinfo); | ||
| 42 | + static napi_value JS_GetRequestUrl(napi_env env, napi_callback_info cbinfo); | ||
| 43 | + static napi_value JS_GetRequestMethod(napi_env env, napi_callback_info cbinfo); | ||
| 44 | + static napi_value JS_GetReferrer(napi_env env, napi_callback_info cbinfo); | ||
| 45 | + static napi_value JS_IsRedirect(napi_env env, napi_callback_info cbinfo); | ||
| 46 | + static napi_value JS_IsMainFrame(napi_env env, napi_callback_info cbinfo); | ||
| 47 | + static napi_value JS_HasGesture(napi_env env, napi_callback_info cbinfo); | ||
| 48 | + static napi_value JS_HttpBodyStream(napi_env env, napi_callback_info cbinfo); | ||
| 49 | + static napi_value JS_GetRequestResourceType(napi_env env, napi_callback_info cbinfo); | ||
| 50 | + static napi_value JS_GetFrameUrl(napi_env env, napi_callback_info cbinfo); | ||
| 51 | + | ||
| 52 | +private: | ||
| 53 | + static napi_status ExportEnumWebResourceType(napi_env env, napi_value* value); | ||
| 54 | +}; | ||
| 55 | + | ||
| 56 | +class NapiWebSchemeHandlerResponse { | ||
| 57 | +public: | ||
| 58 | + NapiWebSchemeHandlerResponse() = default; | ||
| 59 | + ~NapiWebSchemeHandlerResponse() = default; | ||
| 60 | + | ||
| 61 | + static napi_value Init(napi_env env, napi_value exports); | ||
| 62 | + static void ExportWebSchemeHandlerResponseClass(napi_env, napi_value* exportsPointer); | ||
| 63 | + | ||
| 64 | + static napi_value JS_Constructor(napi_env env, napi_callback_info cbinfo); | ||
| 65 | + static napi_value JS_GetUrl(napi_env env, napi_callback_info cbinfo); | ||
| 66 | + static napi_value JS_SetUrl(napi_env env, napi_callback_info cbinfo); | ||
| 67 | + static napi_value JS_GetStatus(napi_env env, napi_callback_info cbinfo); | ||
| 68 | + static napi_value JS_SetStatus(napi_env env, napi_callback_info cbinfo); | ||
| 69 | + static napi_value JS_GetStatusText(napi_env env, napi_callback_info cbinfo); | ||
| 70 | + static napi_value JS_SetStatusText(napi_env env, napi_callback_info cbinfo); | ||
| 71 | + static napi_value JS_GetMimeType(napi_env env, napi_callback_info cbinfo); | ||
| 72 | + static napi_value JS_SetMimeType(napi_env env, napi_callback_info cbinfo); | ||
| 73 | + static napi_value JS_GetEncoding(napi_env env, napi_callback_info cbinfo); | ||
| 74 | + static napi_value JS_SetEncoding(napi_env env, napi_callback_info cbinfo); | ||
| 75 | + static napi_value JS_GetHeaderByName(napi_env env, napi_callback_info cbinfo); | ||
| 76 | + static napi_value JS_SetHeaderByName(napi_env env, napi_callback_info cbinfo); | ||
| 77 | + static napi_value JS_GetNetErrorCode(napi_env env, napi_callback_info cbinfo); | ||
| 78 | + static napi_value JS_SetNetErrorCode(napi_env env, napi_callback_info cbinfo); | ||
| 79 | +}; | ||
| 80 | + | ||
| 81 | +class NapiWebResourceHandler { | ||
| 82 | +public: | ||
| 83 | + NapiWebResourceHandler() = default; | ||
| 84 | + ~NapiWebResourceHandler() = default; | ||
| 85 | + | ||
| 86 | + static napi_value Init(napi_env env, napi_value exports); | ||
| 87 | + static void ExportWebResourceHandlerClass(napi_env, napi_value* exportsPointer); | ||
| 88 | + static napi_status DefineProperties(napi_env env, napi_value* object); | ||
| 89 | + | ||
| 90 | + static napi_value JS_Constructor(napi_env env, napi_callback_info info); | ||
| 91 | + static napi_value JS_DidReceiveResponse(napi_env env, napi_callback_info info); | ||
| 92 | + static napi_value JS_DidReceiveResponseBody(napi_env env, napi_callback_info info); | ||
| 93 | + static napi_value JS_DidFinish(napi_env env, napi_callback_info info); | ||
| 94 | + static napi_value JS_DidFailWithError(napi_env env, napi_callback_info info); | ||
| 95 | +}; | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | + | ||
| @@ -0,0 +1,630 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace OHOS::Plugin { | ||
| 26 | + | ||
| 27 | +struct RequestStopParam { | ||
| 28 | + napi_env env_; | ||
| 29 | + napi_ref callbackRef_; | ||
| 30 | + WebSchemeHandlerRequest* request_; | ||
| 31 | + const ArkWeb_ResourceRequest* arkWebRequest_; | ||
| 32 | +}; | ||
| 33 | + | ||
| 34 | +static void RequestStopAfterWorkCb(uv_work_t* work, int status); | ||
| 35 | + | ||
| 36 | +std::unordered_map<WebSchemeHandler*, ArkWeb_SchemeHandler*> g_web_scheme_handler_map; | ||
| 37 | +std::unordered_map<ArkWeb_SchemeHandler*, WebSchemeHandler*> g_arkui_web_scheme_handler_map; | ||
| 38 | +std::mutex g_mutexForHandlerMap; | ||
| 39 | + | ||
| 40 | +void OnRequestStart(ArkWeb_SchemeHandler* schemeHandler, ArkWeb_ResourceRequest* resourceRequest, | ||
| 41 | + ArkWeb_ResourceHandler* resourceHandler, bool* intercept) | ||
| 42 | +{ | ||
| 43 | + WebSchemeHandler* handler = WebSchemeHandler::GetWebSchemeHandler(schemeHandler); | ||
| 44 | + if (handler == nullptr) { | ||
| 45 | + return; | ||
| 46 | + } | ||
| 47 | + handler->RequestStart(resourceRequest, resourceHandler, intercept); | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +void OnRequestStop(ArkWeb_SchemeHandler* schemeHandler, ArkWeb_ResourceRequest* resourceRequest) | ||
| 51 | +{ | ||
| 52 | + WebSchemeHandler* handler = WebSchemeHandler::GetWebSchemeHandler(schemeHandler); | ||
| 53 | + if (handler == nullptr) { | ||
| 54 | + return; | ||
| 55 | + } | ||
| 56 | + handler->RequestStop(resourceRequest); | ||
| 57 | +} | ||
| 58 | + | ||
| 59 | +WebResourceHandler::WebResourceHandler(napi_env env) : env_(env), handler_(nullptr) {} | ||
| 60 | + | ||
| 61 | +WebResourceHandler::WebResourceHandler(napi_env env, const ArkWeb_ResourceHandler* handler) | ||
| 62 | + : env_(env), handler_(const_cast<ArkWeb_ResourceHandler*>(handler)) | ||
| 63 | +{} | ||
| 64 | + | ||
| 65 | +WebResourceHandler::~WebResourceHandler() {} | ||
| 66 | + | ||
| 67 | +int32_t WebResourceHandler::DidReceiveResponse(const ArkWeb_Response* response) | ||
| 68 | +{ | ||
| 69 | + if (isFinished_) { | ||
| 70 | + return ARKWEB_ERROR_UNKNOWN; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + if (!response || !handler_) { | ||
| 74 | + return ARKWEB_INVALID_PARAM; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + if (handler_->DidReceiveResponse(response) != NWebError::NO_ERROR) { | ||
| 78 | + return ARKWEB_INVALID_PARAM; | ||
| 79 | + } | ||
| 80 | + return ARKWEB_NET_OK; | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +int32_t WebResourceHandler::DidReceiveResponseBody(const uint8_t* webResourceHandlerbuffer, int64_t bufferLen) | ||
| 84 | +{ | ||
| 85 | + if (isFinished_) { | ||
| 86 | + LOGI("WebResourceHandler::DidReceiveResponseBody already finished"); | ||
| 87 | + return ARKWEB_ERROR_UNKNOWN; | ||
| 88 | + } | ||
| 89 | + if (!handler_) { | ||
| 90 | + LOGE("WebResourceHandler::DidReceiveResponseBody handler_ is null"); | ||
| 91 | + return ARKWEB_INVALID_PARAM; | ||
| 92 | + } | ||
| 93 | + if (handler_->DidReceiveData(webResourceHandlerbuffer, bufferLen) != NWebError::NO_ERROR) { | ||
| 94 | + return ARKWEB_INVALID_PARAM; | ||
| 95 | + } | ||
| 96 | + return ARKWEB_NET_OK; | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | +int32_t WebResourceHandler::DidFinish() | ||
| 100 | +{ | ||
| 101 | + if (isFinished_) { | ||
| 102 | + return ARKWEB_ERROR_UNKNOWN; | ||
| 103 | + } | ||
| 104 | + if (!handler_) { | ||
| 105 | + return ARKWEB_INVALID_PARAM; | ||
| 106 | + } | ||
| 107 | + if (handler_->DidFinish() != NWebError::NO_ERROR) { | ||
| 108 | + return ARKWEB_INVALID_PARAM; | ||
| 109 | + } | ||
| 110 | + isFinished_ = true; | ||
| 111 | + return ARKWEB_NET_OK; | ||
| 112 | +} | ||
| 113 | + | ||
| 114 | +int32_t WebResourceHandler::DidFailWithError( | ||
| 115 | + ArkWeb_NetError errorCode, const std::string errorDescription, bool completeIfNoResponse) | ||
| 116 | +{ | ||
| 117 | + if (isFinished_) { | ||
| 118 | + return ArkWeb_ErrorCode::ARKWEB_ERROR_UNKNOWN; | ||
| 119 | + } | ||
| 120 | + if (handler_->DidFailWithError(errorCode, errorDescription, completeIfNoResponse) != NWebError::NO_ERROR) { | ||
| 121 | + return ARKWEB_INVALID_PARAM; | ||
| 122 | + } | ||
| 123 | + isFinished_ = true; | ||
| 124 | + return ARKWEB_NET_OK; | ||
| 125 | +} | ||
| 126 | + | ||
| 127 | +void WebResourceHandler::DestroyArkWebResourceHandler() | ||
| 128 | +{ | ||
| 129 | + if (handler_) { | ||
| 130 | + handler_->DestroyArkWebResourceHandler(); | ||
| 131 | + handler_ = nullptr; | ||
| 132 | + } | ||
| 133 | +} | ||
| 134 | + | ||
| 135 | +WebSchemeHandlerRequest::WebSchemeHandlerRequest(napi_env env) : env_(env) {} | ||
| 136 | + | ||
| 137 | +WebSchemeHandlerRequest::WebSchemeHandlerRequest(napi_env env, const ArkWeb_ResourceRequest* request) | ||
| 138 | +{ | ||
| 139 | + env_ = env; | ||
| 140 | + if (request) { | ||
| 141 | + url_ = request->url_; | ||
| 142 | + method_ = request->method_; | ||
| 143 | + referrer_ = request->referrer_; | ||
| 144 | + isRedirect_ = request->isRedirect_; | ||
| 145 | + isMainFrame_ = request->isMainFrame_; | ||
| 146 | + hasGesture_ = request->hasGesture_; | ||
| 147 | + headerList_ = request->headerList_; | ||
| 148 | + requestResourceType_ = request->requestResourceType_; | ||
| 149 | + frameUrl_ = request->frameUrl_; | ||
| 150 | + } | ||
| 151 | +} | ||
| 152 | + | ||
| 153 | +WebSchemeHandlerRequest::~WebSchemeHandlerRequest() {} | ||
| 154 | + | ||
| 155 | +std::string WebSchemeHandlerRequest::GetUrl() const | ||
| 156 | +{ | ||
| 157 | + return url_; | ||
| 158 | +} | ||
| 159 | + | ||
| 160 | +std::string WebSchemeHandlerRequest::GetMethod() const | ||
| 161 | +{ | ||
| 162 | + return method_; | ||
| 163 | +} | ||
| 164 | +std::string WebSchemeHandlerRequest::GetReferrer() const | ||
| 165 | +{ | ||
| 166 | + return referrer_; | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | +bool WebSchemeHandlerRequest::GetIsRedirect() const | ||
| 170 | +{ | ||
| 171 | + return isRedirect_; | ||
| 172 | +} | ||
| 173 | + | ||
| 174 | +bool WebSchemeHandlerRequest::GetIsMainFrame() const | ||
| 175 | +{ | ||
| 176 | + return isMainFrame_; | ||
| 177 | +} | ||
| 178 | + | ||
| 179 | +bool WebSchemeHandlerRequest::GetHasGesture() const | ||
| 180 | +{ | ||
| 181 | + return hasGesture_; | ||
| 182 | +} | ||
| 183 | + | ||
| 184 | +WebHeaderList WebSchemeHandlerRequest::GetHeaderList() const | ||
| 185 | +{ | ||
| 186 | + return headerList_; | ||
| 187 | +} | ||
| 188 | + | ||
| 189 | +int32_t WebSchemeHandlerRequest::GetRequestResourceType() const | ||
| 190 | +{ | ||
| 191 | + return requestResourceType_; | ||
| 192 | +} | ||
| 193 | + | ||
| 194 | +std::string WebSchemeHandlerRequest::GetFrameUrl() const | ||
| 195 | +{ | ||
| 196 | + return frameUrl_; | ||
| 197 | +} | ||
| 198 | + | ||
| 199 | +void WebSchemeHandlerRequest::SetUrl(const std::string& url) | ||
| 200 | +{ | ||
| 201 | + url_ = url; | ||
| 202 | +} | ||
| 203 | + | ||
| 204 | +void WebSchemeHandlerRequest::SetMethod(const std::string& method) | ||
| 205 | +{ | ||
| 206 | + method_ = method; | ||
| 207 | +} | ||
| 208 | + | ||
| 209 | +void WebSchemeHandlerRequest::SetReferrer(const std::string& referrer) | ||
| 210 | +{ | ||
| 211 | + referrer_ = referrer; | ||
| 212 | +} | ||
| 213 | + | ||
| 214 | +void WebSchemeHandlerRequest::SetIsRedirect(bool isRedirect) | ||
| 215 | +{ | ||
| 216 | + isRedirect_ = isRedirect; | ||
| 217 | +} | ||
| 218 | + | ||
| 219 | +void WebSchemeHandlerRequest::SetIsMainFrame(bool isMainFrame) | ||
| 220 | +{ | ||
| 221 | + isMainFrame_ = isMainFrame; | ||
| 222 | +} | ||
| 223 | + | ||
| 224 | +void WebSchemeHandlerRequest::SetHasGesture(bool hasGesture) | ||
| 225 | +{ | ||
| 226 | + hasGesture_ = hasGesture; | ||
| 227 | +} | ||
| 228 | + | ||
| 229 | +void WebSchemeHandlerRequest::SetHeaderList(const WebHeaderList& headerList) | ||
| 230 | +{ | ||
| 231 | + headerList_ = headerList; | ||
| 232 | +} | ||
| 233 | + | ||
| 234 | +void WebSchemeHandlerRequest::SetRequestResourceType(int32_t requestResourceType) | ||
| 235 | +{ | ||
| 236 | + requestResourceType_ = requestResourceType; | ||
| 237 | +} | ||
| 238 | + | ||
| 239 | +void WebSchemeHandlerRequest::SetFrameUrl(const std::string& frameUrl) | ||
| 240 | +{ | ||
| 241 | + frameUrl_ = frameUrl; | ||
| 242 | +} | ||
| 243 | + | ||
| 244 | +WebSchemeHandlerResponse::WebSchemeHandlerResponse(napi_env env) : env_(env) | ||
| 245 | +{ | ||
| 246 | + if (response_ == nullptr) { | ||
| 247 | + response_ = new ArkWeb_Response(); | ||
| 248 | + } | ||
| 249 | +} | ||
| 250 | + | ||
| 251 | +WebSchemeHandlerResponse::WebSchemeHandlerResponse(napi_env env, ArkWeb_Response* response) | ||
| 252 | + : env_(env), response_(response) | ||
| 253 | +{} | ||
| 254 | + | ||
| 255 | +WebSchemeHandlerResponse::~WebSchemeHandlerResponse() | ||
| 256 | +{ | ||
| 257 | + if (response_ != nullptr) { | ||
| 258 | + delete response_; | ||
| 259 | + response_ = nullptr; | ||
| 260 | + } | ||
| 261 | +} | ||
| 262 | + | ||
| 263 | +std::string WebSchemeHandlerResponse::GetUrl() const | ||
| 264 | +{ | ||
| 265 | + if (!response_) { | ||
| 266 | + return ""; | ||
| 267 | + } | ||
| 268 | + return response_->url_; | ||
| 269 | +} | ||
| 270 | + | ||
| 271 | +int32_t WebSchemeHandlerResponse::SetUrl(const std::string url) | ||
| 272 | +{ | ||
| 273 | + if (!response_ || url.empty()) { | ||
| 274 | + return ARKWEB_INVALID_PARAM; | ||
| 275 | + } | ||
| 276 | + | ||
| 277 | + response_->url_ = url; | ||
| 278 | + return ARKWEB_NET_OK; | ||
| 279 | +} | ||
| 280 | + | ||
| 281 | +int32_t WebSchemeHandlerResponse::GetStatus() const | ||
| 282 | +{ | ||
| 283 | + if (!response_) { | ||
| 284 | + return ARKWEB_INVALID_PARAM; | ||
| 285 | + } | ||
| 286 | + return response_->status_; | ||
| 287 | +} | ||
| 288 | + | ||
| 289 | +int32_t WebSchemeHandlerResponse::SetStatus(int32_t status) | ||
| 290 | +{ | ||
| 291 | + if (!response_) { | ||
| 292 | + return ARKWEB_INVALID_PARAM; | ||
| 293 | + } | ||
| 294 | + response_->status_ = status; | ||
| 295 | + return ARKWEB_NET_OK; | ||
| 296 | +} | ||
| 297 | + | ||
| 298 | +std::string WebSchemeHandlerResponse::GetStatusText() const | ||
| 299 | +{ | ||
| 300 | + if (!response_) { | ||
| 301 | + return ""; | ||
| 302 | + } | ||
| 303 | + return response_->statusText_; | ||
| 304 | +} | ||
| 305 | + | ||
| 306 | +int32_t WebSchemeHandlerResponse::SetStatusText(const std::string statusText) | ||
| 307 | +{ | ||
| 308 | + if (!response_ || statusText.empty()) { | ||
| 309 | + return ARKWEB_INVALID_PARAM; | ||
| 310 | + } | ||
| 311 | + response_->statusText_ = statusText; | ||
| 312 | + return ARKWEB_NET_OK; | ||
| 313 | +} | ||
| 314 | + | ||
| 315 | +std::string WebSchemeHandlerResponse::GetMimeType() const | ||
| 316 | +{ | ||
| 317 | + if (!response_) { | ||
| 318 | + return ""; | ||
| 319 | + } | ||
| 320 | + return response_->mimeType_; | ||
| 321 | +} | ||
| 322 | + | ||
| 323 | +int32_t WebSchemeHandlerResponse::SetMimeType(const std::string mimeType) | ||
| 324 | +{ | ||
| 325 | + if (!response_ || mimeType.empty()) { | ||
| 326 | + return ARKWEB_INVALID_PARAM; | ||
| 327 | + } | ||
| 328 | + response_->mimeType_ = mimeType; | ||
| 329 | + return ARKWEB_NET_OK; | ||
| 330 | +} | ||
| 331 | + | ||
| 332 | +std::string WebSchemeHandlerResponse::GetEncoding() const | ||
| 333 | +{ | ||
| 334 | + if (!response_) { | ||
| 335 | + return ""; | ||
| 336 | + } | ||
| 337 | + return response_->encoding_; | ||
| 338 | +} | ||
| 339 | + | ||
| 340 | +int32_t WebSchemeHandlerResponse::SetEncoding(const std::string encoding) | ||
| 341 | +{ | ||
| 342 | + if (!response_ || encoding.empty()) { | ||
| 343 | + return ARKWEB_INVALID_PARAM; | ||
| 344 | + } | ||
| 345 | + response_->encoding_ = encoding; | ||
| 346 | + return ARKWEB_NET_OK; | ||
| 347 | +} | ||
| 348 | + | ||
| 349 | +std::string WebSchemeHandlerResponse::GetHeaderByName(const std::string name) | ||
| 350 | +{ | ||
| 351 | + if (!response_ || name.empty()) { | ||
| 352 | + return ""; | ||
| 353 | + } | ||
| 354 | + auto it = response_->headers_.find(name); | ||
| 355 | + if (it != response_->headers_.end()) { | ||
| 356 | + return it->second; | ||
| 357 | + } | ||
| 358 | + return ""; | ||
| 359 | +} | ||
| 360 | + | ||
| 361 | +int32_t WebSchemeHandlerResponse::SetHeaderByName(const std::string name, const std::string value, bool overwrite) | ||
| 362 | +{ | ||
| 363 | + if (!response_ || name.empty() || value.empty()) { | ||
| 364 | + return ARKWEB_INVALID_PARAM; | ||
| 365 | + } | ||
| 366 | + auto it = response_->headers_.find(name); | ||
| 367 | + if (overwrite) { | ||
| 368 | + response_->headers_[name] = value; | ||
| 369 | + } else { | ||
| 370 | + if (it == response_->headers_.end()) { | ||
| 371 | + response_->headers_[name] = value; | ||
| 372 | + } | ||
| 373 | + } | ||
| 374 | + return ARKWEB_NET_OK; | ||
| 375 | +} | ||
| 376 | + | ||
| 377 | +int32_t WebSchemeHandlerResponse::GetErrorCode() const | ||
| 378 | +{ | ||
| 379 | + if (!response_) { | ||
| 380 | + return ARKWEB_ERR_FAILED; | ||
| 381 | + } | ||
| 382 | + return response_->errorCode_; | ||
| 383 | +} | ||
| 384 | + | ||
| 385 | +int32_t WebSchemeHandlerResponse::SetErrorCode(int32_t code, const std::string errorDescription) | ||
| 386 | +{ | ||
| 387 | + if (!response_) { | ||
| 388 | + return ARKWEB_INVALID_PARAM; | ||
| 389 | + } | ||
| 390 | + response_->errorCode_ = code; | ||
| 391 | + response_->errorDescription_ = errorDescription; | ||
| 392 | + return ARKWEB_NET_OK; | ||
| 393 | +} | ||
| 394 | + | ||
| 395 | +WebSchemeHandler::WebSchemeHandler(napi_env env) : env_(env) | ||
| 396 | +{ | ||
| 397 | + | ||
| 398 | + ArkWeb_SchemeHandler* handler = AceWebSchemeHandler::CreateArkHandler(); | ||
| 399 | + AceWebSchemeHandler::setOnRequestStart(handler, OnRequestStart); | ||
| 400 | + AceWebSchemeHandler::setOnRequestStop(handler, OnRequestStop); | ||
| 401 | + | ||
| 402 | + | ||
| 403 | + auto handler = WebSchemeHandlerJni::CreateArkSchemeHandler(); | ||
| 404 | + WebSchemeHandlerJni::SetOnRequestStart(handler, OnRequestStart); | ||
| 405 | + WebSchemeHandlerJni::SetOnRequestStop(handler, OnRequestStop); | ||
| 406 | + | ||
| 407 | + if (!handler) { | ||
| 408 | + return; | ||
| 409 | + } | ||
| 410 | + std::lock_guard<std::mutex> auto_lock(g_mutexForHandlerMap); | ||
| 411 | + g_web_scheme_handler_map.insert(std::make_pair(this, handler)); | ||
| 412 | + g_arkui_web_scheme_handler_map.insert(std::make_pair(handler, this)); | ||
| 413 | +} | ||
| 414 | + | ||
| 415 | +WebSchemeHandler::~WebSchemeHandler() | ||
先获取锁并删除g_web_scheme_handler_map/g_arkui_web_scheme_handler_map中的条目,再释放锁并销毁handler,确保回调中不会访问到正在销毁的对象 ![]() ![]() | |||
| 416 | +{ | ||
| 417 | + ArkWeb_SchemeHandler* handler = const_cast<ArkWeb_SchemeHandler*>(GetArkWebSchemeHandler(this)); | ||
| 418 | + if (handler) { | ||
| 419 | + std::lock_guard<std::mutex> auto_lock(g_mutexForHandlerMap); | ||
| 420 | + g_web_scheme_handler_map.erase(this); | ||
| 421 | + g_arkui_web_scheme_handler_map.erase(handler); | ||
| 422 | + | ||
| 423 | + AceWebSchemeHandler::destroySchemeHandler(handler); | ||
| 424 | + | ||
| 425 | + | ||
| 426 | + WebSchemeHandlerJni::DeleteArkSchemeHandler(handler); | ||
| 427 | + | ||
| 428 | + } | ||
| 429 | +} | ||
| 430 | + | ||
| 431 | +ArkWeb_SchemeHandler* WebSchemeHandler::GetArkWebSchemeHandler(WebSchemeHandler* handler) | ||
| 432 | +{ | ||
| 433 | + if (!handler) { | ||
| 434 | + return nullptr; | ||
| 435 | + } | ||
| 436 | + std::lock_guard<std::mutex> lock(g_mutexForHandlerMap); | ||
| 437 | + auto it = g_web_scheme_handler_map.find(handler); | ||
| 438 | + if (it != g_web_scheme_handler_map.end()) { | ||
| 439 | + return it->second; | ||
| 440 | + } | ||
| 441 | + return nullptr; | ||
| 442 | +} | ||
| 443 | + | ||
| 444 | +WebSchemeHandler* WebSchemeHandler::GetWebSchemeHandler(ArkWeb_SchemeHandler* arkHandler) | ||
| 445 | +{ | ||
| 446 | + if (!arkHandler) { | ||
| 447 | + return nullptr; | ||
| 448 | + } | ||
| 449 | + std::lock_guard<std::mutex> lock(g_mutexForHandlerMap); | ||
| 450 | + auto it = g_arkui_web_scheme_handler_map.find(arkHandler); | ||
| 451 | + if (it != g_arkui_web_scheme_handler_map.end()) { | ||
| 452 | + return it->second; | ||
| 453 | + } | ||
| 454 | + return nullptr; | ||
| 455 | +} | ||
| 456 | + | ||
| 457 | +void WebSchemeHandler::ClearWebSchemeHandler() | ||
| 458 | +{ | ||
| 459 | + std::lock_guard<std::mutex> lock(g_mutexForHandlerMap); | ||
| 460 | + g_web_scheme_handler_map.clear(); | ||
| 461 | + g_arkui_web_scheme_handler_map.clear(); | ||
| 462 | +} | ||
| 463 | + | ||
| 464 | +void WebSchemeHandler::PutRequestStart(napi_env, napi_value callback) | ||
| 465 | +{ | ||
| 466 | + napi_status status = napi_create_reference(env_, callback, 1, &request_start_callback_); | ||
| 467 | + if (status != napi_status::napi_ok) { | ||
| 468 | + LOGE("PutRequestStart create reference failed."); | ||
| 469 | + } | ||
| 470 | +} | ||
| 471 | + | ||
| 472 | +void WebSchemeHandler::PutRequestStop(napi_env, napi_value callback) | ||
| 473 | +{ | ||
| 474 | + napi_status status = napi_create_reference(env_, callback, 1, &request_stop_callback_); | ||
| 475 | + if (status != napi_status::napi_ok) { | ||
| 476 | + LOGE("PutRequestStop create reference failed."); | ||
| 477 | + } | ||
| 478 | +} | ||
| 479 | + | ||
| 480 | +void WebSchemeHandler::RequestStart( | ||
| 481 | + ArkWeb_ResourceRequest* request, ArkWeb_ResourceHandler* arkWeb_ResourceHandler, bool* intercept) | ||
| 482 | +{ | ||
| 483 | + napi_handle_scope scope; | ||
| 484 | + napi_status status_scope = napi_open_handle_scope(env_, &scope); | ||
| 485 | + if (status_scope != napi_ok) { | ||
| 486 | + LOGE("scheme handler RequestStart scope is nullptr"); | ||
| 487 | + return; | ||
| 488 | + } | ||
| 489 | + size_t paramCount = 2; | ||
| 490 | + napi_value callbackFunc = nullptr; | ||
| 491 | + napi_status status; | ||
| 492 | + if (!request_start_callback_) { | ||
| 493 | + LOGE("scheme handler onRequestStart nil env"); | ||
| 494 | + return; | ||
| 495 | + } | ||
| 496 | + status = napi_get_reference_value(env_, request_start_callback_, &callbackFunc); | ||
| 497 | + if (status != napi_ok || callbackFunc == nullptr) { | ||
| 498 | + LOGE("scheme handler get onRequestStart func failed."); | ||
| 499 | + return; | ||
| 500 | + } | ||
| 501 | + | ||
| 502 | + napi_value requestValue[2] = { 0 }; | ||
| 503 | + napi_create_object(env_, &requestValue[0]); | ||
| 504 | + napi_create_object(env_, &requestValue[1]); | ||
| 505 | + WebSchemeHandlerRequest* schemeHandlerRequest = new (std::nothrow) WebSchemeHandlerRequest(env_, request); | ||
| 506 | + if (schemeHandlerRequest == nullptr) { | ||
| 507 | + LOGE("RequestStart, new schemeHandlerRequest failed"); | ||
| 508 | + return; | ||
| 509 | + } | ||
| 510 | + std::shared_ptr<WebResourceHandler> resourceHandler = | ||
| 511 | + std::make_shared<WebResourceHandler>(env_, arkWeb_ResourceHandler); | ||
| 512 | + if (resourceHandler == nullptr) { | ||
| 513 | + LOGE("RequestStart, new resourceHandler failed"); | ||
| 514 | + delete schemeHandlerRequest; | ||
| 515 | + return; | ||
| 516 | + } | ||
| 517 | + napi_wrap( | ||
| 518 | + env_, requestValue[0], schemeHandlerRequest, | ||
| 519 | + [](napi_env /* env */, void* data, void* /* hint */) { | ||
| 520 | + WebSchemeHandlerRequest* request = (WebSchemeHandlerRequest*)data; | ||
| 521 | + delete request; | ||
| 522 | + }, | ||
| 523 | + nullptr, nullptr); | ||
| 524 | + NapiWebSchemeHandlerRequest::DefineProperties(env_, &requestValue[0]); | ||
| 525 | + napi_wrap( | ||
| 526 | + env_, requestValue[1], resourceHandler.get(), | ||
| 527 | + [](napi_env /* env */, void* data, void* /* hint */) {}, nullptr, nullptr); | ||
| 528 | + NapiWebResourceHandler::DefineProperties(env_, &requestValue[1]); | ||
| 529 | + napi_value result = nullptr; | ||
| 530 | + status = napi_call_function(env_, nullptr, callbackFunc, paramCount, requestValue, &result); | ||
| 531 | + if (status != napi_status::napi_ok) { | ||
| 532 | + LOGE("scheme handler call onRequestStart failed."); | ||
| 533 | + } | ||
| 534 | + if (!NapiParseUtils::ParseBoolean(env_, result, *intercept)) { | ||
| 535 | + LOGE("scheme handler onRequestStart intercept parse failed"); | ||
| 536 | + *intercept = false; | ||
| 537 | + } | ||
| 538 | + if (!*intercept) { | ||
| 539 | + resourceHandler->SetFinishFlag(); | ||
| 540 | + } | ||
| 541 | +} | ||
| 542 | + | ||
| 543 | +void WebSchemeHandler::RequestStop(ArkWeb_ResourceRequest* resourceRequest) | ||
| 544 | +{ | ||
| 545 | + uv_loop_s* loop = nullptr; | ||
| 546 | + uv_work_t* work = nullptr; | ||
| 547 | + napi_get_uv_event_loop(env_, &loop); | ||
| 548 | + if (loop == nullptr) { | ||
| 549 | + return; | ||
| 550 | + } | ||
| 551 | + work = new (std::nothrow) uv_work_t; | ||
| 552 | + if (work == nullptr) { | ||
| 553 | + return; | ||
| 554 | + } | ||
| 555 | + RequestStopParam* param = new (std::nothrow) RequestStopParam(); | ||
| 556 | + if (param == nullptr) { | ||
| 557 | + delete work; | ||
| 558 | + return; | ||
| 559 | + } | ||
| 560 | + param->env_ = env_; | ||
| 561 | + param->callbackRef_ = request_stop_callback_; | ||
| 562 | + param->request_ = new (std::nothrow) WebSchemeHandlerRequest(param->env_, resourceRequest); | ||
| 563 | + if (param->request_ == nullptr) { | ||
| 564 | + delete work; | ||
| 565 | + delete param; | ||
| 566 | + return; | ||
| 567 | + } | ||
| 568 | + param->arkWebRequest_ = resourceRequest; | ||
| 569 | + work->data = reinterpret_cast<void*>(param); | ||
| 570 | + int ret = uv_queue_work_with_qos(loop, work, [](uv_work_t* work) {}, RequestStopAfterWorkCb, uv_qos_user_initiated); | ||
| 571 | + if (ret != 0) { | ||
| 572 | + if (param != nullptr) { | ||
| 573 | + delete param; | ||
| 574 | + param = nullptr; | ||
| 575 | + } | ||
| 576 | + if (work != nullptr) { | ||
| 577 | + delete work; | ||
| 578 | + work = nullptr; | ||
| 579 | + } | ||
| 580 | + } | ||
| 581 | +} | ||
| 582 | + | ||
| 583 | +static void RequestStopAfterWorkCb(uv_work_t* work, int status) | ||
| 584 | +{ | ||
| 585 | + RequestStopParam* param = reinterpret_cast<RequestStopParam*>(work->data); | ||
| 586 | + if (param == nullptr) { | ||
| 587 | + delete work; | ||
| 588 | + return; | ||
| 589 | + } | ||
| 590 | + | ||
| 591 | + napi_handle_scope scope; | ||
| 592 | + napi_status status_scope = napi_open_handle_scope(param->env_, &scope); | ||
| 593 | + if (status_scope != napi_ok) { | ||
| 594 | + LOGE("scheme handler RequestStopAfterWorkCb scope is nullptr"); | ||
| 595 | + delete param->request_; | ||
| 596 | + delete param; | ||
| 597 | + delete work; | ||
| 598 | + return; | ||
| 599 | + } | ||
| 600 | + | ||
| 601 | + if (param->callbackRef_) { | ||
| 602 | + napi_value callbackFunc = nullptr; | ||
| 603 | + napi_status napi_status = napi_get_reference_value(param->env_, param->callbackRef_, &callbackFunc); | ||
| 604 | + if (napi_status == napi_ok && callbackFunc != nullptr) { | ||
| 605 | + napi_value requestValue; | ||
| 606 | + napi_create_object(param->env_, &requestValue); | ||
| 607 | + napi_wrap( | ||
| 608 | + param->env_, requestValue, param->request_, | ||
| 609 | + [](napi_env /* env */, void* data, void* /* hint */) { | ||
| 610 | + WebSchemeHandlerRequest* request = (WebSchemeHandlerRequest*)data; | ||
| 611 | + delete request; | ||
| 612 | + }, | ||
| 613 | + nullptr, nullptr); | ||
| 614 | + NapiWebSchemeHandlerRequest::DefineProperties(param->env_, &requestValue); | ||
| 615 | + | ||
| 616 | + napi_value result = nullptr; | ||
| 617 | + napi_status = napi_call_function(param->env_, nullptr, callbackFunc, 1, &requestValue, &result); | ||
| 618 | + if (napi_status != napi_status::napi_ok) { | ||
| 619 | + LOGE("scheme handler call onRequestStop failed."); | ||
| 620 | + } | ||
| 621 | + } | ||
| 622 | + } else { | ||
| 623 | + delete param->request_; | ||
| 624 | + } | ||
| 625 | + | ||
| 626 | + napi_close_handle_scope(param->env_, scope); | ||
| 627 | + delete param; | ||
| 628 | + delete work; | ||
| 629 | +} | ||
| 630 | +} // namespace OHOS::Plugin | ||
| @@ -0,0 +1,146 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + | ||
| 34 | +namespace OHOS::Plugin { | ||
| 35 | +using WebHeaderList = std::vector<std::pair<std::string, std::string>>; | ||
| 36 | +class WebSchemeHandlerRequest { | ||
| 37 | +public: | ||
| 38 | + explicit WebSchemeHandlerRequest(napi_env env); | ||
| 39 | + WebSchemeHandlerRequest(napi_env env, const ArkWeb_ResourceRequest* request); | ||
| 40 | + ~WebSchemeHandlerRequest(); | ||
| 41 | + | ||
| 42 | +public: | ||
| 43 | + std::string GetUrl() const; | ||
| 44 | + std::string GetMethod() const; | ||
| 45 | + std::string GetReferrer() const; | ||
| 46 | + bool GetIsRedirect() const; | ||
| 47 | + bool GetIsMainFrame() const; | ||
| 48 | + bool GetHasGesture() const; | ||
| 49 | + WebHeaderList GetHeaderList() const; | ||
| 50 | + int32_t GetRequestResourceType() const; | ||
| 51 | + std::string GetFrameUrl() const; | ||
| 52 | + void SetUrl(const std::string& url); | ||
| 53 | + void SetMethod(const std::string& method); | ||
| 54 | + void SetReferrer(const std::string& referrer); | ||
| 55 | + void SetIsRedirect(bool isRedirect); | ||
| 56 | + void SetIsMainFrame(bool isMainFrame); | ||
| 57 | + void SetHasGesture(bool hasGesture); | ||
| 58 | + void SetHeaderList(const WebHeaderList& headerList); | ||
| 59 | + void SetRequestResourceType(int32_t requestResourceType); | ||
| 60 | + void SetFrameUrl(const std::string& frameUrl); | ||
| 61 | + | ||
| 62 | +private: | ||
| 63 | + std::string url_ = ""; | ||
| 64 | + std::string method_ = ""; | ||
| 65 | + std::string referrer_ = ""; | ||
| 66 | + bool isRedirect_ = false; | ||
| 67 | + bool isMainFrame_ = false; | ||
| 68 | + bool hasGesture_ = false; | ||
| 69 | + WebHeaderList headerList_; | ||
| 70 | + int32_t requestResourceType_ = -1; | ||
| 71 | + std::string frameUrl_ = ""; | ||
| 72 | + napi_env env_; | ||
| 73 | +}; | ||
| 74 | + | ||
| 75 | +class WebSchemeHandlerResponse { | ||
| 76 | +public: | ||
| 77 | + explicit WebSchemeHandlerResponse(napi_env env); | ||
| 78 | + WebSchemeHandlerResponse(napi_env env, ArkWeb_Response* response); | ||
| 79 | + ~WebSchemeHandlerResponse(); | ||
| 80 | + | ||
| 81 | + std::string GetUrl() const; | ||
| 82 | + int32_t SetUrl(const std::string url); | ||
| 83 | + int32_t GetStatus() const; | ||
| 84 | + int32_t SetStatus(int32_t status); | ||
| 85 | + std::string GetStatusText() const; | ||
| 86 | + int32_t SetStatusText(const std::string statusText); | ||
| 87 | + std::string GetMimeType() const; | ||
| 88 | + int32_t SetMimeType(const std::string mimeType); | ||
| 89 | + std::string GetEncoding() const; | ||
| 90 | + int32_t SetEncoding(const std::string encoding); | ||
| 91 | + std::string GetHeaderByName(const std::string name); | ||
| 92 | + int32_t SetHeaderByName(const std::string name, const std::string value, bool overwrite); | ||
| 93 | + int32_t GetErrorCode() const; | ||
| 94 | + int32_t SetErrorCode(int32_t code, const std::string errorDescription); | ||
| 95 | + ArkWeb_Response* GetArkWebResponse() | ||
| 96 | + { | ||
| 97 | + return response_; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | +private: | ||
| 101 | + napi_env env_; | ||
| 102 | + ArkWeb_Response* response_ = nullptr; | ||
| 103 | +}; | ||
| 104 | + | ||
| 105 | +class WebResourceHandler { | ||
| 106 | +public: | ||
| 107 | + explicit WebResourceHandler(napi_env env); | ||
| 108 | + WebResourceHandler(napi_env env, const ArkWeb_ResourceHandler* handler); | ||
| 109 | + ~WebResourceHandler(); | ||
| 110 | + int32_t DidReceiveResponse(const ArkWeb_Response* response); | ||
| 111 | + int32_t DidReceiveResponseBody(const uint8_t* webResourceHandlerbuffer, int64_t bufferLen); | ||
| 112 | + int32_t DidFinish(); | ||
| 113 | + int32_t DidFailWithError(ArkWeb_NetError errorCode, const std::string errorDescription, bool completeIfNoResponse); | ||
| 114 | + void DestroyArkWebResourceHandler(); | ||
| 115 | + void SetFinishFlag() | ||
| 116 | + { | ||
| 117 | + isFinished_ = true; | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | +private: | ||
| 121 | + bool isFinished_ = false; | ||
| 122 | + ArkWeb_ResourceHandler* handler_ = nullptr; | ||
| 123 | + napi_env env_; | ||
| 124 | +}; | ||
| 125 | + | ||
| 126 | +class WebSchemeHandler { | ||
| 127 | +public: | ||
| 128 | + explicit WebSchemeHandler(napi_env env); | ||
| 129 | + ~WebSchemeHandler(); | ||
| 130 | + napi_ref delegate_ = nullptr; | ||
| 131 | + static ArkWeb_SchemeHandler* GetArkWebSchemeHandler(WebSchemeHandler* handler); | ||
| 132 | + static WebSchemeHandler* GetWebSchemeHandler(ArkWeb_SchemeHandler* handler); | ||
| 133 | + static void ClearWebSchemeHandler(); | ||
| 134 | + void RequestStart(ArkWeb_ResourceRequest* request, ArkWeb_ResourceHandler* ArkWeb_ResourceHandler, bool* intercept); | ||
| 135 | + void RequestStop(ArkWeb_ResourceRequest* resourceRequest); | ||
| 136 | + | ||
| 137 | + void PutRequestStart(napi_env, napi_value callback); | ||
| 138 | + void PutRequestStop(napi_env, napi_value callback); | ||
| 139 | + | ||
| 140 | +private: | ||
| 141 | + napi_env env_; | ||
| 142 | + napi_ref request_start_callback_ = nullptr; | ||
| 143 | + napi_ref request_stop_callback_ = nullptr; | ||
| 144 | +}; | ||
| 145 | +} // namespace OHOS::Plugin | ||
| 146 | + | ||
| @@ -28,4 +28,6 @@ web_include = [ | |||
| 28 | web_source = [ | 28 | web_source = [ |
| 29 | "$SUBSYSTEM_DIR/interfaces/kits/nativecommon/web_errors.cpp", | 29 | "$SUBSYSTEM_DIR/interfaces/kits/nativecommon/web_errors.cpp", |
| 30 | "$SUBSYSTEM_DIR/interfaces/kits/napi/common/business_error.cpp", | 30 | "$SUBSYSTEM_DIR/interfaces/kits/napi/common/business_error.cpp", |
| 31 | + "$SUBSYSTEM_DIR/interfaces/kits/napi/web_net_error_code/napi_web_net_errorcode.cpp", | ||
| 32 | + "$SUBSYSTEM_DIR/interfaces/kits/napi/web_net_error_code/napi_web_net_errorcode_module.cpp", | ||
| 31 | ] | 33 | ] |
| @@ -26,6 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | + | ||
| 29 | 30 | ||
| 30 | namespace OHOS::Plugin { | 31 | namespace OHOS::Plugin { |
| 31 | struct WebHistoryItem final { | 32 | struct WebHistoryItem final { |
| @@ -125,6 +126,9 @@ public: | |||
| 125 | virtual int32_t GetPageHeight() = 0; | 126 | virtual int32_t GetPageHeight() = 0; |
| 126 | virtual void RegisterJavaScriptProxy(const RegisterJavaScriptProxyParam& param) = 0; | 127 | virtual void RegisterJavaScriptProxy(const RegisterJavaScriptProxyParam& param) = 0; |
| 127 | virtual void DeleteJavaScriptRegister(const std::string& objName) = 0; | 128 | virtual void DeleteJavaScriptRegister(const std::string& objName) = 0; |
| 129 | + virtual bool SetWebSchemeHandler(const char* scheme, WebSchemeHandler* handler) = 0; | ||
| 130 | + virtual bool ClearWebSchemeHandler() = 0; | ||
| 131 | + virtual std::string GetUserAgent() = 0; | ||
| 128 | virtual ErrCode ClearHistory() { | 132 | virtual ErrCode ClearHistory() { |
| 129 | return NWebError::NO_ERROR; | 133 | return NWebError::NO_ERROR; |
| 130 | } | 134 | } |


g_webViewClass