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