1 /* 2 * Copyright (c) 2024 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 #include <cstdint> 17 #include <thread> 18 #include "web_scheme_handler_request.h" 19 #include "webview_javascript_execute_callback.h" 20 #include "native_arkweb_utils.h" 21 #include "native_interface_arkweb.h" 22 #include "cj_common_ffi.h" 23 #include "application_context.h" 24 #include "webview_log.h" 25 #include "webview_utils.h" 26 #include "nweb_store_web_archive_callback.h" 27 28 namespace OHOS::Webview { GetRequestResourceType()29 int WebSchemeHandlerRequestImpl::GetRequestResourceType() 30 { 31 return requestResourceType_; 32 } 33 HasGesture()34 bool WebSchemeHandlerRequestImpl::HasGesture() 35 { 36 return hasGesture_; 37 } 38 IsMainFrame()39 bool WebSchemeHandlerRequestImpl::IsMainFrame() 40 { 41 return isMainFrame_; 42 } 43 IsRedirect()44 bool WebSchemeHandlerRequestImpl::IsRedirect() 45 { 46 return isRedirect_; 47 } 48 GetRequestUrl()49 std::string WebSchemeHandlerRequestImpl::GetRequestUrl() 50 { 51 return url_; 52 } 53 GetMethod()54 std::string WebSchemeHandlerRequestImpl::GetMethod() 55 { 56 return method_; 57 } 58 GetReferrer()59 std::string WebSchemeHandlerRequestImpl::GetReferrer() 60 { 61 return referrer_; 62 } 63 GetFrameUrl()64 std::string WebSchemeHandlerRequestImpl::GetFrameUrl() 65 { 66 return frameUrl_; 67 } 68 GetHeader()69 const WebHeaderList& WebSchemeHandlerRequestImpl::GetHeader() 70 { 71 return headerList_; 72 } 73 GetHttpBodyStream()74 ArkWeb_HttpBodyStream* WebSchemeHandlerRequestImpl::GetHttpBodyStream() 75 { 76 return stream_; 77 } 78 HttpBodyStreamInitCallback(const ArkWeb_HttpBodyStream * httpBodyStream,ArkWeb_NetError result)79 void WebHttpBodyStreamImpl::HttpBodyStreamInitCallback( 80 const ArkWeb_HttpBodyStream* httpBodyStream, ArkWeb_NetError result) 81 { 82 WEBVIEWLOGD("WebHttpBodyStream::HttpBodyStreamInitCallback"); 83 WebHttpBodyStreamImpl* stream = reinterpret_cast<WebHttpBodyStreamImpl*>( 84 OH_ArkWebHttpBodyStream_GetUserData(httpBodyStream)); 85 if (!stream) { 86 WEBVIEWLOGD("OH_ArkWebHttpBodyStream_GetUserData is nullptr"); 87 return; 88 } 89 } 90 initialize()91 int32_t WebHttpBodyStreamImpl::initialize() 92 { 93 int ret = OH_ArkWebHttpBodyStream_Init(stream_, &WebHttpBodyStreamImpl::HttpBodyStreamInitCallback); 94 if (ret != 0) { 95 WEBVIEWLOGD("OH_ArkWebHttpBodyStream_Init failed"); 96 return NWebError::HTTP_BODY_STREAN_INIT_FAILED; 97 } 98 return NWebError::NO_ERROR; 99 } 100 Read(int32_t bufLen)101 int32_t WebHttpBodyStreamImpl::Read(int32_t bufLen) 102 { 103 WEBVIEWLOGD("WebHttpBodyStreamImpl::Read"); 104 if (bufLen <= 0) { 105 WEBVIEWLOGE("WebHttpBodyStreamImpl::Read failed: bufLen is illegal"); 106 return NWebError::PARAM_CHECK_ERROR; 107 } 108 uint8_t* buffer = new (std::nothrow) uint8_t[bufLen]; 109 if (buffer == nullptr) { 110 WEBVIEWLOGE("WebHttpBodyStreamImpl::Read failed: buffer is null"); 111 return NWebError::PARAM_CHECK_ERROR; 112 } 113 OH_ArkWebHttpBodyStream_Read(stream_, buffer, bufLen); 114 delete[] buffer; 115 return NWebError::NO_ERROR; 116 } 117 GetPostion()118 uint64_t WebHttpBodyStreamImpl::GetPostion() 119 { 120 return OH_ArkWebHttpBodyStream_GetPosition(stream_); 121 } 122 GetSize()123 uint64_t WebHttpBodyStreamImpl::GetSize() 124 { 125 return OH_ArkWebHttpBodyStream_GetSize(stream_); 126 } 127 IsChunked()128 bool WebHttpBodyStreamImpl::IsChunked() 129 { 130 return OH_ArkWebHttpBodyStream_IsChunked(stream_); 131 } 132 IsEof()133 bool WebHttpBodyStreamImpl::IsEof() 134 { 135 return OH_ArkWebHttpBodyStream_IsEof(stream_); 136 } 137 IsInMemory()138 bool WebHttpBodyStreamImpl::IsInMemory() 139 { 140 return OH_ArkWebHttpBodyStream_IsInMemory(stream_); 141 } 142 DidReceiveResponse(const ArkWeb_Response * response)143 int32_t WebResourceHandlerImpl::DidReceiveResponse(const ArkWeb_Response* response) 144 { 145 if (isFinished_) { 146 return ArkWeb_ErrorCode::ARKWEB_ERROR_UNKNOWN; 147 } 148 return OH_ArkWebResourceHandler_DidReceiveResponse(handler_, response); 149 } 150 DidReceiveResponseBody(const uint8_t * buffer,int64_t buflen)151 int32_t WebResourceHandlerImpl::DidReceiveResponseBody(const uint8_t* buffer, int64_t buflen) 152 { 153 if (isFinished_) { 154 return ArkWeb_ErrorCode::ARKWEB_ERROR_UNKNOWN; 155 } 156 return OH_ArkWebResourceHandler_DidReceiveData(handler_, buffer, buflen); 157 } 158 DidFinish()159 int32_t WebResourceHandlerImpl::DidFinish() 160 { 161 if (isFinished_) { 162 return ArkWeb_ErrorCode::ARKWEB_ERROR_UNKNOWN; 163 } 164 int32_t ret = OH_ArkWebResourceHandler_DidFinish(handler_); 165 if (ret == 0) { 166 isFinished_ = true; 167 } 168 return ret; 169 } 170 DidFailWithError(ArkWeb_NetError errorCode)171 int32_t WebResourceHandlerImpl::DidFailWithError(ArkWeb_NetError errorCode) 172 { 173 if (isFinished_) { 174 return ArkWeb_ErrorCode::ARKWEB_ERROR_UNKNOWN; 175 } 176 int32_t ret = OH_ArkWebResourceHandler_DidFailWithError(handler_, errorCode); 177 if (ret == 0) { 178 isFinished_ = true; 179 } 180 return ret; 181 } 182 DestroyArkWebResourceHandler()183 void WebResourceHandlerImpl::DestroyArkWebResourceHandler() 184 { 185 if (handler_) { 186 OH_ArkWebResourceHandler_Destroy(handler_); 187 handler_ = nullptr; 188 } 189 } 190 OnRequestStart(const ArkWeb_SchemeHandler * schemeHandler,ArkWeb_ResourceRequest * resourceRequest,const ArkWeb_ResourceHandler * resourceHandler,bool * intercept)191 void OnRequestStart( 192 const ArkWeb_SchemeHandler* schemeHandler, 193 ArkWeb_ResourceRequest* resourceRequest, 194 const ArkWeb_ResourceHandler* resourceHandler, 195 bool* intercept) 196 { 197 WEBVIEWLOGD("SchemeHandler OnRequestStart"); 198 if (!schemeHandler) { 199 WEBVIEWLOGD("OnRequestStart schemeHandler is nullptr"); 200 return; 201 } 202 WebSchemeHandlerImpl* handler = 203 WebSchemeHandlerImpl::GetWebSchemeHandler(schemeHandler); 204 if (!handler) { 205 WEBVIEWLOGD("GetWebSchemeHandler failed"); 206 return; 207 } 208 handler->RequestStart(resourceRequest, resourceHandler, 209 intercept); 210 } 211 OnRequestStop(const ArkWeb_SchemeHandler * schemeHandler,const ArkWeb_ResourceRequest * resourceRequest)212 void OnRequestStop( 213 const ArkWeb_SchemeHandler* schemeHandler, const ArkWeb_ResourceRequest* resourceRequest) 214 { 215 WEBVIEWLOGD("SchemeHandler OnRequestStop"); 216 if (!schemeHandler) { 217 WEBVIEWLOGD("OnRequestStop schemeHandler is nullptr"); 218 return; 219 } 220 WebSchemeHandlerImpl* handler = 221 WebSchemeHandlerImpl::GetWebSchemeHandler(schemeHandler); 222 if (!handler) { 223 WEBVIEWLOGD("GetWebSchemeHandler failed"); 224 return; 225 } 226 handler->RequestStop(resourceRequest); 227 } 228 229 std::unordered_map<WebSchemeHandlerImpl*, const ArkWeb_SchemeHandler*> 230 WebSchemeHandlerImpl::webSchemeHandlerMap_; 231 std::unordered_map<const ArkWeb_SchemeHandler*, WebSchemeHandlerImpl*> 232 WebSchemeHandlerImpl::arkWebSchemeHandlerMap_; 233 GetArkWebSchemeHandler(WebSchemeHandlerImpl * handler)234 const ArkWeb_SchemeHandler* WebSchemeHandlerImpl::GetArkWebSchemeHandler( 235 WebSchemeHandlerImpl* handler) 236 { 237 return WebSchemeHandlerImpl::webSchemeHandlerMap_.find(handler) != 238 WebSchemeHandlerImpl::webSchemeHandlerMap_.end() ? 239 WebSchemeHandlerImpl::webSchemeHandlerMap_[handler] : nullptr; 240 } 241 GetWebSchemeHandler(const ArkWeb_SchemeHandler * handler)242 WebSchemeHandlerImpl* WebSchemeHandlerImpl::GetWebSchemeHandler(const ArkWeb_SchemeHandler* handler) 243 { 244 return WebSchemeHandlerImpl::arkWebSchemeHandlerMap_.find(handler) != 245 WebSchemeHandlerImpl::arkWebSchemeHandlerMap_.end() ? 246 WebSchemeHandlerImpl::arkWebSchemeHandlerMap_[handler] : nullptr; 247 } 248 WebSchemeHandlerImpl()249 WebSchemeHandlerImpl::WebSchemeHandlerImpl() 250 { 251 ArkWeb_SchemeHandler* handler; 252 OH_ArkWeb_CreateSchemeHandler(&handler); 253 if (!handler) { 254 WEBVIEWLOGD("create WebSchemeHandler failed"); 255 return; 256 } 257 onRequestStart_ = &OnRequestStart; 258 onRequestStop_ = &OnRequestStop; 259 OH_ArkWebSchemeHandler_SetOnRequestStart(handler, onRequestStart_); 260 OH_ArkWebSchemeHandler_SetOnRequestStop(handler, onRequestStop_); 261 OH_ArkWebSchemeHandler_SetFromEts(handler, true); 262 webSchemeHandlerMap_.insert(std::make_pair(this, handler)); 263 arkWebSchemeHandlerMap_.insert(std::make_pair(handler, this)); 264 } 265 ~WebSchemeHandlerImpl()266 WebSchemeHandlerImpl::~WebSchemeHandlerImpl() 267 { 268 WEBVIEWLOGD("WebSchemeHandler::~WebSchemeHandler"); 269 ArkWeb_SchemeHandler* handler = 270 const_cast<ArkWeb_SchemeHandler*>(GetArkWebSchemeHandler(this)); 271 if (!handler) { 272 WEBVIEWLOGD("~WebSchemeHandler not found ArkWeb_SchemeHandler"); 273 return; 274 } 275 webSchemeHandlerMap_.erase(this); 276 arkWebSchemeHandlerMap_.erase(handler); 277 OH_ArkWeb_DestroySchemeHandler(handler); 278 } 279 RequestStart(ArkWeb_ResourceRequest * request,const ArkWeb_ResourceHandler * ArkWeb_ResourceHandler,bool * intercept)280 void WebSchemeHandlerImpl::RequestStart( 281 ArkWeb_ResourceRequest* request, 282 const ArkWeb_ResourceHandler* ArkWeb_ResourceHandler, 283 bool* intercept) 284 { 285 WEBVIEWLOGI("[SchemeHandler] WebSchemeHandlerImpl::RequestStart"); 286 if (!request_start_callback_) { 287 WEBVIEWLOGE("[SchemeHandler] :RequestStart not exists."); 288 return; 289 } 290 sptr<WebSchemeHandlerRequestImpl> schemeHandlerRequest = FFIData::Create<WebSchemeHandlerRequestImpl>(request); 291 if (schemeHandlerRequest == nullptr) { 292 WEBVIEWLOGD("RequestStart, new schemeHandlerRequest failed"); 293 return; 294 } 295 sptr<WebResourceHandlerImpl> resourceHandler = FFIData::Create<WebResourceHandlerImpl>(ArkWeb_ResourceHandler); 296 if (resourceHandler == nullptr) { 297 WEBVIEWLOGD("RequestStart, new resourceHandler failed"); 298 return; 299 } 300 if (OH_ArkWebResourceRequest_SetUserData(request, resourceHandler) != 0) { 301 WEBVIEWLOGD("OH_ArkWebResourceRequest_SetUserData failed"); 302 } else { 303 resourceHandler->IncStrongRef(nullptr); 304 } 305 *intercept = request_start_callback_(schemeHandlerRequest->GetID(), resourceHandler->GetID()); 306 if (!*intercept) { 307 resourceHandler->SetFinishFlag(); 308 resourceHandler->DecStrongRef(nullptr); 309 } 310 } 311 RequestStopAfterWorkCb(RequestStopParam * param)312 void WebSchemeHandlerImpl::RequestStopAfterWorkCb(RequestStopParam* param) 313 { 314 WEBVIEWLOGI("[SchemeHandler] WebSchemeHandlerImpl::RequestStopAfterWorkCb"); 315 if (!param->callbackRef_) { 316 WEBVIEWLOGI("scheme handler onRequestStop not exists"); 317 delete param; 318 return; 319 } 320 param->callbackRef_(param->request_->GetID()); 321 WebResourceHandlerImpl* resourceHandler = 322 reinterpret_cast<WebResourceHandlerImpl*>( 323 OH_ArkWebResourceRequest_GetUserData(param->arkWebRequest_)); 324 if (resourceHandler) { 325 resourceHandler->SetFinishFlag(); 326 } 327 delete param; 328 param = nullptr; 329 } 330 RequestStop(const ArkWeb_ResourceRequest * resourceRequest)331 void WebSchemeHandlerImpl::RequestStop(const ArkWeb_ResourceRequest* resourceRequest) 332 { 333 WEBVIEWLOGI("[SchemeHandler] WebSchemeHandlerImpl::RequestStop"); 334 RequestStopParam *param = new (std::nothrow) RequestStopParam(); 335 if (param == nullptr) { 336 return; 337 } 338 param->callbackRef_ = request_stop_callback_; 339 param->request_ = FFIData::Create<WebSchemeHandlerRequestImpl>(resourceRequest); 340 if (param->request_ == nullptr) { 341 delete param; 342 return; 343 } 344 param->arkWebRequest_ = resourceRequest; 345 std::thread([param]() { 346 RequestStopAfterWorkCb(param); 347 }).detach(); 348 } 349 PutRequestStart(std::function<bool (int64_t,int64_t)> callback)350 void WebSchemeHandlerImpl::PutRequestStart(std::function<bool(int64_t, int64_t)> callback) 351 { 352 WEBVIEWLOGI("[SchemeHandler] WebSchemeHandlerImpl::PutRequestStart"); 353 request_start_callback_ = callback; 354 } 355 PutRequestStop(std::function<void (int64_t)> callback)356 void WebSchemeHandlerImpl::PutRequestStop(std::function<void(int64_t)> callback) 357 { 358 WEBVIEWLOGI("WebSchemeHandlerImpl::PutRequestStop"); 359 request_stop_callback_ = callback; 360 } 361 }