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