in packages/api-rest/src/RestClient.ts [91:226]
async ajax(urlOrApiInfo: string | ApiInfo, method: string, init) {
logger.debug(method, urlOrApiInfo);
let parsed_url;
let url: string;
let region: string = 'us-east-1';
let service: string = 'execute-api';
let custom_header: () => {
[key: string]: string;
} = undefined;
if (typeof urlOrApiInfo === 'string') {
parsed_url = this._parseUrl(urlOrApiInfo);
url = urlOrApiInfo;
} else {
({ endpoint: url, custom_header, region, service } = urlOrApiInfo);
parsed_url = this._parseUrl(urlOrApiInfo.endpoint);
}
const params = {
method,
url,
host: parsed_url.host,
path: parsed_url.path,
headers: {},
data: null,
responseType: 'json',
timeout: 0,
cancelToken: null,
};
let libraryHeaders = {};
if (Platform.isReactNative) {
const userAgent = Platform.userAgent || 'aws-amplify/0.1.x';
libraryHeaders = {
'User-Agent': userAgent,
};
}
const initParams = Object.assign({}, init);
const isAllResponse = initParams.response;
if (initParams.body) {
if (
typeof FormData === 'function' &&
initParams.body instanceof FormData
) {
libraryHeaders['Content-Type'] = 'multipart/form-data';
params.data = initParams.body;
} else {
libraryHeaders['Content-Type'] = 'application/json; charset=UTF-8';
params.data = JSON.stringify(initParams.body);
}
}
if (initParams.responseType) {
params.responseType = initParams.responseType;
}
if (initParams.withCredentials) {
params['withCredentials'] = initParams.withCredentials;
}
if (initParams.timeout) {
params.timeout = initParams.timeout;
}
if (initParams.cancellableToken) {
params.cancelToken = initParams.cancellableToken.token;
}
params['signerServiceInfo'] = initParams.signerServiceInfo;
// custom_header callback
const custom_header_obj =
typeof custom_header === 'function' ? await custom_header() : undefined;
params.headers = {
...libraryHeaders,
...custom_header_obj,
...initParams.headers,
};
// Intentionally discarding search
const { search, ...parsedUrl } = parse(url, true, true);
params.url = format({
...parsedUrl,
query: {
...parsedUrl.query,
...(initParams.queryStringParameters || {}),
},
});
// Do not sign the request if client has added 'Authorization' header,
// which means custom authorizer.
if (typeof params.headers['Authorization'] !== 'undefined') {
params.headers = Object.keys(params.headers).reduce((acc, k) => {
if (params.headers[k]) {
acc[k] = params.headers[k];
}
return acc;
// tslint:disable-next-line:align
}, {});
return this._request(params, isAllResponse);
}
// Signing the request in case there credentials are available
return this.Credentials.get().then(
credentials => {
return this._signed({ ...params }, credentials, isAllResponse, {
region,
service,
}).catch(error => {
if (DateUtils.isClockSkewError(error)) {
const { headers } = error.response;
const dateHeader = headers && (headers.date || headers.Date);
const responseDate = new Date(dateHeader);
const requestDate = DateUtils.getDateFromHeaderString(
params.headers['x-amz-date']
);
// Compare local clock to the server clock
if (DateUtils.isClockSkewed(responseDate)) {
DateUtils.setClockOffset(
responseDate.getTime() - requestDate.getTime()
);
return this.ajax(urlOrApiInfo, method, init);
}
}
throw error;
});
},
err => {
logger.debug('No credentials available, the request will be unsigned');
return this._request(params, isAllResponse);
}
);
}