目录

Interceptor: Richer and Higher-Level Customization Capabilities

Interceptors can be used to modify HTTP requests and responses. You can create an interceptor chain by customizing a group of interceptors to modify your network requests and responses. Remote Communication Kit provides the interceptor capability. You can add the interceptors parameter to SessionConfiguration and pass the customized interceptor settings to intercept HTTP requests and responses as needed.

Constraints

The powerful and higher-level interceptor customization capability supports phones, 2-in-1 devices, tablets, and wearables. Starting from version 5.1.1(19), it is also supported on TVs.

How an Interceptor Works

Before an HTTP request sent by a client reaches the target server, an interceptor can be used to modify the request. As shown in the following figure, the RequestUrlChangeInterceptor chain interceptor (interceptor 1 for short) and ResponseHeaderRemoveInterceptor chain interceptor (interceptor 2 for short) are defined. Interceptor 1 intercepts a request and then adjusts the size of the requested resource by modifying the URL in the HTTP request when the network quality is poor. Then, the request passes through interceptor 2 and finally reaches the Internet. Before the response returned by the target server reaches the client, interceptor 2 intercepts the response and checks and modifies the request header. Then, the response passes through interceptor 1, and finally, the client receives the response.

RequestUrlChangeInterceptor and ResponseHeaderRemoveInterceptor are both custom interceptors. You need to implement their internal logic by coding.

Defining and Using Interceptors

This section describes how to customize interceptors, define the RequestUrlChangeInterceptor and ResponseHeaderRemoveInterceptor interceptors to implement Interceptor, and customize the processing logic in the intercept() method based on service requirements to modify requests and responses. The following uses a scenario where the network quality is poor as an example.

  1. Import required modules. In this example, the following modules are imported as Remote Communication Kit is used to initiate network requests and handle response success and failure:

    import { rcp } from '@kit.RemoteCommunicationKit';
    import { url } from '@kit.ArkTS';
  2. Define two interceptors. In RequestUrlChangeInterceptor, when the network quality is poor, modify the URL path in the request to request a smaller image for a better user experience. In the code, isNetWorkFast in NetworkQualityProvider is used to simulate the quality of the network. This is only a simulated example, and you need to implement the logic based on your own needs.

    // Simulate the scenario where the network quality is poor.
    export class NetworkQualityProvider {
      public isNetworkFast: boolean = true
    
      public constructor(isNetworkFast: boolean) {
        this.isNetworkFast = isNetworkFast
      }
    }
    
    // Define RequestUrlChangeInterceptor.
    export class RequestUrlChangeInterceptor implements rcp.Interceptor {
      private readonly networkQualityProvider: NetworkQualityProvider;
    
      constructor(networkQualityProvider: NetworkQualityProvider) {
        this.networkQualityProvider = networkQualityProvider;
      }
    
      // Customize the request processing logic.
      async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
        if (context.request.method === 'GET' && !this.networkQualityProvider.isNetworkFast) {
          console.info('[RequestUrlChangeInterceptor]: Slow network is detected');
          const parts = context.request.url.pathname.split('.');
          if (parts.length === 2) {
            const changed = url.URL.parseURL(context.request.url.href);
            changed.pathname = parts[0] + '_small.' + parts[1];
            console.info(`[RequestUrlChangeInterceptor]: Replace URL from "${context.request.url.href}" to "${changed}"`);
            AppStorage.setOrCreate('ReplacedInfo',
              `[RequestUrlChangeInterceptor]: Replace URL from '${context.request.url.href}' to '${changed}'`);
            context.request.url = changed;
          }
        } else {
          console.info('[RequestUrlChangeInterceptor]: Network is fast');
          AppStorage.setOrCreate('ReplacedInfo', '');
        }
        return next.handle(context);
      }
    }
    
    // Define ResponseHeaderRemoveInterceptor.
    export class ResponseHeaderRemoveInterceptor implements rcp.Interceptor {
      // Customize the response processing logic.
      async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
        const response = await next.handle(context);
        const toReturn: rcp.Response = {
          request: response.request,
          statusCode: response.statusCode,
          httpVersion: response.httpVersion,
          headers: {
            'content-range': response.headers['content-range']
          },
          effectiveUrl: response.effectiveUrl,
          timeInfo: response.timeInfo,
          toJSON: () => null
        };
        console.info('[ResponseHeaderRemoveInterceptor]: Response was modified');
        AppStorage.setOrCreate('ReplacedResponseData',
          `[ResponseHeaderRemoveInterceptor]: Response was modified '${context.request.url.href}'`);
        return toReturn;
      }
    }
  3. Use the interceptors. You can add them to requests or responses through the SessionConfiguration object in the Remote Communication Kit module.

    function httpRequest(networkStateSimulator: NetworkQualityProvider): rcp.Session {
      const sessionConfig: rcp.SessionConfiguration = {
        interceptors: [
          new RequestUrlChangeInterceptor(networkStateSimulator),
          new ResponseHeaderRemoveInterceptor()
        ],
        requestConfiguration: {
          security: {
            tlsOptions: {
              tlsVersion: 'TlsV1.3'
            }
          }
        }
      };
      const session = rcp.createSession(sessionConfig);
      return session;
    }