• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }