import { LogLevel , LogService } from "./logging/LogService" ; import { getRequestFn } from "./request" ; let lastRequestId = 0 ; category param { string } baseUrl param { "GET" | "POST" | "PUT" | "DELETE" } method param { string } endpoint param { any } qs param { any } body param { any } headers param { number } timeout param { boolean } raw param { string } contentType param { string } noEncoding returns { Promise < any > } export function doHttpRequest ( baseUrl , method , endpoint , qs = null , body = null , headers = { } , timeout = 60000 , raw = false , contentType = "application/json" , noEncoding = false ) { if ( ! endpoint . startsWith ( '/' ) ) { endpoint = '/' + endpoint ; } const requestId = ++ lastRequestId ; const url = baseUrl + endpoint ; LogService . debug ( "MatrixHttpClient (REQ-" + requestId + ")" , method + " " + url ) ; if ( LogService . level . includes ( LogLevel . TRACE ) ) { if ( qs ) LogService . trace ( "MatrixHttpClient (REQ-" + requestId + ")" , "qs = " + JSON . stringify ( qs ) ) ; if ( body && ! Buffer . isBuffer ( body ) ) LogService . trace ( "MatrixHttpClient (REQ-" + requestId + ")" , "body = " + JSON . stringify ( redactObjectForLogging ( body ) ) ) ; if ( body && Buffer . isBuffer ( body ) ) LogService . trace ( "MatrixHttpClient (REQ-" + requestId + ")" , "body = <Buffer>" ) ; } const params = { uri : url , method : method , qs : qs , encoding : noEncoding === false ? undefined : null , useQuerystring : true , qsStringifyOptions : { options : { arrayFormat : 'repeat' } , } , timeout : timeout , headers : headers , forever : true , } ; if ( body ) { if ( Buffer . isBuffer ( body ) ) { params . headers [ "Content-Type" ] = contentType ; params . body = body ; } else { params . headers [ "Content-Type" ] = "application/json" ; params . body = JSON . stringify ( body ) ; } } return new Promise ( ( resolve , reject ) => { getRequestFn ( ) ( params , ( err , response , resBody ) => { if ( err ) { LogService . error ( "MatrixHttpClient (REQ-" + requestId + ")" , err ) ; reject ( err ) ; } else { if ( typeof ( resBody ) === 'string' ) { try { resBody = JSON . parse ( resBody ) ; } catch ( e ) { } } if ( typeof ( response . body ) === 'string' ) { try { response . body = JSON . parse ( response . body ) ; } catch ( e ) { } } const respIsBuffer = ( response . body instanceof Buffer ) ; if ( LogService . level . includes ( LogLevel . TRACE ) ) { const redactedBody = respIsBuffer ? '<Buffer>' : redactObjectForLogging ( response . body ) ; LogService . trace ( "MatrixHttpClient (REQ-" + requestId + " RESP-H" + response . statusCode + ")" , redactedBody ) ; } if ( response . statusCode < 200 || response . statusCode >= 300 ) { const redactedBody = respIsBuffer ? '<Buffer>' : redactObjectForLogging ( response . body ) ; LogService . error ( "MatrixHttpClient (REQ-" + requestId + ")" , redactedBody ) ; reject ( response ) ; } else resolve ( raw ? response : resBody ) ; } } ) ; } ) ; } export function redactObjectForLogging ( input ) { if ( ! input ) return input ; const fieldsToRedact = [ 'access_token' , 'password' , 'new_password' , ] ; const redactFn = ( i ) => { if ( ! i ) return i ; if ( typeof i === 'string' ) return i ; if ( Array . isArray ( i ) ) { const rebuilt = [ ] ; for ( const v of i ) { rebuilt . push ( redactFn ( v ) ) ; } return rebuilt ; } if ( i instanceof Object ) { const rebuilt = { } ; for ( const key of Object . keys ( i ) ) { if ( fieldsToRedact . includes ( key ) ) { rebuilt [ key ] = '<redacted>' ; } else { rebuilt [ key ] = redactFn ( i [ key ] ) ; } } return rebuilt ; } return i ; } ; return redactFn ( input ) ; }