Skip to content

Commit

Permalink
feat: Add base x-goog-api-client for XML API
Browse files Browse the repository at this point in the history
  • Loading branch information
d-goog committed Sep 25, 2023
1 parent 5d590fd commit ab5a3eb
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 40 deletions.
63 changes: 34 additions & 29 deletions src/transfer-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ import {ApiError} from './nodejs-common';
import {GaxiosResponse, Headers} from 'gaxios';
import {createHash} from 'crypto';
import {GCCL_GCS_CMD_KEY} from './nodejs-common/util';
import {getRuntimeTrackingString} from './util';

const packageJson = require('../../package.json');

/**
* Default number of concurrently executing promises to use when calling uploadManyFiles.
Expand Down Expand Up @@ -200,6 +203,33 @@ class XMLMultiPartUploadHelper implements MultiPartUploadHelper {
};
}

#setGoogApiClientHeaders(headers: Headers = {}): Headers {
let headerFound = false;

for (const [key, value] of Object.entries(headers)) {
if (key.toLocaleLowerCase().trim() === 'x-goog-api-client') {
headerFound = true;

// Prepend command feature to value, if not already there
if (!value.includes(GCCL_GCS_CMD_FEATURE.UPLOAD_SHARDED)) {
headers[
key
] = `${value} gccl-gcs-cmd/${GCCL_GCS_CMD_FEATURE.UPLOAD_SHARDED}`;
}
break;
}
}

// If the header isn't present, add it
if (!headerFound) {
headers['x-goog-api-client'] = `${getRuntimeTrackingString()} gccl/${
packageJson.version
} gccl-gcs-cmd/${GCCL_GCS_CMD_FEATURE.UPLOAD_SHARDED}`;
}

return headers;
}

/**
* Initiates a multipart upload (MPU) to the XML API and stores the resultant upload id.
*
Expand All @@ -209,38 +239,12 @@ class XMLMultiPartUploadHelper implements MultiPartUploadHelper {
const url = `${this.baseUrl}?uploads`;
return retry(async bail => {
try {
const combinedHeaders = {
...(await this.authClient.getRequestHeaders(url)),
...headers,
};

let headerFound = false;

for (const [key, value] of Object.entries(combinedHeaders)) {
if (key.toLocaleLowerCase().trim() === 'x-goog-api-client') {
headerFound = true;

// Prepend command feature to value, if not already there
if (!value.includes(GCCL_GCS_CMD_FEATURE.UPLOAD_SHARDED)) {
combinedHeaders[
key
] = `${value} gccl-gcs-cmd/${GCCL_GCS_CMD_FEATURE.UPLOAD_SHARDED}`;
}
break;
}
}

if (!headerFound) {
combinedHeaders[
'x-goog-api-client'
] = `gccl-gcs-cmd/${GCCL_GCS_CMD_FEATURE.UPLOAD_SHARDED}`;
}

const res = await this.authClient.request({
headers: combinedHeaders,
headers: this.#setGoogApiClientHeaders(headers),
method: 'POST',
url,
});

if (res.data && res.data.error) {
throw res.data.error;
}
Expand Down Expand Up @@ -271,7 +275,7 @@ class XMLMultiPartUploadHelper implements MultiPartUploadHelper {
validation?: 'md5' | false
): Promise<void> {
const url = `${this.baseUrl}?partNumber=${partNumber}&uploadId=${this.uploadId}`;
let headers: Headers = {};
let headers: Headers = this.#setGoogApiClientHeaders();

if (validation === 'md5') {
const hash = createHash('md5').update(chunk).digest('base64');
Expand Down Expand Up @@ -318,6 +322,7 @@ class XMLMultiPartUploadHelper implements MultiPartUploadHelper {
return retry(async bail => {
try {
const res = await this.authClient.request({
headers: this.#setGoogApiClientHeaders(),
url,
method: 'POST',
body,
Expand Down
22 changes: 11 additions & 11 deletions test/transfer-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,8 +474,8 @@ describe('Transfer Manager', () => {
);
});

it('should set the appropriate `GCCL_GCS_CMD_KEY` - simple upload', async () => {
let firstCall = true;
it('should set the appropriate `GCCL_GCS_CMD_KEY`', async () => {
let called = true;
class TestAuthClient extends AuthClient {
async getAccessToken() {
return {token: '', res: undefined};
Expand All @@ -486,16 +486,14 @@ describe('Transfer Manager', () => {
}

async request(opts: GaxiosOptions) {
if (firstCall) {
firstCall = false;
called = true;

assert(opts.headers);
assert('x-goog-api-client' in opts.headers);
assert.match(
opts.headers['x-goog-api-client'],
/gccl-gcs-cmd\/tm.upload_sharded/
);
}
assert(opts.headers);
assert('x-goog-api-client' in opts.headers);
assert.match(
opts.headers['x-goog-api-client'],
/gccl-gcs-cmd\/tm.upload_sharded/
);

return {
data: Buffer.from(
Expand All @@ -513,6 +511,8 @@ describe('Transfer Manager', () => {
});

await transferManager.uploadFileInChunks(filePath);

assert(called);
});
});
});

0 comments on commit ab5a3eb

Please sign in to comment.