xref: /aosp_15_r20/development/tools/winscope/src/common/http_request.ts (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
1*90c8c64dSAndroid Build Coastguard Worker/*
2*90c8c64dSAndroid Build Coastguard Worker * Copyright 2024, The Android Open Source Project
3*90c8c64dSAndroid Build Coastguard Worker *
4*90c8c64dSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*90c8c64dSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*90c8c64dSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*90c8c64dSAndroid Build Coastguard Worker *
8*90c8c64dSAndroid Build Coastguard Worker *     http://www.apache.org/licenses/LICENSE-2.0
9*90c8c64dSAndroid Build Coastguard Worker *
10*90c8c64dSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*90c8c64dSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*90c8c64dSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*90c8c64dSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*90c8c64dSAndroid Build Coastguard Worker * limitations under the License.
15*90c8c64dSAndroid Build Coastguard Worker */
16*90c8c64dSAndroid Build Coastguard Worker
17*90c8c64dSAndroid Build Coastguard Workerimport {assertDefined} from 'common/assert_utils';
18*90c8c64dSAndroid Build Coastguard Worker
19*90c8c64dSAndroid Build Coastguard Workerexport type HttpRequestHeaderType = Array<[string, string]>;
20*90c8c64dSAndroid Build Coastguard Worker
21*90c8c64dSAndroid Build Coastguard Workerexport enum HttpRequestStatus {
22*90c8c64dSAndroid Build Coastguard Worker  UNSENT,
23*90c8c64dSAndroid Build Coastguard Worker  UNAUTH,
24*90c8c64dSAndroid Build Coastguard Worker  SUCCESS,
25*90c8c64dSAndroid Build Coastguard Worker  ERROR,
26*90c8c64dSAndroid Build Coastguard Worker}
27*90c8c64dSAndroid Build Coastguard Worker
28*90c8c64dSAndroid Build Coastguard Workerexport interface HttpResponse {
29*90c8c64dSAndroid Build Coastguard Worker  status: HttpRequestStatus;
30*90c8c64dSAndroid Build Coastguard Worker  type: XMLHttpRequestResponseType; //eslint-disable-line no-undef
31*90c8c64dSAndroid Build Coastguard Worker  text: string;
32*90c8c64dSAndroid Build Coastguard Worker  body: any;
33*90c8c64dSAndroid Build Coastguard Worker  getHeader: (name: string) => string | undefined;
34*90c8c64dSAndroid Build Coastguard Worker}
35*90c8c64dSAndroid Build Coastguard Worker
36*90c8c64dSAndroid Build Coastguard Workerexport class HttpRequest {
37*90c8c64dSAndroid Build Coastguard Worker  static async get(
38*90c8c64dSAndroid Build Coastguard Worker    path: string,
39*90c8c64dSAndroid Build Coastguard Worker    headers: HttpRequestHeaderType,
40*90c8c64dSAndroid Build Coastguard Worker    type?: XMLHttpRequest['responseType'],
41*90c8c64dSAndroid Build Coastguard Worker  ): Promise<HttpResponse> {
42*90c8c64dSAndroid Build Coastguard Worker    return await HttpRequest.call('GET', path, headers, type);
43*90c8c64dSAndroid Build Coastguard Worker  }
44*90c8c64dSAndroid Build Coastguard Worker
45*90c8c64dSAndroid Build Coastguard Worker  static async post(
46*90c8c64dSAndroid Build Coastguard Worker    path: string,
47*90c8c64dSAndroid Build Coastguard Worker    headers: HttpRequestHeaderType,
48*90c8c64dSAndroid Build Coastguard Worker    jsonRequest?: object,
49*90c8c64dSAndroid Build Coastguard Worker  ): Promise<HttpResponse> {
50*90c8c64dSAndroid Build Coastguard Worker    return await HttpRequest.call(
51*90c8c64dSAndroid Build Coastguard Worker      'POST',
52*90c8c64dSAndroid Build Coastguard Worker      path,
53*90c8c64dSAndroid Build Coastguard Worker      headers,
54*90c8c64dSAndroid Build Coastguard Worker      undefined,
55*90c8c64dSAndroid Build Coastguard Worker      jsonRequest,
56*90c8c64dSAndroid Build Coastguard Worker    );
57*90c8c64dSAndroid Build Coastguard Worker  }
58*90c8c64dSAndroid Build Coastguard Worker
59*90c8c64dSAndroid Build Coastguard Worker  private static async call(
60*90c8c64dSAndroid Build Coastguard Worker    method: string,
61*90c8c64dSAndroid Build Coastguard Worker    path: string,
62*90c8c64dSAndroid Build Coastguard Worker    headers: HttpRequestHeaderType,
63*90c8c64dSAndroid Build Coastguard Worker    type?: XMLHttpRequest['responseType'],
64*90c8c64dSAndroid Build Coastguard Worker    jsonRequest?: object,
65*90c8c64dSAndroid Build Coastguard Worker  ): Promise<HttpResponse> {
66*90c8c64dSAndroid Build Coastguard Worker    const req = new XMLHttpRequest();
67*90c8c64dSAndroid Build Coastguard Worker    let status: HttpRequestStatus | undefined;
68*90c8c64dSAndroid Build Coastguard Worker
69*90c8c64dSAndroid Build Coastguard Worker    await new Promise<void>((resolve) => {
70*90c8c64dSAndroid Build Coastguard Worker      req.onreadystatechange = async () => {
71*90c8c64dSAndroid Build Coastguard Worker        if (req.readyState !== XMLHttpRequest.DONE) {
72*90c8c64dSAndroid Build Coastguard Worker          return;
73*90c8c64dSAndroid Build Coastguard Worker        }
74*90c8c64dSAndroid Build Coastguard Worker        if (req.status === XMLHttpRequest.UNSENT) {
75*90c8c64dSAndroid Build Coastguard Worker          status = HttpRequestStatus.UNSENT;
76*90c8c64dSAndroid Build Coastguard Worker        } else if (req.status === 200) {
77*90c8c64dSAndroid Build Coastguard Worker          status = HttpRequestStatus.SUCCESS;
78*90c8c64dSAndroid Build Coastguard Worker        } else if (req.status === 403) {
79*90c8c64dSAndroid Build Coastguard Worker          status = HttpRequestStatus.UNAUTH;
80*90c8c64dSAndroid Build Coastguard Worker        } else {
81*90c8c64dSAndroid Build Coastguard Worker          status = HttpRequestStatus.ERROR;
82*90c8c64dSAndroid Build Coastguard Worker        }
83*90c8c64dSAndroid Build Coastguard Worker        resolve();
84*90c8c64dSAndroid Build Coastguard Worker      };
85*90c8c64dSAndroid Build Coastguard Worker      req.responseType = type || '';
86*90c8c64dSAndroid Build Coastguard Worker      req.open(method, path);
87*90c8c64dSAndroid Build Coastguard Worker      headers.forEach(([header, value]) => {
88*90c8c64dSAndroid Build Coastguard Worker        req.setRequestHeader(header, value);
89*90c8c64dSAndroid Build Coastguard Worker      });
90*90c8c64dSAndroid Build Coastguard Worker
91*90c8c64dSAndroid Build Coastguard Worker      if (jsonRequest) {
92*90c8c64dSAndroid Build Coastguard Worker        const json = JSON.stringify(jsonRequest);
93*90c8c64dSAndroid Build Coastguard Worker        req.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
94*90c8c64dSAndroid Build Coastguard Worker        req.send(json);
95*90c8c64dSAndroid Build Coastguard Worker      } else {
96*90c8c64dSAndroid Build Coastguard Worker        req.send();
97*90c8c64dSAndroid Build Coastguard Worker      }
98*90c8c64dSAndroid Build Coastguard Worker    });
99*90c8c64dSAndroid Build Coastguard Worker
100*90c8c64dSAndroid Build Coastguard Worker    const hasResponseText =
101*90c8c64dSAndroid Build Coastguard Worker      req.responseType === '' || req.responseType === 'text';
102*90c8c64dSAndroid Build Coastguard Worker
103*90c8c64dSAndroid Build Coastguard Worker    return {
104*90c8c64dSAndroid Build Coastguard Worker      status: assertDefined(status),
105*90c8c64dSAndroid Build Coastguard Worker      type: req.responseType,
106*90c8c64dSAndroid Build Coastguard Worker      text: hasResponseText ? req.responseText : '',
107*90c8c64dSAndroid Build Coastguard Worker      body: req.response,
108*90c8c64dSAndroid Build Coastguard Worker      getHeader: (name: string) => req.getResponseHeader(name) ?? undefined,
109*90c8c64dSAndroid Build Coastguard Worker    };
110*90c8c64dSAndroid Build Coastguard Worker  }
111*90c8c64dSAndroid Build Coastguard Worker}
112