1e41f4b71Sopenharmony_ci# Intercepting Network Requests Initiated by the Web Component 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciThe [Network Interception APIs](../reference/apis-arkweb/arkweb__scheme__handler_8h.md) are used to intercept requests sent by **Web** components and provide custom response headers and bodies for intercepted requests. 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci## Setting Network Interceptors for Web Components 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ciSet **ArkWeb_SchemeHandler** for a specified **Web** component or ServiceWorker. When the **Web** kernel sends a scheme request, the callback of **ArkWeb_SchemeHandler** is triggered. You need to set the network interceptor when the **Web** component is initialized. 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ciWhen a request starts, **ArkWeb_OnRequestStart** is called. When a request ends, **ArkWeb_OnRequestStop** is called. 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ciTo intercept the first request sent by a **Web** component, you can use [initializeWebEngine](../reference/apis-arkweb/js-apis-webview.md#initializewebengine) to initialize the **Web** component in advance and set an interceptor. 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci ```c++ 14e41f4b71Sopenharmony_ci // Create an ArkWeb_SchemeHandler object. 15e41f4b71Sopenharmony_ci ArkWeb_SchemeHandler *schemeHandler; 16e41f4b71Sopenharmony_ci OH_ArkWeb_CreateSchemeHandler(&schemeHandler); 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci // Set the ArkWeb_OnRequestStart and ArkWeb_OnRequestStop callbacks for ArkWeb_SchemeHandler. 19e41f4b71Sopenharmony_ci OH_ArkWebSchemeHandler_SetOnRequestStart(schemeHandler, OnURLRequestStart); 20e41f4b71Sopenharmony_ci OH_ArkWebSchemeHandler_SetOnRequestStop(schemeHandler, OnURLRequestStop); 21e41f4b71Sopenharmony_ci 22e41f4b71Sopenharmony_ci // Intercept the request whose scheme is https sent by the Web component whose webTag is scheme-handler. 23e41f4b71Sopenharmony_ci OH_ArkWeb_SetSchemeHandler("https", "scheme-handler", schemeHandler); 24e41f4b71Sopenharmony_ci OH_ArkWebServiceWorker_SetSchemeHandler("https", schemeHandler); 25e41f4b71Sopenharmony_ci ``` 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ciYou can also intercept requests of built-in schemes of non-web components. 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ci ```c++ 30e41f4b71Sopenharmony_ci // Create an ArkWeb_SchemeHandler object. 31e41f4b71Sopenharmony_ci ArkWeb_SchemeHandler *schemeHandler; 32e41f4b71Sopenharmony_ci OH_ArkWeb_CreateSchemeHandler(&schemeHandler); 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ci // Set the ArkWeb_OnRequestStart and ArkWeb_OnRequestStop callbacks for ArkWeb_SchemeHandler. 35e41f4b71Sopenharmony_ci OH_ArkWebSchemeHandler_SetOnRequestStart(schemeHandler, OnURLRequestStart); 36e41f4b71Sopenharmony_ci OH_ArkWebSchemeHandler_SetOnRequestStop(schemeHandler, OnURLRequestStop); 37e41f4b71Sopenharmony_ci 38e41f4b71Sopenharmony_ci // Intercept the request whose scheme is custom sent by the Web component whose webTag is scheme-handler. 39e41f4b71Sopenharmony_ci OH_ArkWeb_SetSchemeHandler("custom", "scheme-handler", schemeHandler); 40e41f4b71Sopenharmony_ci OH_ArkWebServiceWorker_SetSchemeHandler("custom", schemeHandler); 41e41f4b71Sopenharmony_ci ``` 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ci## Rules for Setting a Custom Scheme 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ciTo intercept the request of a custom scheme, you need to register the custom scheme with the web kernel before the **Web** component is initialized. Otherwise, the registration fails. 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci ```c++ 48e41f4b71Sopenharmony_ci // Register the custom scheme with the Web component and specify that this scheme should follow the standard scheme rules, allowing cross-origin requests from this scheme. 49e41f4b71Sopenharmony_ci OH_ArkWeb_RegisterCustomSchemes("custom", ARKWEB_SCHEME_OPTION_STANDARD | ARKWEB_SCHEME_OPTION_CORS_ENABLED); 50e41f4b71Sopenharmony_ci // Register the custom-local scheme with the Web component and specify that this scheme should follow the same rules as the file scheme. 51e41f4b71Sopenharmony_ci OH_ArkWeb_RegisterCustomSchemes("custom-local", ARKWEB_SCHEME_OPTION_LOCAL); 52e41f4b71Sopenharmony_ci // Register custom-csp-bypassing with the Web component and specify that this scheme should follow the standard scheme rules, allowing it to bypass CSP checks. 53e41f4b71Sopenharmony_ci OH_ArkWeb_RegisterCustomSchemes("custom-csp-bypassing", ARKWEB_SCHEME_OPTION_CSP_BYPASSING | ARKWEB_SCHEME_OPTION_STANDARD); 54e41f4b71Sopenharmony_ci // Register custom-isolated with the Web component and specify that requests for this scheme must be initiated from web pages loaded with the same scheme. 55e41f4b71Sopenharmony_ci OH_ArkWeb_RegisterCustomSchemes("custom-isolated", ARKWEB_SCHEME_OPTION_DISPLAY_ISOLATED); 56e41f4b71Sopenharmony_ci ``` 57e41f4b71Sopenharmony_ci 58e41f4b71Sopenharmony_ciThe scheme needs to be registered before the **Web** component is initialized, and the network interceptor needs to be set after the **Web** component is initialized. Therefore, you are advised to call the C++ API in **onCreate()** of **EntryAbility** to register the scheme. 59e41f4b71Sopenharmony_ciAfter the scheme is registered, use [initializeWebEngine](../reference/apis-arkweb/js-apis-webview.md#initializewebengine) to initialize the **Web** component, and then set the network interceptor. 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci ```ts 62e41f4b71Sopenharmony_ci export default class EntryAbility extends UIAbility { 63e41f4b71Sopenharmony_ci onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 64e41f4b71Sopenharmony_ci // Register the scheme configuration. 65e41f4b71Sopenharmony_ci testNapi.registerCustomSchemes(); 66e41f4b71Sopenharmony_ci // Initialize the kernel of the Web component. This operation initializes the Browser process and creates BrowserContext. 67e41f4b71Sopenharmony_ci webview.WebviewController.initializeWebEngine(); 68e41f4b71Sopenharmony_ci // Create and set ArkWeb_SchemeHandler. 69e41f4b71Sopenharmony_ci testNapi.setSchemeHandler(); 70e41f4b71Sopenharmony_ci } 71e41f4b71Sopenharmony_ci ... 72e41f4b71Sopenharmony_ci }; 73e41f4b71Sopenharmony_ci ``` 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ci## Obtaining Information of an Intercepted Request 76e41f4b71Sopenharmony_ci 77e41f4b71Sopenharmony_ciUse **OH_ArkWebResourceRequest_*** to obtain information of intercepted requests. You can obtain information such as url, method, referrer, headers, and resourceType. 78e41f4b71Sopenharmony_ci 79e41f4b71Sopenharmony_ci ```c++ 80e41f4b71Sopenharmony_ci char* url; 81e41f4b71Sopenharmony_ci OH_ArkWebResourceRequest_GetUrl(resourceRequest_, &url); 82e41f4b71Sopenharmony_ci OH_ArkWeb_ReleaseString(url); 83e41f4b71Sopenharmony_ci 84e41f4b71Sopenharmony_ci char* method; 85e41f4b71Sopenharmony_ci OH_ArkWebResourceRequest_GetMethod(resourceRequest_, &method); 86e41f4b71Sopenharmony_ci OH_ArkWeb_ReleaseString(method); 87e41f4b71Sopenharmony_ci 88e41f4b71Sopenharmony_ci int32_t resourceType = OH_ArkWebResourceRequest_GetResourceType(resourceRequest_); 89e41f4b71Sopenharmony_ci 90e41f4b71Sopenharmony_ci char* frameUrl; 91e41f4b71Sopenharmony_ci OH_ArkWebResourceRequest_GetFrameUrl(resourceRequest_, &frameUrl); 92e41f4b71Sopenharmony_ci OH_ArkWeb_ReleaseString(frameUrl); 93e41f4b71Sopenharmony_ci ... 94e41f4b71Sopenharmony_ci ``` 95e41f4b71Sopenharmony_ci 96e41f4b71Sopenharmony_ciUploaded data of **PUT** and **POST** requests can be obtained. Data types such as BYTES, FILE, BLOB, and CHUNKED are supported. 97e41f4b71Sopenharmony_ci 98e41f4b71Sopenharmony_ci ```c++ 99e41f4b71Sopenharmony_ci // Obtain the uploaded data of the intercepted request. 100e41f4b71Sopenharmony_ci OH_ArkWebResourceRequest_GetHttpBodyStream(resourceRequest(), &stream_); 101e41f4b71Sopenharmony_ci // Set the read callback used to read the uploaded data. 102e41f4b71Sopenharmony_ci OH_ArkWebHttpBodyStream_SetReadCallback(stream_, ReadCallback); 103e41f4b71Sopenharmony_ci // Initialize ArkWeb_HttpBodyStream. Other OH_ArkWebHttpBodyStream* functions need to be called during initialization. 104e41f4b71Sopenharmony_ci OH_ArkWebHttpBodyStream_Init(stream_, InitCallback); 105e41f4b71Sopenharmony_ci ``` 106e41f4b71Sopenharmony_ci 107e41f4b71Sopenharmony_ci## Providing Custom Response Bodies for Intercepted Requests 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ciThe network interception of **Web** components provide custom response bodies for intercepted requests in stream mode in the worker thread. You can also end the intercepted request with a specific [network error code](../reference/apis-arkweb/arkweb__net__error__list_8h.md). 110e41f4b71Sopenharmony_ci 111e41f4b71Sopenharmony_ci ```c++ 112e41f4b71Sopenharmony_ci // Create a response header for the intercepted request. 113e41f4b71Sopenharmony_ci ArkWeb_Response *response; 114e41f4b71Sopenharmony_ci OH_ArkWeb_CreateResponse(&response); 115e41f4b71Sopenharmony_ci 116e41f4b71Sopenharmony_ci // Set the HTTP status code to 200. 117e41f4b71Sopenharmony_ci OH_ArkWebResponse_SetStatus(response, 200); 118e41f4b71Sopenharmony_ci // Set the encoding format of the response body. 119e41f4b71Sopenharmony_ci OH_ArkWebResponse_SetCharset(response, "UTF-8"); 120e41f4b71Sopenharmony_ci // Set the size of the response body. 121e41f4b71Sopenharmony_ci OH_ArkWebResponse_SetHeaderByName(response, "content-length", "1024", false); 122e41f4b71Sopenharmony_ci // Pass the response header created for the intercepted request to the Web component. 123e41f4b71Sopenharmony_ci OH_ArkWebResourceHandler_DidReceiveResponse(resourceHandler, response); 124e41f4b71Sopenharmony_ci 125e41f4b71Sopenharmony_ci // This function can be called for multiple times, and data can be transferred to the Web component in multiple copies. 126e41f4b71Sopenharmony_ci OH_ArkWebResourceHandler_DidReceiveData(resourceHandler, buffer, bufLen); 127e41f4b71Sopenharmony_ci 128e41f4b71Sopenharmony_ci // The response body for reading ends. If you want the request to fail, you can also call OH_ArkWebResourceHandler_DidFailWithError(resourceHandler_, errorCode). 129e41f4b71Sopenharmony_ci // Pass an error code to the Web component and end the request. 130e41f4b71Sopenharmony_ci OH_ArkWebResourceHandler_DidFinish(resourceHandler); 131e41f4b71Sopenharmony_ci ``` 132e41f4b71Sopenharmony_ci 133e41f4b71Sopenharmony_ci## Sample Code 134e41f4b71Sopenharmony_ci 135e41f4b71Sopenharmony_ciIn DevEco Studio, create a default **Native C++** project. You need to prepare an MP4 file named **test.mp4** and place the **test.mp4** file in **main/resources/rawfile**. 136e41f4b71Sopenharmony_ci 137e41f4b71Sopenharmony_cimain/ets/pages/index.ets 138e41f4b71Sopenharmony_ci```ts 139e41f4b71Sopenharmony_ciimport testNapi from 'libentry.so'; 140e41f4b71Sopenharmony_ciimport { webview } from '@kit.ArkWeb'; 141e41f4b71Sopenharmony_ciimport { resourceManager } from '@kit.LocalizationKit'; 142e41f4b71Sopenharmony_ci 143e41f4b71Sopenharmony_ci@Entry 144e41f4b71Sopenharmony_ci@Component 145e41f4b71Sopenharmony_cistruct Index { 146e41f4b71Sopenharmony_ci mycontroller: webview.WebviewController = new webview.WebviewController("scheme-handler"); 147e41f4b71Sopenharmony_ci 148e41f4b71Sopenharmony_ci build() { 149e41f4b71Sopenharmony_ci Row() { 150e41f4b71Sopenharmony_ci Column() { 151e41f4b71Sopenharmony_ci Button("goback").onClick( event => { 152e41f4b71Sopenharmony_ci this.mycontroller.backward(); 153e41f4b71Sopenharmony_ci }) 154e41f4b71Sopenharmony_ci 155e41f4b71Sopenharmony_ci Web({ src: $rawfile("test.html"), controller: this.mycontroller}) 156e41f4b71Sopenharmony_ci .javaScriptAccess(true) 157e41f4b71Sopenharmony_ci .width('100%') 158e41f4b71Sopenharmony_ci .height('100%') 159e41f4b71Sopenharmony_ci .databaseAccess(true) 160e41f4b71Sopenharmony_ci .fileAccess(false) 161e41f4b71Sopenharmony_ci .domStorageAccess(true) 162e41f4b71Sopenharmony_ci .cacheMode(CacheMode.Default) 163e41f4b71Sopenharmony_ci .onPageBegin( event => { 164e41f4b71Sopenharmony_ci testNapi.initResourceManager(getContext().resourceManager); 165e41f4b71Sopenharmony_ci }) 166e41f4b71Sopenharmony_ci } 167e41f4b71Sopenharmony_ci .width('100%') 168e41f4b71Sopenharmony_ci } 169e41f4b71Sopenharmony_ci .height('100%') 170e41f4b71Sopenharmony_ci } 171e41f4b71Sopenharmony_ci} 172e41f4b71Sopenharmony_ci``` 173e41f4b71Sopenharmony_ci 174e41f4b71Sopenharmony_cimain/ets/entryability/EntryAbility.ets 175e41f4b71Sopenharmony_ci```ts 176e41f4b71Sopenharmony_ciimport { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 177e41f4b71Sopenharmony_ciimport { hilog } from '@kit.PerformanceAnalysisKit'; 178e41f4b71Sopenharmony_ciimport { window } from '@kit.ArkUI'; 179e41f4b71Sopenharmony_ciimport testNapi from 'libentry.so'; 180e41f4b71Sopenharmony_ciimport { webview } from '@kit.ArkWeb'; 181e41f4b71Sopenharmony_ci 182e41f4b71Sopenharmony_ciexport default class EntryAbility extends UIAbility { 183e41f4b71Sopenharmony_ci onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 184e41f4b71Sopenharmony_ci // Register the configuration of the third-party protocol. 185e41f4b71Sopenharmony_ci testNapi.registerCustomSchemes(); 186e41f4b71Sopenharmony_ci // Initialize the kernel of the Web component, which will initialize the Browser process and create a BrowserContext. 187e41f4b71Sopenharmony_ci webview.WebviewController.initializeWebEngine(); 188e41f4b71Sopenharmony_ci // Set SchemeHandler. 189e41f4b71Sopenharmony_ci testNapi.setSchemeHandler(); 190e41f4b71Sopenharmony_ci } 191e41f4b71Sopenharmony_ci 192e41f4b71Sopenharmony_ci onDestroy(): void { 193e41f4b71Sopenharmony_ci 194e41f4b71Sopenharmony_ci } 195e41f4b71Sopenharmony_ci 196e41f4b71Sopenharmony_ci onWindowStageCreate(windowStage: window.WindowStage): void { 197e41f4b71Sopenharmony_ci windowStage.loadContent('pages/Index', (err, data) => { 198e41f4b71Sopenharmony_ci if (err.code) { 199e41f4b71Sopenharmony_ci return; 200e41f4b71Sopenharmony_ci } 201e41f4b71Sopenharmony_ci }); 202e41f4b71Sopenharmony_ci } 203e41f4b71Sopenharmony_ci 204e41f4b71Sopenharmony_ci onWindowStageDestroy(): void { 205e41f4b71Sopenharmony_ci 206e41f4b71Sopenharmony_ci } 207e41f4b71Sopenharmony_ci 208e41f4b71Sopenharmony_ci onForeground(): void { 209e41f4b71Sopenharmony_ci 210e41f4b71Sopenharmony_ci } 211e41f4b71Sopenharmony_ci 212e41f4b71Sopenharmony_ci onBackground(): void { 213e41f4b71Sopenharmony_ci 214e41f4b71Sopenharmony_ci } 215e41f4b71Sopenharmony_ci}; 216e41f4b71Sopenharmony_ci``` 217e41f4b71Sopenharmony_ci 218e41f4b71Sopenharmony_cimain/cpp/hello.cpp 219e41f4b71Sopenharmony_ci```c++ 220e41f4b71Sopenharmony_ci#include "hilog/log.h" 221e41f4b71Sopenharmony_ci#include "napi/native_api.h" 222e41f4b71Sopenharmony_ci#include "rawfile_request.h" 223e41f4b71Sopenharmony_ci#include "rawfile/raw_file_manager.h" 224e41f4b71Sopenharmony_ci#include "web/arkweb_scheme_handler.h" 225e41f4b71Sopenharmony_ci#include "web/arkweb_net_error_list.h" 226e41f4b71Sopenharmony_ci 227e41f4b71Sopenharmony_ci#undef LOG_TAG 228e41f4b71Sopenharmony_ci#define LOG_TAG "ss-handler" 229e41f4b71Sopenharmony_ci 230e41f4b71Sopenharmony_ciArkWeb_SchemeHandler *g_schemeHandler; 231e41f4b71Sopenharmony_ciArkWeb_SchemeHandler *g_schemeHandlerForSW; 232e41f4b71Sopenharmony_ciNativeResourceManager *g_resourceManager; 233e41f4b71Sopenharmony_ci 234e41f4b71Sopenharmony_ci// Register the configuration of the third-party protocol. This API must be called before the Web kernel is initialized. Otherwise, the registration fails. 235e41f4b71Sopenharmony_cistatic napi_value RegisterCustomSchemes(napi_env env, napi_callback_info info) 236e41f4b71Sopenharmony_ci{ 237e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "register custom schemes"); 238e41f4b71Sopenharmony_ci OH_ArkWeb_RegisterCustomSchemes("custom", ARKWEB_SCHEME_OPTION_STANDARD | ARKWEB_SCHEME_OPTION_CORS_ENABLED); 239e41f4b71Sopenharmony_ci OH_ArkWeb_RegisterCustomSchemes("custom-local", ARKWEB_SCHEME_OPTION_LOCAL); 240e41f4b71Sopenharmony_ci OH_ArkWeb_RegisterCustomSchemes("custom-csp-bypassing", ARKWEB_SCHEME_OPTION_CSP_BYPASSING | ARKWEB_SCHEME_OPTION_STANDARD); 241e41f4b71Sopenharmony_ci OH_ArkWeb_RegisterCustomSchemes("custom-isolated", ARKWEB_SCHEME_OPTION_DISPLAY_ISOLATED); 242e41f4b71Sopenharmony_ci return nullptr; 243e41f4b71Sopenharmony_ci} 244e41f4b71Sopenharmony_ci 245e41f4b71Sopenharmony_ci// Callback used when a request is started. Create a RawfileRequest in this function to intercept Web kernel requests. 246e41f4b71Sopenharmony_civoid OnURLRequestStart(const ArkWeb_SchemeHandler *schemeHandler, 247e41f4b71Sopenharmony_ci ArkWeb_ResourceRequest *resourceRequest, 248e41f4b71Sopenharmony_ci const ArkWeb_ResourceHandler *resourceHandler, 249e41f4b71Sopenharmony_ci bool *intercept) 250e41f4b71Sopenharmony_ci{ 251e41f4b71Sopenharmony_ci *intercept = true; 252e41f4b71Sopenharmony_ci RawfileRequest* request = new RawfileRequest(resourceRequest, resourceHandler, g_resourceManager); 253e41f4b71Sopenharmony_ci OH_ArkWebResourceRequest_SetUserData(resourceRequest, request); 254e41f4b71Sopenharmony_ci request->Start(); 255e41f4b71Sopenharmony_ci} 256e41f4b71Sopenharmony_ci 257e41f4b71Sopenharmony_ci// Callback used when the request is stopped. In this function, mark RawfileRequest as ended, and ResourceHandler should not be used internally. 258e41f4b71Sopenharmony_civoid OnURLRequestStop(const ArkWeb_SchemeHandler *schemeHandler, 259e41f4b71Sopenharmony_ci const ArkWeb_ResourceRequest *request) 260e41f4b71Sopenharmony_ci{ 261e41f4b71Sopenharmony_ci if (!request) { 262e41f4b71Sopenharmony_ci OH_LOG_ERROR(LOG_APP, "on request stop request is nullptr."); 263e41f4b71Sopenharmony_ci return; 264e41f4b71Sopenharmony_ci } 265e41f4b71Sopenharmony_ci 266e41f4b71Sopenharmony_ci RawfileRequest *rawfileRequest = (RawfileRequest *)OH_ArkWebResourceRequest_GetUserData(request); 267e41f4b71Sopenharmony_ci if (rawfileRequest) { 268e41f4b71Sopenharmony_ci rawfileRequest->Stop(); 269e41f4b71Sopenharmony_ci } 270e41f4b71Sopenharmony_ci} 271e41f4b71Sopenharmony_ci 272e41f4b71Sopenharmony_civoid OnURLRequestStartForSW(const ArkWeb_SchemeHandler *schemeHandler, 273e41f4b71Sopenharmony_ci ArkWeb_ResourceRequest *resourceRequest, 274e41f4b71Sopenharmony_ci const ArkWeb_ResourceHandler *resourceHandler, 275e41f4b71Sopenharmony_ci bool *intercept) 276e41f4b71Sopenharmony_ci{ 277e41f4b71Sopenharmony_ci *intercept = true; 278e41f4b71Sopenharmony_ci RawfileRequest* request = new RawfileRequest(resourceRequest, resourceHandler, g_resourceManager); 279e41f4b71Sopenharmony_ci OH_ArkWebResourceRequest_SetUserData(resourceRequest, request); 280e41f4b71Sopenharmony_ci request->Start(); 281e41f4b71Sopenharmony_ci} 282e41f4b71Sopenharmony_ci 283e41f4b71Sopenharmony_civoid OnURLRequestStopForSW(const ArkWeb_SchemeHandler *schemeHandler, 284e41f4b71Sopenharmony_ci const ArkWeb_ResourceRequest *request) 285e41f4b71Sopenharmony_ci{ 286e41f4b71Sopenharmony_ci if (!request) { 287e41f4b71Sopenharmony_ci OH_LOG_ERROR(LOG_APP, "on request stop request is nullptr."); 288e41f4b71Sopenharmony_ci return; 289e41f4b71Sopenharmony_ci } 290e41f4b71Sopenharmony_ci 291e41f4b71Sopenharmony_ci RawfileRequest *rawfileRequest = (RawfileRequest *)OH_ArkWebResourceRequest_GetUserData(request); 292e41f4b71Sopenharmony_ci if (rawfileRequest) { 293e41f4b71Sopenharmony_ci rawfileRequest->Stop(); 294e41f4b71Sopenharmony_ci } 295e41f4b71Sopenharmony_ci} 296e41f4b71Sopenharmony_ci 297e41f4b71Sopenharmony_ci// Set SchemeHandler. 298e41f4b71Sopenharmony_cistatic napi_value SetSchemeHandler(napi_env env, napi_callback_info info) 299e41f4b71Sopenharmony_ci{ 300e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "set scheme handler"); 301e41f4b71Sopenharmony_ci OH_ArkWeb_CreateSchemeHandler(&g_schemeHandler); 302e41f4b71Sopenharmony_ci OH_ArkWeb_CreateSchemeHandler(&g_schemeHandlerForSW); 303e41f4b71Sopenharmony_ci 304e41f4b71Sopenharmony_ci OH_ArkWebSchemeHandler_SetOnRequestStart(g_schemeHandler, OnURLRequestStart); 305e41f4b71Sopenharmony_ci OH_ArkWebSchemeHandler_SetOnRequestStop(g_schemeHandler, OnURLRequestStop); 306e41f4b71Sopenharmony_ci 307e41f4b71Sopenharmony_ci OH_ArkWebSchemeHandler_SetOnRequestStart(g_schemeHandlerForSW, OnURLRequestStart); 308e41f4b71Sopenharmony_ci OH_ArkWebSchemeHandler_SetOnRequestStop(g_schemeHandlerForSW, OnURLRequestStop); 309e41f4b71Sopenharmony_ci 310e41f4b71Sopenharmony_ci OH_ArkWeb_SetSchemeHandler("custom", "scheme-handler", g_schemeHandler); 311e41f4b71Sopenharmony_ci OH_ArkWeb_SetSchemeHandler("custom-csp-bypassing", "scheme-handler", g_schemeHandler); 312e41f4b71Sopenharmony_ci OH_ArkWeb_SetSchemeHandler("custom-isolated", "scheme-handler", g_schemeHandler); 313e41f4b71Sopenharmony_ci OH_ArkWeb_SetSchemeHandler("custom-local", "scheme-handler", g_schemeHandler); 314e41f4b71Sopenharmony_ci OH_ArkWeb_SetSchemeHandler("https", "scheme-handler", g_schemeHandler); 315e41f4b71Sopenharmony_ci OH_ArkWeb_SetSchemeHandler("http", "scheme-handler", g_schemeHandler); 316e41f4b71Sopenharmony_ci 317e41f4b71Sopenharmony_ci OH_ArkWebServiceWorker_SetSchemeHandler("https", g_schemeHandlerForSW); 318e41f4b71Sopenharmony_ci return nullptr; 319e41f4b71Sopenharmony_ci} 320e41f4b71Sopenharmony_ci 321e41f4b71Sopenharmony_cistatic napi_value InitResourceManager(napi_env env, napi_callback_info info) 322e41f4b71Sopenharmony_ci{ 323e41f4b71Sopenharmony_ci size_t argc = 2; 324e41f4b71Sopenharmony_ci napi_value argv[2] = {nullptr}; 325e41f4b71Sopenharmony_ci napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 326e41f4b71Sopenharmony_ci g_resourceManager = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 327e41f4b71Sopenharmony_ci return nullptr; 328e41f4b71Sopenharmony_ci} 329e41f4b71Sopenharmony_ci 330e41f4b71Sopenharmony_ciEXTERN_C_START 331e41f4b71Sopenharmony_cistatic napi_value Init(napi_env env, napi_value exports) 332e41f4b71Sopenharmony_ci{ 333e41f4b71Sopenharmony_ci napi_property_descriptor desc[] = { 334e41f4b71Sopenharmony_ci {"setSchemeHandler", nullptr, SetSchemeHandler, nullptr, nullptr, nullptr, napi_default, nullptr}, 335e41f4b71Sopenharmony_ci {"initResourceManager", nullptr, InitResourceManager, nullptr, nullptr, nullptr, napi_default, nullptr}, 336e41f4b71Sopenharmony_ci {"registerCustomSchemes", nullptr, RegisterCustomSchemes, nullptr, nullptr, nullptr, napi_default, nullptr} 337e41f4b71Sopenharmony_ci }; 338e41f4b71Sopenharmony_ci napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 339e41f4b71Sopenharmony_ci return exports; 340e41f4b71Sopenharmony_ci} 341e41f4b71Sopenharmony_ciEXTERN_C_END 342e41f4b71Sopenharmony_ci 343e41f4b71Sopenharmony_cistatic napi_module demoModule = { 344e41f4b71Sopenharmony_ci .nm_version = 1, 345e41f4b71Sopenharmony_ci .nm_flags = 0, 346e41f4b71Sopenharmony_ci .nm_filename = nullptr, 347e41f4b71Sopenharmony_ci .nm_register_func = Init, 348e41f4b71Sopenharmony_ci .nm_modname = "entry", 349e41f4b71Sopenharmony_ci .nm_priv = ((void*)0), 350e41f4b71Sopenharmony_ci .reserved = { 0 }, 351e41f4b71Sopenharmony_ci}; 352e41f4b71Sopenharmony_ci 353e41f4b71Sopenharmony_ciextern "C" __attribute__((constructor)) void RegisterEntryModule(void) 354e41f4b71Sopenharmony_ci{ 355e41f4b71Sopenharmony_ci napi_module_register(&demoModule); 356e41f4b71Sopenharmony_ci} 357e41f4b71Sopenharmony_ci``` 358e41f4b71Sopenharmony_ci 359e41f4b71Sopenharmony_ci 360e41f4b71Sopenharmony_cimain/cpp/CMakeLists.txt 361e41f4b71Sopenharmony_ci```text 362e41f4b71Sopenharmony_ci# the minimum version of CMake. 363e41f4b71Sopenharmony_cicmake_minimum_required(VERSION 3.4.1) 364e41f4b71Sopenharmony_ciproject(schemehandler) 365e41f4b71Sopenharmony_ci 366e41f4b71Sopenharmony_ciset(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) 367e41f4b71Sopenharmony_ci 368e41f4b71Sopenharmony_ciif(DEFINED PACKAGE_INFO_FILE) 369e41f4b71Sopenharmony_ci include(${PACKAGE_INFO_FILE}) 370e41f4b71Sopenharmony_ciendif() 371e41f4b71Sopenharmony_ci 372e41f4b71Sopenharmony_ciinclude_directories(${NATIVERENDER_ROOT_PATH} 373e41f4b71Sopenharmony_ci ${NATIVERENDER_ROOT_PATH}/include) 374e41f4b71Sopenharmony_ci 375e41f4b71Sopenharmony_ciadd_library(entry SHARED rawfile_request.cpp hello.cpp) 376e41f4b71Sopenharmony_citarget_link_libraries(entry PUBLIC librawfile.z.so libace_napi.z.so libohweb.so libhilog_ndk.z.so) 377e41f4b71Sopenharmony_ci``` 378e41f4b71Sopenharmony_ci 379e41f4b71Sopenharmony_cimain/cpp/types/index.d.ts 380e41f4b71Sopenharmony_ci```ts 381e41f4b71Sopenharmony_ciexport const registerCustomSchemes: () => void; 382e41f4b71Sopenharmony_ciexport const setSchemeHandler: () => void; 383e41f4b71Sopenharmony_ciexport const initResourceManager: (resmgr: resourceManager.ResourceManager) => void; 384e41f4b71Sopenharmony_ci``` 385e41f4b71Sopenharmony_ci 386e41f4b71Sopenharmony_cimain/cpp/rawfile_request.h 387e41f4b71Sopenharmony_ci```c++ 388e41f4b71Sopenharmony_ci#ifndef RAWFILE_REQUEST_H 389e41f4b71Sopenharmony_ci#define RAWFILE_REQUEST_H 390e41f4b71Sopenharmony_ci 391e41f4b71Sopenharmony_ci#include <mutex> 392e41f4b71Sopenharmony_ci#include <string> 393e41f4b71Sopenharmony_ci 394e41f4b71Sopenharmony_ci#include <rawfile/raw_file_manager.h> 395e41f4b71Sopenharmony_ci#include "web/arkweb_scheme_handler.h" 396e41f4b71Sopenharmony_ci#include "web/arkweb_net_error_list.h" 397e41f4b71Sopenharmony_ci 398e41f4b71Sopenharmony_ciclass RawfileRequest { 399e41f4b71Sopenharmony_cipublic: 400e41f4b71Sopenharmony_ci RawfileRequest(const ArkWeb_ResourceRequest *resourceRequest, 401e41f4b71Sopenharmony_ci const ArkWeb_ResourceHandler *resourceHandler, 402e41f4b71Sopenharmony_ci const NativeResourceManager* resourceManager); 403e41f4b71Sopenharmony_ci ~RawfileRequest(); 404e41f4b71Sopenharmony_ci 405e41f4b71Sopenharmony_ci void Start(); 406e41f4b71Sopenharmony_ci void Stop(); 407e41f4b71Sopenharmony_ci void ReadRawfileDataOnWorkerThread(); 408e41f4b71Sopenharmony_ci 409e41f4b71Sopenharmony_ci const ArkWeb_ResourceHandler *resourceHandler() { return resourceHandler_; } 410e41f4b71Sopenharmony_ci const ArkWeb_ResourceRequest *resourceRequest() { return resourceRequest_; } 411e41f4b71Sopenharmony_ci const NativeResourceManager *resourceManager() { return resourceManager_; } 412e41f4b71Sopenharmony_ci ArkWeb_Response *response() { return response_; } 413e41f4b71Sopenharmony_ci ArkWeb_HttpBodyStream *stream() { return stream_; } 414e41f4b71Sopenharmony_ci const std::string rawfilePath() { return rawfilePath_; } 415e41f4b71Sopenharmony_ci 416e41f4b71Sopenharmony_ci void DidReceiveResponse(); 417e41f4b71Sopenharmony_ci void DidReceiveData(const uint8_t *buffer, int64_t bufLen); 418e41f4b71Sopenharmony_ci void DidFinish(); 419e41f4b71Sopenharmony_ci void DidFailWithError(ArkWeb_NetError errorCode); 420e41f4b71Sopenharmony_ci 421e41f4b71Sopenharmony_ciprivate: 422e41f4b71Sopenharmony_ci const ArkWeb_ResourceRequest *resourceRequest_{nullptr}; 423e41f4b71Sopenharmony_ci const ArkWeb_ResourceHandler *resourceHandler_{nullptr}; 424e41f4b71Sopenharmony_ci const NativeResourceManager *resourceManager_{nullptr}; 425e41f4b71Sopenharmony_ci ArkWeb_Response *response_; 426e41f4b71Sopenharmony_ci bool stopped_{false}; 427e41f4b71Sopenharmony_ci std::string rawfilePath_; 428e41f4b71Sopenharmony_ci ArkWeb_HttpBodyStream *stream_{nullptr}; 429e41f4b71Sopenharmony_ci std::mutex mutex_; 430e41f4b71Sopenharmony_ci}; 431e41f4b71Sopenharmony_ci 432e41f4b71Sopenharmony_ci#endif // RAWFILE_REQUEST_H 433e41f4b71Sopenharmony_ci``` 434e41f4b71Sopenharmony_ci 435e41f4b71Sopenharmony_cimain/cpp/rawfile_request.cpp 436e41f4b71Sopenharmony_ci```c++ 437e41f4b71Sopenharmony_ci#include "rawfile_request.h" 438e41f4b71Sopenharmony_ci 439e41f4b71Sopenharmony_ci#include "threads.h" 440e41f4b71Sopenharmony_ci 441e41f4b71Sopenharmony_ci#include "hilog/log.h" 442e41f4b71Sopenharmony_ci#include "rawfile/raw_file.h" 443e41f4b71Sopenharmony_ci#include "rawfile/raw_file_manager.h" 444e41f4b71Sopenharmony_ci 445e41f4b71Sopenharmony_ci#undef LOG_TAG 446e41f4b71Sopenharmony_ci#define LOG_TAG "ss-handler" 447e41f4b71Sopenharmony_ci 448e41f4b71Sopenharmony_cinamespace { 449e41f4b71Sopenharmony_ci 450e41f4b71Sopenharmony_ciuint8_t buffer[1024]; 451e41f4b71Sopenharmony_cicnd_t http_body_cnd; 452e41f4b71Sopenharmony_cimtx_t http_body_mtx; 453e41f4b71Sopenharmony_ci 454e41f4b71Sopenharmony_ci// Read callback of HttpBodyStream. 455e41f4b71Sopenharmony_civoid ReadCallback(const ArkWeb_HttpBodyStream *httpBodyStream, uint8_t* buffer, int bytesRead) 456e41f4b71Sopenharmony_ci{ 457e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "read http body back."); 458e41f4b71Sopenharmony_ci bool isEof = OH_ArkWebHttpBodyStream_IsEof(httpBodyStream); 459e41f4b71Sopenharmony_ci if (!isEof && bytesRead != 0) { 460e41f4b71Sopenharmony_ci memset(buffer, 0, 1000); 461e41f4b71Sopenharmony_ci OH_ArkWebHttpBodyStream_Read(httpBodyStream, buffer, 1000); 462e41f4b71Sopenharmony_ci } else { 463e41f4b71Sopenharmony_ci RawfileRequest *rawfileRequest = (RawfileRequest *)OH_ArkWebHttpBodyStream_GetUserData(httpBodyStream); 464e41f4b71Sopenharmony_ci if (rawfileRequest) { 465e41f4b71Sopenharmony_ci rawfileRequest->ReadRawfileDataOnWorkerThread(); 466e41f4b71Sopenharmony_ci cnd_signal(&http_body_cnd); 467e41f4b71Sopenharmony_ci } 468e41f4b71Sopenharmony_ci } 469e41f4b71Sopenharmony_ci} 470e41f4b71Sopenharmony_ci 471e41f4b71Sopenharmony_ciint ReadHttpBodyOnWorkerThread(void* userData) 472e41f4b71Sopenharmony_ci{ 473e41f4b71Sopenharmony_ci memset(buffer, 0, 1000); 474e41f4b71Sopenharmony_ci ArkWeb_HttpBodyStream *httpBodyStream = (ArkWeb_HttpBodyStream *)userData; 475e41f4b71Sopenharmony_ci OH_ArkWebHttpBodyStream_Read(httpBodyStream, buffer, 1000); 476e41f4b71Sopenharmony_ci cnd_init(&http_body_cnd); 477e41f4b71Sopenharmony_ci mtx_init(&http_body_mtx, mtx_plain); 478e41f4b71Sopenharmony_ci cnd_wait(&http_body_cnd, &http_body_mtx); 479e41f4b71Sopenharmony_ci return 0; 480e41f4b71Sopenharmony_ci} 481e41f4b71Sopenharmony_ci 482e41f4b71Sopenharmony_ciint ReadRawfileOnWorkerThread(void* userData) 483e41f4b71Sopenharmony_ci{ 484e41f4b71Sopenharmony_ci RawfileRequest * rawfileRequest = (RawfileRequest *)userData; 485e41f4b71Sopenharmony_ci if (rawfileRequest) { 486e41f4b71Sopenharmony_ci rawfileRequest->ReadRawfileDataOnWorkerThread(); 487e41f4b71Sopenharmony_ci } 488e41f4b71Sopenharmony_ci return 0; 489e41f4b71Sopenharmony_ci} 490e41f4b71Sopenharmony_ci 491e41f4b71Sopenharmony_ci// Callback used when ArkWeb_HttpBodyStream is initialized. 492e41f4b71Sopenharmony_civoid InitCallback(const ArkWeb_HttpBodyStream *httpBodyStream, ArkWeb_NetError result) 493e41f4b71Sopenharmony_ci{ 494e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "init http body stream done %{public}d.", result); 495e41f4b71Sopenharmony_ci bool isChunked = OH_ArkWebHttpBodyStream_IsChunked(httpBodyStream); 496e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "http body stream is chunked %{public}d.", isChunked); 497e41f4b71Sopenharmony_ci thrd_t th; 498e41f4b71Sopenharmony_ci if (thrd_create(&th, ReadHttpBodyOnWorkerThread, (void *)httpBodyStream) != thrd_success) { 499e41f4b71Sopenharmony_ci OH_LOG_ERROR(LOG_APP, "create thread failed."); 500e41f4b71Sopenharmony_ci return; 501e41f4b71Sopenharmony_ci } 502e41f4b71Sopenharmony_ci 503e41f4b71Sopenharmony_ci if (thrd_detach(th) != thrd_success) { 504e41f4b71Sopenharmony_ci OH_LOG_ERROR(LOG_APP, "detach thread failed."); 505e41f4b71Sopenharmony_ci } 506e41f4b71Sopenharmony_ci} 507e41f4b71Sopenharmony_ci 508e41f4b71Sopenharmony_ciconst int blockSize = 1024 * 8; 509e41f4b71Sopenharmony_ci 510e41f4b71Sopenharmony_ci} // namespace 511e41f4b71Sopenharmony_ci 512e41f4b71Sopenharmony_ciRawfileRequest::RawfileRequest(const ArkWeb_ResourceRequest *resourceRequest, 513e41f4b71Sopenharmony_ci const ArkWeb_ResourceHandler *resourceHandler, 514e41f4b71Sopenharmony_ci const NativeResourceManager* resourceManager) 515e41f4b71Sopenharmony_ci : resourceRequest_(resourceRequest), 516e41f4b71Sopenharmony_ci resourceHandler_(resourceHandler), 517e41f4b71Sopenharmony_ci resourceManager_(resourceManager) {} 518e41f4b71Sopenharmony_ci 519e41f4b71Sopenharmony_ciRawfileRequest::~RawfileRequest() {} 520e41f4b71Sopenharmony_ci 521e41f4b71Sopenharmony_civoid RawfileRequest::Start() 522e41f4b71Sopenharmony_ci{ 523e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "start a rawfile request."); 524e41f4b71Sopenharmony_ci char* url; 525e41f4b71Sopenharmony_ci OH_ArkWebResourceRequest_GetUrl(resourceRequest_, &url); 526e41f4b71Sopenharmony_ci std::string urlStr(url); 527e41f4b71Sopenharmony_ci std::size_t position = urlStr.rfind('/'); 528e41f4b71Sopenharmony_ci if (position != std::string::npos) { 529e41f4b71Sopenharmony_ci rawfilePath_ = urlStr.substr(position + 1); 530e41f4b71Sopenharmony_ci } 531e41f4b71Sopenharmony_ci OH_ArkWeb_ReleaseString(url); 532e41f4b71Sopenharmony_ci 533e41f4b71Sopenharmony_ci OH_ArkWeb_CreateResponse(&response_); 534e41f4b71Sopenharmony_ci OH_ArkWebResourceRequest_GetHttpBodyStream(resourceRequest(), &stream_); 535e41f4b71Sopenharmony_ci if (stream_) { 536e41f4b71Sopenharmony_ci OH_LOG_ERROR(LOG_APP, "have http body stream"); 537e41f4b71Sopenharmony_ci OH_ArkWebHttpBodyStream_SetUserData(stream_, this); 538e41f4b71Sopenharmony_ci OH_ArkWebHttpBodyStream_SetReadCallback(stream_, ReadCallback); 539e41f4b71Sopenharmony_ci OH_ArkWebHttpBodyStream_Init(stream_, InitCallback); 540e41f4b71Sopenharmony_ci } else { 541e41f4b71Sopenharmony_ci thrd_t th; 542e41f4b71Sopenharmony_ci if (thrd_create(&th, ReadRawfileOnWorkerThread, (void *)this) != thrd_success) { 543e41f4b71Sopenharmony_ci OH_LOG_ERROR(LOG_APP, "create thread failed."); 544e41f4b71Sopenharmony_ci return; 545e41f4b71Sopenharmony_ci } 546e41f4b71Sopenharmony_ci 547e41f4b71Sopenharmony_ci if (thrd_detach(th) != thrd_success) { 548e41f4b71Sopenharmony_ci OH_LOG_ERROR(LOG_APP, "detach thread failed."); 549e41f4b71Sopenharmony_ci } 550e41f4b71Sopenharmony_ci } 551e41f4b71Sopenharmony_ci} 552e41f4b71Sopenharmony_ci 553e41f4b71Sopenharmony_ci// Read rawfile in the worker thread and return it to the Web kernel using ResourceHandler. 554e41f4b71Sopenharmony_civoid RawfileRequest::ReadRawfileDataOnWorkerThread() 555e41f4b71Sopenharmony_ci{ 556e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "read rawfile in worker thread."); 557e41f4b71Sopenharmony_ci const struct UrlInfo { 558e41f4b71Sopenharmony_ci std::string resource; 559e41f4b71Sopenharmony_ci std::string mimeType; 560e41f4b71Sopenharmony_ci } urlInfos[] = { 561e41f4b71Sopenharmony_ci {"test.html", "text/html"}, 562e41f4b71Sopenharmony_ci {"video.html", "text/html"}, 563e41f4b71Sopenharmony_ci {"isolated.html", "text/html"}, 564e41f4b71Sopenharmony_ci {"csp_bypassing.html", "text/html"}, 565e41f4b71Sopenharmony_ci {"post_data.html", "text/html"}, 566e41f4b71Sopenharmony_ci {"chunked_post_stream.html", "text/html"}, 567e41f4b71Sopenharmony_ci {"local.html", "text/html"}, 568e41f4b71Sopenharmony_ci {"service_worker.html", "text/html"}, 569e41f4b71Sopenharmony_ci {"csp_script.js", "text/javascript"}, 570e41f4b71Sopenharmony_ci {"sw.js", "text/javascript"}, 571e41f4b71Sopenharmony_ci {"isolated_script.js", "text/javascript"}, 572e41f4b71Sopenharmony_ci {"local_script.js", "text/javascript"}, 573e41f4b71Sopenharmony_ci {"test.mp4", "video/mp4"}, 574e41f4b71Sopenharmony_ci {"xhr", "application/json"} 575e41f4b71Sopenharmony_ci }; 576e41f4b71Sopenharmony_ci 577e41f4b71Sopenharmony_ci if (!resourceManager()) { 578e41f4b71Sopenharmony_ci OH_LOG_ERROR(LOG_APP, "read rawfile error, resource manager is nullptr."); 579e41f4b71Sopenharmony_ci return; 580e41f4b71Sopenharmony_ci } 581e41f4b71Sopenharmony_ci 582e41f4b71Sopenharmony_ci RawFile *rawfile = OH_ResourceManager_OpenRawFile(resourceManager(), rawfilePath().c_str()); 583e41f4b71Sopenharmony_ci if (!rawfile) { 584e41f4b71Sopenharmony_ci OH_ArkWebResponse_SetStatus(response(), 404); 585e41f4b71Sopenharmony_ci } else { 586e41f4b71Sopenharmony_ci OH_ArkWebResponse_SetStatus(response(), 200); 587e41f4b71Sopenharmony_ci } 588e41f4b71Sopenharmony_ci 589e41f4b71Sopenharmony_ci for (auto &urlInfo : urlInfos) { 590e41f4b71Sopenharmony_ci if (urlInfo.resource == rawfilePath()) { 591e41f4b71Sopenharmony_ci OH_ArkWebResponse_SetMimeType(response(), urlInfo.mimeType.c_str()); 592e41f4b71Sopenharmony_ci break; 593e41f4b71Sopenharmony_ci } 594e41f4b71Sopenharmony_ci } 595e41f4b71Sopenharmony_ci OH_ArkWebResponse_SetCharset(response(), "UTF-8"); 596e41f4b71Sopenharmony_ci 597e41f4b71Sopenharmony_ci long len = OH_ResourceManager_GetRawFileSize(rawfile); 598e41f4b71Sopenharmony_ci OH_ArkWebResponse_SetHeaderByName(response(), "content-length", std::to_string(len).c_str(), false); 599e41f4b71Sopenharmony_ci DidReceiveResponse(); 600e41f4b71Sopenharmony_ci 601e41f4b71Sopenharmony_ci long consumed = 0; 602e41f4b71Sopenharmony_ci uint8_t buffer[blockSize]; 603e41f4b71Sopenharmony_ci while (true) { 604e41f4b71Sopenharmony_ci int ret = OH_ResourceManager_ReadRawFile(rawfile, buffer, blockSize); 605e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "read rawfile %{public}d bytes.", ret); 606e41f4b71Sopenharmony_ci if (ret == 0) { 607e41f4b71Sopenharmony_ci break; 608e41f4b71Sopenharmony_ci } 609e41f4b71Sopenharmony_ci consumed += ret; 610e41f4b71Sopenharmony_ci OH_ResourceManager_SeekRawFile(rawfile, consumed, 0); 611e41f4b71Sopenharmony_ci DidReceiveData(buffer, ret); 612e41f4b71Sopenharmony_ci memset(buffer, 0, blockSize); 613e41f4b71Sopenharmony_ci } 614e41f4b71Sopenharmony_ci 615e41f4b71Sopenharmony_ci OH_ResourceManager_CloseRawFile(rawfile); 616e41f4b71Sopenharmony_ci DidFinish(); 617e41f4b71Sopenharmony_ci} 618e41f4b71Sopenharmony_ci 619e41f4b71Sopenharmony_civoid RawfileRequest::Stop() 620e41f4b71Sopenharmony_ci{ 621e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "stop the rawfile request."); 622e41f4b71Sopenharmony_ci std::lock_guard<std::mutex> guard(mutex_); 623e41f4b71Sopenharmony_ci stopped_ = true; 624e41f4b71Sopenharmony_ci if (response_) { 625e41f4b71Sopenharmony_ci OH_ArkWeb_DestroyResponse(response_); 626e41f4b71Sopenharmony_ci } 627e41f4b71Sopenharmony_ci OH_ArkWebResourceRequest_Destroy(resourceRequest_); 628e41f4b71Sopenharmony_ci OH_ArkWebResourceHandler_Destroy(resourceHandler_); 629e41f4b71Sopenharmony_ci} 630e41f4b71Sopenharmony_ci 631e41f4b71Sopenharmony_civoid RawfileRequest::DidReceiveResponse() 632e41f4b71Sopenharmony_ci{ 633e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "did receive response."); 634e41f4b71Sopenharmony_ci std::lock_guard<std::mutex> guard(mutex_); 635e41f4b71Sopenharmony_ci if (!stopped_) { 636e41f4b71Sopenharmony_ci OH_ArkWebResourceHandler_DidReceiveResponse(resourceHandler_, response_); 637e41f4b71Sopenharmony_ci } 638e41f4b71Sopenharmony_ci} 639e41f4b71Sopenharmony_ci 640e41f4b71Sopenharmony_civoid RawfileRequest::DidReceiveData(const uint8_t *buffer, int64_t bufLen) 641e41f4b71Sopenharmony_ci{ 642e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "did receive data."); 643e41f4b71Sopenharmony_ci std::lock_guard<std::mutex> guard(mutex_); 644e41f4b71Sopenharmony_ci if (!stopped_) { 645e41f4b71Sopenharmony_ci OH_ArkWebResourceHandler_DidReceiveData(resourceHandler_, buffer, bufLen); 646e41f4b71Sopenharmony_ci } 647e41f4b71Sopenharmony_ci} 648e41f4b71Sopenharmony_ci 649e41f4b71Sopenharmony_civoid RawfileRequest::DidFinish() 650e41f4b71Sopenharmony_ci{ 651e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "did finish."); 652e41f4b71Sopenharmony_ci std::lock_guard<std::mutex> guard(mutex_); 653e41f4b71Sopenharmony_ci if (!stopped_) { 654e41f4b71Sopenharmony_ci OH_ArkWebResourceHandler_DidFinish(resourceHandler_); 655e41f4b71Sopenharmony_ci } 656e41f4b71Sopenharmony_ci} 657e41f4b71Sopenharmony_ci 658e41f4b71Sopenharmony_civoid RawfileRequest::DidFailWithError(ArkWeb_NetError errorCode) 659e41f4b71Sopenharmony_ci{ 660e41f4b71Sopenharmony_ci OH_LOG_INFO(LOG_APP, "did finish with error %{public}d.", errorCode); 661e41f4b71Sopenharmony_ci if (!stopped_) { 662e41f4b71Sopenharmony_ci OH_ArkWebResourceHandler_DidFailWithError(resourceHandler_, errorCode); 663e41f4b71Sopenharmony_ci } 664e41f4b71Sopenharmony_ci} 665e41f4b71Sopenharmony_ci``` 666e41f4b71Sopenharmony_ci 667e41f4b71Sopenharmony_cimain/resources/rawfile/test.html 668e41f4b71Sopenharmony_ci```html 669e41f4b71Sopenharmony_ci<html> 670e41f4b71Sopenharmony_ci<head> 671e41f4b71Sopenharmony_ci<meta name="viewport" content="width=device-width,initial-scale=1"> 672e41f4b71Sopenharmony_ci</head> 673e41f4b71Sopenharmony_ci 674e41f4b71Sopenharmony_ci<body> 675e41f4b71Sopenharmony_ci<h1> Network Interception Test Demo</h1> 676e41f4b71Sopenharmony_ci<a href="https://www.example.com/video.html"> Intercept the video resource request and read the local MP4 file.</a><br/> 677e41f4b71Sopenharmony_ci<a href="https://www.example.com/csp_bypassing.html">The third-party protocol bypasses the CSP check and this request is successfully intercepted.</a><br/> 678e41f4b71Sopenharmony_ci<a href="https://www.example.com/isolated.html">Intercept the third-party protocol with ISOLATED attribute.</a><br/> 679e41f4b71Sopenharmony_ci<a href="https://www.example.com/local.html">Intercept the third-party protocol with LOCAL attribute.</a><br/> 680e41f4b71Sopenharmony_ci<a href="https://www.example.com/service_worker.html"> Intercept the request triggered by the service worker.</a><br/> 681e41f4b71Sopenharmony_ci<a href="https://www.example.com/post_data.html">Read the HTTP body stream of BLOB type.</a><br/> 682e41f4b71Sopenharmony_ci<a href="https://www.example.com/chunked_post_stream.html">Read the http body stream of chunked type.</a> 683e41f4b71Sopenharmony_ci</body> 684e41f4b71Sopenharmony_ci</html> 685e41f4b71Sopenharmony_ci``` 686e41f4b71Sopenharmony_ci 687e41f4b71Sopenharmony_cimain/resources/rawfile/cat.svg 688e41f4b71Sopenharmony_ci``` 689e41f4b71Sopenharmony_ci<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13.37 10.79"><path d="M12.8 10.18l-.8-.8c-.98-.8-.86-1.92-.87-2.04-.02-.1-.02-.58.02-.74.04-.15 0-.32 0-.32.28-1.18 1.2-.85 1.2-.85.38.04.4-.33.4-.33.25-.13.2-.4.2-.4l-.47-.48c-.18-.48-.7-.6-.7-.6.08-.48-.17-.78-.17-.78-.03.14-.58.72-.62.73-.63.15-.43.26-.83.55-.4.28-1.26.63-1.64.43-.37-.2-3.5-.5-4.86-.5-.4 0-.7.1-.95.2-.23-.16-.52-.52-.73-1.02-.3-.74-.36-1.48-.12-1.98.13-.27.28-.42.44-.45.23-.05.52.16.6.24.17.14.42.13.56-.03.15-.15.14-.4-.02-.55C3.38.4 2.8-.1 2.14.02c-.42.08-.76.38-1 .9-.34.7-.3 1.66.1 2.6.18.44.47.93.83 1.25-.1.13-.13.23-.13.23-.12.27-.44.9-.33 1.45.13.56-.22.82-.3.88-.05.07-.73.47-.73.47L0 9.78c-.08.38.43.6.43.6.18-.03.2-.63.2-.63l.44-1.04 1.66-.6s0 .7-.02.83-.1.35-.1.35c.08.46 1.2 1.5 1.2 1.5h.85v-.26c-.07-.3-.5-.16-.5-.16l-.62-.95c.66-.5.93-1.38.93-1.38.3.26 1.8-.22 1.8-.22l.9.1-.25 2.1c-.07.5.05.68.05.68h.4c.3 0 .48.03.48-.27 0-.28-.4-.23-.4-.23l1-1.95c.93-.58 1.53.26 1.53.26l.05.3c.37.53 2.38 1.9 2.38 1.9h1v-.3c-.18-.32-.6-.2-.6-.2z"/></svg> 690e41f4b71Sopenharmony_ci``` 691e41f4b71Sopenharmony_ci 692e41f4b71Sopenharmony_cimain/resources/rawfile/csp_bypassing.html 693e41f4b71Sopenharmony_ci```html 694e41f4b71Sopenharmony_ci<html> 695e41f4b71Sopenharmony_ci<head> 696e41f4b71Sopenharmony_ci<meta name="viewport" content="width=device-width,initial-scale=1"> 697e41f4b71Sopenharmony_ci<meta http-equiv="Content-Security-Policy" content="default-src 'self'; media-src 'self'"> 698e41f4b71Sopenharmony_ci</head> 699e41f4b71Sopenharmony_ci<body> 700e41f4b71Sopenharmony_ci<p>scheme: custom-csp-bypassing</p> 701e41f4b71Sopenharmony_ci<p>options: ARKWEB_SCHEME_OPTION_CSP_BYPASSING | ARKWEB_SCHEME_OPTION_STANDARD</p> 702e41f4b71Sopenharmony_ci<script src="custom-csp-bypassing://www.example.com/csp_script.js"></script> 703e41f4b71Sopenharmony_ci</body> 704e41f4b71Sopenharmony_ci</html> 705e41f4b71Sopenharmony_ci``` 706e41f4b71Sopenharmony_ci 707e41f4b71Sopenharmony_cimain/resources/rawfile/csp_script.js 708e41f4b71Sopenharmony_ci```js 709e41f4b71Sopenharmony_ciconst body = document.body; 710e41f4b71Sopenharmony_ciconst element = document.createElement('div'); 711e41f4b71Sopenharmony_cielement.textContent = 'csp_script.js bypass the csp rules'; 712e41f4b71Sopenharmony_cibody.appendChild(element); 713e41f4b71Sopenharmony_ci``` 714e41f4b71Sopenharmony_ci 715e41f4b71Sopenharmony_cimain/resources/rawfile/isolated_script.js 716e41f4b71Sopenharmony_ci```js 717e41f4b71Sopenharmony_ciconst element = document.getElementById('isolated_test'); 718e41f4b71Sopenharmony_cielement.textContent = 'isolated_script.js not blocked'; 719e41f4b71Sopenharmony_ci``` 720e41f4b71Sopenharmony_ci 721e41f4b71Sopenharmony_cimain/resources/rawfile/isolated.html 722e41f4b71Sopenharmony_ci```html 723e41f4b71Sopenharmony_ci<html> 724e41f4b71Sopenharmony_ci<head> 725e41f4b71Sopenharmony_ci<meta name="viewport" content="width=device-width,initial-scale=1"> 726e41f4b71Sopenharmony_ci</head> 727e41f4b71Sopenharmony_ci<body> 728e41f4b71Sopenharmony_ci<p>scheme: custom-isolated</p> 729e41f4b71Sopenharmony_ci<p>options: ARKWEB_SCHEME_OPTION_DISPLAY_ISOLATED</p> 730e41f4b71Sopenharmony_ci<div id="isolated_test">isolated_script.js is intercepted</div> 731e41f4b71Sopenharmony_ci<script src="custom-isolated://www.example.com/isolated_script.js"></script> 732e41f4b71Sopenharmony_ci</body> 733e41f4b71Sopenharmony_ci</html> 734e41f4b71Sopenharmony_ci``` 735e41f4b71Sopenharmony_ci 736e41f4b71Sopenharmony_cimain/resources/rawfile/local_script.js 737e41f4b71Sopenharmony_ci```js 738e41f4b71Sopenharmony_ciconst element = document.getElementById('local_test'); 739e41f4b71Sopenharmony_cielement.textContent = 'local_script.js not blocked.'; 740e41f4b71Sopenharmony_ci``` 741e41f4b71Sopenharmony_ci 742e41f4b71Sopenharmony_cimain/resources/rawfile/local.html 743e41f4b71Sopenharmony_ci```html 744e41f4b71Sopenharmony_ci<html> 745e41f4b71Sopenharmony_ci<head> 746e41f4b71Sopenharmony_ci<meta name="viewport" content="width=device-width,initial-scale=1"> 747e41f4b71Sopenharmony_ci</head> 748e41f4b71Sopenharmony_ci<body> 749e41f4b71Sopenharmony_ci<p>scheme: custom-local</p> 750e41f4b71Sopenharmony_ci<p>options: ARKWEB_SCHEME_OPTION_LOCAL</p> 751e41f4b71Sopenharmony_ci<div id="local_test">local_script.js is intercepted</div> 752e41f4b71Sopenharmony_ci<script src="custom-local://www.example.com/local_script.js"></script> 753e41f4b71Sopenharmony_ci</body> 754e41f4b71Sopenharmony_ci</html> 755e41f4b71Sopenharmony_ci``` 756e41f4b71Sopenharmony_ci 757e41f4b71Sopenharmony_cimain/resources/rawfile/post_data.html 758e41f4b71Sopenharmony_ci```html 759e41f4b71Sopenharmony_ci<html> 760e41f4b71Sopenharmony_ci<head> 761e41f4b71Sopenharmony_ci<meta name="viewport" content="width=device-width,initial-scale=1"> 762e41f4b71Sopenharmony_ci<script> 763e41f4b71Sopenharmony_ci function textPostXhr(url) { 764e41f4b71Sopenharmony_ci var formData = new FormData(); 765e41f4b71Sopenharmony_ci var myBlob = new Blob(["This is my blob content"], {type : "text/plain"}); 766e41f4b71Sopenharmony_ci formData.append("upload", myBlob); 767e41f4b71Sopenharmony_ci var xhr = new XMLHttpRequest(); 768e41f4b71Sopenharmony_ci xhr.open('POST', url, true); 769e41f4b71Sopenharmony_ci xhr.send(formData); 770e41f4b71Sopenharmony_ci xhr.onreadystatechange = function (err) { 771e41f4b71Sopenharmony_ci console.log(err.target.status); 772e41f4b71Sopenharmony_ci } 773e41f4b71Sopenharmony_ci } 774e41f4b71Sopenharmony_ci function textPutXhr(url) { 775e41f4b71Sopenharmony_ci var formData = new FormData(); 776e41f4b71Sopenharmony_ci var myBlob = new Blob(["This is my blob content"], {type : "text/plain"}); 777e41f4b71Sopenharmony_ci formData.append("upload", myBlob); 778e41f4b71Sopenharmony_ci var xhr = new XMLHttpRequest(); 779e41f4b71Sopenharmony_ci xhr.open('PUT', url, true); 780e41f4b71Sopenharmony_ci xhr.send(formData); 781e41f4b71Sopenharmony_ci xhr.onreadystatechange = function (err) { 782e41f4b71Sopenharmony_ci console.log(err.target.status); 783e41f4b71Sopenharmony_ci } 784e41f4b71Sopenharmony_ci } 785e41f4b71Sopenharmony_ci</script> 786e41f4b71Sopenharmony_ci</head> 787e41f4b71Sopenharmony_ci<body> 788e41f4b71Sopenharmony_ci<div onclick="textPostXhr('https://www.example.com/xhr')">test xhr post</div> 789e41f4b71Sopenharmony_ci<div onclick="textPutXhr('https://www.example.com/xhr')">test xhr put</div> 790e41f4b71Sopenharmony_ci</body> 791e41f4b71Sopenharmony_ci</html> 792e41f4b71Sopenharmony_ci``` 793e41f4b71Sopenharmony_ci 794e41f4b71Sopenharmony_cimain/resources/rawfile/service_worker.html 795e41f4b71Sopenharmony_ci```html 796e41f4b71Sopenharmony_ci<html> 797e41f4b71Sopenharmony_ci<head> 798e41f4b71Sopenharmony_ci<meta name="viewport" content="width=device-width,initial-scale=1"> 799e41f4b71Sopenharmony_ci<script> 800e41f4b71Sopenharmony_cifunction registerSuccess() { 801e41f4b71Sopenharmony_ci const body = document.body; 802e41f4b71Sopenharmony_ci const element = document.createElement('div'); 803e41f4b71Sopenharmony_ci element.textContent = 'register sw successful.'; 804e41f4b71Sopenharmony_ci body.appendChild(element); 805e41f4b71Sopenharmony_ci} 806e41f4b71Sopenharmony_ci 807e41f4b71Sopenharmony_cinavigator.serviceWorker.register('/sw.js') 808e41f4b71Sopenharmony_ci .then(reg => registerSuccess()) 809e41f4b71Sopenharmony_ci .catch(error => console.log('failed!', error)) 810e41f4b71Sopenharmony_ci</script> 811e41f4b71Sopenharmony_ci</head> 812e41f4b71Sopenharmony_ci<body> 813e41f4b71Sopenharmony_ci</body> 814e41f4b71Sopenharmony_ci</html> 815e41f4b71Sopenharmony_ci``` 816e41f4b71Sopenharmony_ci 817e41f4b71Sopenharmony_cimain/resources/rawfile/sw.js 818e41f4b71Sopenharmony_ci```js 819e41f4b71Sopenharmony_ciself.addEventListener('install', event => { 820e41f4b71Sopenharmony_ci console.log('v1 installing'); 821e41f4b71Sopenharmony_ci event.waitUntil( 822e41f4b71Sopenharmony_ci caches.open('static-v1').then(cache => cache.add('/cat.svg')) 823e41f4b71Sopenharmony_ci ); 824e41f4b71Sopenharmony_ci}); 825e41f4b71Sopenharmony_ci 826e41f4b71Sopenharmony_ciself.addEventListener('activate', event => { 827e41f4b71Sopenharmony_ci console.log("v1 now redy to handle fetches."); 828e41f4b71Sopenharmony_ci}); 829e41f4b71Sopenharmony_ci``` 830e41f4b71Sopenharmony_ci 831e41f4b71Sopenharmony_cimain/resources/rawfile/video.html 832e41f4b71Sopenharmony_ci```html 833e41f4b71Sopenharmony_ci<html> 834e41f4b71Sopenharmony_ci<head> 835e41f4b71Sopenharmony_ci<meta name="viewport" content="width=device-width,initial-scale=1"> 836e41f4b71Sopenharmony_ci</head> 837e41f4b71Sopenharmony_ci<body> 838e41f4b71Sopenharmony_ci<video width="400" height="400" controls> 839e41f4b71Sopenharmony_ci <source src="https://www.example.com/test.mp4" type="video/mp4"> 840e41f4b71Sopenharmony_ci</video> 841e41f4b71Sopenharmony_ci</body> 842e41f4b71Sopenharmony_ci</html> 843e41f4b71Sopenharmony_ci``` 844e41f4b71Sopenharmony_ci 845e41f4b71Sopenharmony_cimain/resources/rawfile/chunked_post_stream.html 846e41f4b71Sopenharmony_ci```html 847e41f4b71Sopenharmony_ci<html> 848e41f4b71Sopenharmony_ci<head> 849e41f4b71Sopenharmony_ci<meta name="viewport" content="width=device-width,initial-scale=1"> 850e41f4b71Sopenharmony_ci</head> 851e41f4b71Sopenharmony_ci<script> 852e41f4b71Sopenharmony_cilet uploaded = 0; 853e41f4b71Sopenharmony_cilet buf = new Uint8Array(1024 * 50); 854e41f4b71Sopenharmony_cilet start = Date.now(); 855e41f4b71Sopenharmony_civar rs = new ReadableStream({ 856e41f4b71Sopenharmony_ci pull(ctrl) { 857e41f4b71Sopenharmony_ci uploaded += buf.byteLength; 858e41f4b71Sopenharmony_ci crypto.getRandomValues(buf); 859e41f4b71Sopenharmony_ci ctrl.enqueue(buf); 860e41f4b71Sopenharmony_ci if ((start + 1000) < Date.now()) ctrl.close(); 861e41f4b71Sopenharmony_ci } 862e41f4b71Sopenharmony_ci}); 863e41f4b71Sopenharmony_ci 864e41f4b71Sopenharmony_cifunction test() { 865e41f4b71Sopenharmony_ci fetch('https://www.example.com/xhr', { 866e41f4b71Sopenharmony_ci method: 'POST', 867e41f4b71Sopenharmony_ci body: rs, 868e41f4b71Sopenharmony_ci duplex: 'half' 869e41f4b71Sopenharmony_ci }).then(r => r.json()).then(console.log); 870e41f4b71Sopenharmony_ci} 871e41f4b71Sopenharmony_ci</script> 872e41f4b71Sopenharmony_ci<body> 873e41f4b71Sopenharmony_ci<div onclick="test()">test post chunked http body.</div> 874e41f4b71Sopenharmony_ci</body> 875e41f4b71Sopenharmony_ci</html> 876e41f4b71Sopenharmony_ci``` 877e41f4b71Sopenharmony_ci 878e41f4b71Sopenharmony_cimain/resources/rawfile/xhr 879e41f4b71Sopenharmony_ci``` 880e41f4b71Sopenharmony_ci{} 881e41f4b71Sopenharmony_ci``` 882