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 #ifndef WEB_SCHEME_HANDLER_REQUEST_H 17 #define WEB_SCHEME_HANDLER_REQUEST_H 18 19 #include <cstdint> 20 #include <map> 21 #include "ffi_remote_data.h" 22 #include "web_errors.h" 23 #include "webview_javascript_result_callback.h" 24 #include "nweb.h" 25 #include "nweb_helper.h" 26 #include "arkweb_scheme_handler.h" 27 #include "nweb_log.h" 28 29 namespace OHOS::Webview { 30 enum class WebResourceType : int { 31 MAIN_FRAME = 0, 32 SUB_FRAME = 1, 33 STYLE_SHEET = 2, 34 SCRIPT = 3, 35 IMAGE = 4, 36 FONT_RESOURCE = 5, 37 SUB_RESOURCE = 6, 38 OBJECT = 7, 39 MEDIA = 8, 40 WORKED = 9, 41 SHARED_WORKED = 10, 42 PREFETCH = 11, 43 FAVICON = 12, 44 XHR = 13, 45 PING = 14, 46 SERVICE_WORKED = 15, 47 CSP_REPORT = 16, 48 PLUNGIN_RESOURCE = 17, 49 NAVIGATION_PRELOAD_MAIN_FRAME = 19, 50 NAVIGATION_PRELOAD_SUB_FRAME = 20 51 }; 52 53 //WebHttpBodyStream 54 class WebHttpBodyStreamImpl : public OHOS::FFI::FFIData { 55 DECL_TYPE(WebHttpBodyStreamImpl, OHOS::FFI::FFIData) 56 public: 57 explicit WebHttpBodyStreamImpl() = default; WebHttpBodyStreamImpl(ArkWeb_HttpBodyStream * stream)58 WebHttpBodyStreamImpl(ArkWeb_HttpBodyStream* stream) 59 { 60 stream_ = stream; 61 }; ~WebHttpBodyStreamImpl()62 ~WebHttpBodyStreamImpl() 63 { 64 if (!stream_) { 65 OH_ArkWebResourceRequest_DestroyHttpBodyStream(stream_); 66 stream_ = nullptr; 67 } 68 }; 69 static void HttpBodyStreamInitCallback(const ArkWeb_HttpBodyStream* httpBodyStream, ArkWeb_NetError result); 70 int32_t initialize(); 71 int32_t Read(int32_t bufLen); 72 uint64_t GetPostion(); 73 uint64_t GetSize(); 74 bool IsChunked(); 75 bool IsEof(); 76 bool IsInMemory(); 77 private: 78 ArkWeb_HttpBodyStream* stream_ = nullptr; 79 }; 80 81 //WebSchemeHandlerRequest 82 using WebHeaderList = std::vector<std::pair<std::string, std::string>>; 83 class WebSchemeHandlerRequestImpl : public OHOS::FFI::FFIData { 84 DECL_TYPE(WebSchemeHandlerRequestImpl, OHOS::FFI::FFIData) 85 public: 86 explicit WebSchemeHandlerRequestImpl() = default; WebSchemeHandlerRequestImpl(const ArkWeb_ResourceRequest * request)87 WebSchemeHandlerRequestImpl(const ArkWeb_ResourceRequest* request) 88 { 89 OH_ArkWebResourceRequest_GetUrl(request, &url_); 90 OH_ArkWebResourceRequest_GetMethod(request, &method_); 91 OH_ArkWebResourceRequest_GetReferrer(request, &referrer_); 92 isRedirect_ = OH_ArkWebResourceRequest_IsRedirect(request); 93 isMainFrame_ = OH_ArkWebResourceRequest_IsMainFrame(request); 94 hasGesture_ = OH_ArkWebResourceRequest_HasGesture(request); 95 OH_ArkWebResourceRequest_GetFrameUrl(request, &frameUrl_); 96 OH_ArkWebResourceRequest_GetHttpBodyStream(request, &stream_); 97 requestResourceType_ = OH_ArkWebResourceRequest_GetResourceType(request); 98 99 ArkWeb_RequestHeaderList* arkWebHeaderlist = nullptr; 100 OH_ArkWebResourceRequest_GetRequestHeaders(request, &arkWebHeaderlist); 101 if (!arkWebHeaderlist) { 102 WVLOG_E("OH_ArkWebRequestHeaderList_Create failed"); 103 return; 104 } 105 int32_t size = OH_ArkWebRequestHeaderList_GetSize(arkWebHeaderlist); 106 if (size <= 0) { 107 WVLOG_E("OH_ArkWebRequestHeaderList_GetSize:%{public}d", size); 108 return; 109 } 110 for (int32_t index = 0; index < size; index++) { 111 char* key; 112 char* value; 113 OH_ArkWebRequestHeaderList_GetHeader(arkWebHeaderlist, index, &key, &value); 114 if (!key || !value) { 115 continue; 116 } 117 std::string strKey(key); 118 std::string strValue(value); 119 headerList_.emplace_back(std::make_pair(strKey, strValue)); 120 OH_ArkWeb_ReleaseString(key); 121 OH_ArkWeb_ReleaseString(value); 122 } 123 OH_ArkWebRequestHeaderList_Destroy(arkWebHeaderlist); 124 }; 125 std::string GetRequestUrl(); 126 std::string GetMethod(); 127 std::string GetReferrer(); 128 std::string GetFrameUrl(); 129 int32_t GetRequestResourceType(); 130 ArkWeb_HttpBodyStream* GetHttpBodyStream(); 131 const WebHeaderList& GetHeader(); 132 bool HasGesture(); 133 bool IsMainFrame(); 134 bool IsRedirect(); 135 private: 136 char* url_ = nullptr; 137 char* method_ = nullptr; 138 char* referrer_ = nullptr; 139 char* frameUrl_ = nullptr; 140 int32_t requestResourceType_ = -1; 141 bool isRedirect_ = false; 142 bool isMainFrame_ = false; 143 bool hasGesture_ = false; 144 WebHeaderList headerList_; 145 ArkWeb_HttpBodyStream* stream_ = nullptr; 146 }; 147 148 // WebSchemeHandler 149 class WebSchemeHandlerImpl : public OHOS::FFI::FFIData { 150 DECL_TYPE(WebSchemeHandlerImpl, OHOS::FFI::FFIData) 151 public: 152 explicit WebSchemeHandlerImpl(); 153 ~WebSchemeHandlerImpl(); 154 155 static const ArkWeb_SchemeHandler* GetArkWebSchemeHandler( 156 WebSchemeHandlerImpl* handler); 157 static WebSchemeHandlerImpl* GetWebSchemeHandler( 158 const ArkWeb_SchemeHandler* handler); 159 160 void RequestStart(ArkWeb_ResourceRequest* request, 161 const ArkWeb_ResourceHandler* ArkWeb_ResourceHandler, 162 bool* intercept); 163 void RequestStop(const ArkWeb_ResourceRequest* resourceRequest); 164 165 void PutRequestStart(std::function<bool(int64_t, int64_t)> callback); 166 void PutRequestStop(std::function<void(int64_t)> callback); 167 168 static std::unordered_map<WebSchemeHandlerImpl*, const ArkWeb_SchemeHandler*> 169 webSchemeHandlerMap_; 170 static std::unordered_map<const ArkWeb_SchemeHandler*, WebSchemeHandlerImpl*> 171 arkWebSchemeHandlerMap_; 172 private: 173 typedef struct RequestStopParam { 174 std::function<void(int64_t)> callbackRef_; 175 WebSchemeHandlerRequestImpl* request_; 176 const ArkWeb_ResourceRequest* arkWebRequest_; 177 } RequestStopParam; 178 179 static void RequestStopAfterWorkCb(RequestStopParam* param); 180 181 ArkWeb_OnRequestStart onRequestStart_ = nullptr; 182 ArkWeb_OnRequestStop onRequestStop_ = nullptr; 183 184 std::function<bool(int64_t, int64_t)> request_start_callback_ = nullptr; 185 std::function<void(int64_t)> request_stop_callback_ = nullptr; 186 }; 187 188 // WebResourceHandler 189 class WebResourceHandlerImpl : public OHOS::FFI::FFIData { 190 DECL_TYPE(WebResourceHandlerImpl, OHOS::FFI::FFIData) 191 public: 192 explicit WebResourceHandlerImpl() = default; WebResourceHandlerImpl(const ArkWeb_ResourceHandler * handler)193 WebResourceHandlerImpl(const ArkWeb_ResourceHandler* handler) 194 { 195 handler_ = const_cast<ArkWeb_ResourceHandler*>(handler); 196 }; 197 ~WebResourceHandlerImpl() = default; 198 int32_t DidReceiveResponse(const ArkWeb_Response* response); 199 int32_t DidReceiveResponseBody(const uint8_t* buffer, int64_t buflen); 200 int32_t DidFinish(); 201 int32_t DidFailWithError(ArkWeb_NetError errorCode); 202 void DestroyArkWebResourceHandler(); SetFinishFlag()203 void SetFinishFlag() 204 { 205 isFinished_ = true; 206 } 207 private: 208 bool isFinished_ = false; 209 ArkWeb_ResourceHandler* handler_ = nullptr; 210 }; 211 } 212 #endif // WEB_SCHEME_HANDLER_REQUEST_H