Skip to content

Commit

Permalink
Impl. size-dependent request body compression (#4283)
Browse files Browse the repository at this point in the history
For both Public and Internal API
  • Loading branch information
pvannierop authored Jun 7, 2022
1 parent 91e8f0c commit 1ea79f5
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 91 deletions.
50 changes: 0 additions & 50 deletions src/config/config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,54 +29,4 @@ describe('ServerConfigHelpers', () => {
});
});
});

describe('pairMatchesPath', () => {
it('should match exact match', () => {
const pair: UrlParamPair = { url: '/foo/', params: { a: '1' } };
const ans = pairMatchesPath(pair, '/foo/bar/baz', { a: '1' });

assert.isTrue(ans);
});

it('should match exact match with empty params', () => {
const pair: UrlParamPair = { url: '/foo/', params: {} };
const ans = pairMatchesPath(pair, '/foo/bar/baz', {});

assert.isTrue(ans);
});

it('should match exact match with extra params', () => {
const pair: UrlParamPair = { url: '/foo/', params: { a: '1' } };
const ans = pairMatchesPath(pair, '/foo/bar/baz', {
a: '1',
b: '1',
});

assert.isTrue(ans);
});

it('should not match exact when missing all params', () => {
const pair: UrlParamPair = { url: '/foo/', params: { a: '1' } };
const ans = pairMatchesPath(pair, '/foo/bar/baz', {});

assert.isFalse(ans);
});

it('should not match exact when missing some params', () => {
const pair: UrlParamPair = {
url: '/foo/',
params: { a: '1', b: '1' },
};
const ans = pairMatchesPath(pair, '/foo/bar/baz', { a: '1' });

assert.isFalse(ans);
});

it('should not match when param has different val', () => {
const pair: UrlParamPair = { url: '/foo/', params: { a: '1' } };
const ans = pairMatchesPath(pair, '/foo/bar/baz', { a: '2' });

assert.isFalse(ans);
});
});
});
58 changes: 17 additions & 41 deletions src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import pako from 'pako';

const win = window as any;

const REQ_BODY_SIZE_CHAR_LIMIT = 10000;

// these should not be exported. they should only be accessed
// via getServerConfig and getLoadConfig
const config: any = { serverConfig: {} };
Expand Down Expand Up @@ -202,49 +204,22 @@ export function initializeAPIClients() {
}

if (getServerConfig().enable_request_body_gzip_compression) {
compressRequestBodies(
CBioPortalAPI,
[
{ url: '/mutations/fetch', params: {} },
{ url: '/structural-variant/fetch', params: {} },
{ url: '/clinical-attributes/counts/fetch', params: {} },
{ url: '/patients/fetch', params: {} },
{ url: '/molecular-data/fetch', params: {} },
{
url: '/clinical-data/fetch',
params: { clinicalDataType: 'SAMPLE' },
},
{ url: '/gene-panel-data/fetch', params: {} },
{
url: '/clinical-data/fetch',
params: { clinicalDataType: 'PATIENT' },
},
],
registerRequestBodyCompression(CBioPortalAPI, getCbioPortalApiUrl());
registerRequestBodyCompression(
CBioPortalAPIInternal,
getCbioPortalApiUrl()
);
}
}

/**
* Compresses the request bodies of POST calls of urls that start with
* domain + urlToCompress, and adds the Content-Encoding header. To do this,
* Compresses the request bodies of POST calls of urls with large
* request body size, and adds the Content-Encoding header. To do this,
* it wraps the api client's request function.
* @param apiClient
* @param urlsToCompress
* @param domain
*/
function compressRequestBodies(
apiClient: any,
urlsToCompress: UrlParamPair[],
domain: string
): void {
urlsToCompress = urlsToCompress.map(pair => {
return {
url: domain + pair.url,
params: pair.params,
};
});

function registerRequestBodyCompression(apiClient: any, domain: string): void {
const oldRequestFunc = apiClient.prototype.request;

const newRequestFunc = (
Expand All @@ -258,14 +233,15 @@ function compressRequestBodies(
resolve: any,
errorHandlers: any[]
) => {
if (
method === 'POST' &&
urlsToCompress.filter(pair =>
pairMatchesPath(pair, url, queryParameters)
).length > 0
) {
headers['Content-Encoding'] = 'gzip';
body = pako.gzip(JSON.stringify(body)).buffer;
if (method === 'POST') {
var bodyString = JSON.stringify(body);
if (bodyString.length > REQ_BODY_SIZE_CHAR_LIMIT) {
headers['Content-Encoding'] = 'gzip';
body = pako.gzip(bodyString).buffer;
} else {
// Store stringified body, so that stringify only runs once.
body = bodyString;
}
}

oldRequestFunc(
Expand Down

0 comments on commit 1ea79f5

Please sign in to comment.