Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
b2e12e7
fix(storage): standardize URL formatting and enhance transport retry
thiyaguk09 May 7, 2026
a55baa3
fix storage transport & retry issues
thiyaguk09 May 7, 2026
d50bc9e
fix
thiyaguk09 May 7, 2026
618abb6
Update handwritten/storage/src/file.ts
thiyaguk09 May 7, 2026
2a2ef77
fix(storage): interceptors test
thiyaguk09 May 7, 2026
65f9f33
fix(storage): standardize URL formatting and enhance transport retry
thiyaguk09 May 7, 2026
1ae557f
refactor(storage): remove Service.ts and migrate logic to StorageTran…
thiyaguk09 May 14, 2026
f3b81f0
Merge remote-tracking branch 'upstream/storage-node-18' into storage-…
thiyaguk09 May 14, 2026
bd33380
fix(storage): standardize URL formatting and enhance transport retry
thiyaguk09 May 7, 2026
cc411a0
refactor(storage): remove Service.ts and migrate logic to StorageTran…
thiyaguk09 May 14, 2026
d8385a4
Merge remote-tracking branch 'upstream/storage-node-18' into storage-…
thiyaguk09 May 14, 2026
128bf0a
fix(storage): standardize URL formatting and enhance transport retry
thiyaguk09 May 7, 2026
9010041
refactor(storage): remove Service.ts and migrate logic to StorageTran…
thiyaguk09 May 14, 2026
cf7060a
Merge remote-tracking branch 'upstream/storage-node-18' into storage-…
thiyaguk09 May 15, 2026
7b6d68b
fix(storage): standardize URL formatting and enhance transport retry
thiyaguk09 May 7, 2026
0e8f067
refactor(storage): remove Service.ts and migrate logic to StorageTran…
thiyaguk09 May 14, 2026
7fe696a
Merge remote-tracking branch 'upstream/storage-node-18' into storage-…
thiyaguk09 May 18, 2026
e399bea
feat: implement robust storage conformance test retry framework with …
thiyaguk09 May 18, 2026
df71511
fix: correct response handler for binary/resumable uploads and improv…
thiyaguk09 May 19, 2026
e506e77
Merge remote-tracking branch 'upstream/storage-node-18' into storage-…
thiyaguk09 May 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions handwritten/storage/src/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1405,7 +1405,12 @@ class File extends ServiceObject<File, FileMetadata> {
}

if (newFile.encryptionKey !== undefined) {
this.setEncryptionKey(newFile.encryptionKey!);
headers.set('x-goog-encryption-algorithm', 'AES256');
headers.set('x-goog-encryption-key', newFile.encryptionKeyBase64 || '');
headers.set(
'x-goog-encryption-key-sha256',
newFile.encryptionKeyHash || '',
);
} else if (options.destinationKmsKeyName !== undefined) {
query.destinationKmsKeyName = options.destinationKmsKeyName;
delete options.destinationKmsKeyName;
Expand Down Expand Up @@ -1639,6 +1644,8 @@ class File extends ServiceObject<File, FileMetadata> {
}

const headers = response.headers;
const isStoredCompressed =
headers.get('x-goog-stored-content-encoding') === 'gzip';
const isCompressed = headers.get('content-encoding') === 'gzip';
const hashes: {crc32c?: string; md5?: string} = {};

Expand All @@ -1652,7 +1659,7 @@ class File extends ServiceObject<File, FileMetadata> {

const transformStreams: Transform[] = [];

if (shouldRunValidation) {
if (shouldRunValidation && !isStoredCompressed) {
// The x-goog-hash header should be set with a crc32c and md5 hash.
// ex: headers.set('x-goog-hash', 'crc32c=xxxx,md5=xxxx')
if (typeof headers.get('x-goog-hash') === 'string') {
Expand Down Expand Up @@ -1721,6 +1728,7 @@ class File extends ServiceObject<File, FileMetadata> {
const headers = {
'Accept-Encoding': 'gzip',
'Cache-Control': 'no-store',
...(this.encryptionKeyHeaders || {}),
} as Headers;

if (rangeRequest) {
Expand All @@ -1735,7 +1743,9 @@ class File extends ServiceObject<File, FileMetadata> {
headers,
queryParameters: query as unknown as StorageQueryParameters,
responseType: 'stream',
};
decompress: options.decompress,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any;

if (options[GCCL_GCS_CMD_KEY]) {
reqOpts[GCCL_GCS_CMD_KEY] = options[GCCL_GCS_CMD_KEY];
Expand Down Expand Up @@ -2426,6 +2436,18 @@ class File extends ServiceObject<File, FileMetadata> {
}
}

get encryptionKeyHeaders(): Record<string, string> | undefined {
if (!this.encryptionKey) {
return undefined;
}

return {
'x-goog-encryption-algorithm': 'AES256',
'x-goog-encryption-key': this.encryptionKey.toString('base64'),
'x-goog-encryption-key-sha256': this.encryptionKeyHash || '',
};
}

/**
* The Storage API allows you to use a custom key for server-side encryption.
*
Expand Down Expand Up @@ -4562,6 +4584,14 @@ class File extends ServiceObject<File, FileMetadata> {
},
];

const headers: Record<string, string> = {};
if (this.encryptionKey) {
headers['x-goog-encryption-algorithm'] = 'AES256';
headers['x-goog-encryption-key'] = this.encryptionKeyBase64!;
headers['x-goog-encryption-key-sha256'] = this.encryptionKeyHash!;
}
reqOpts.headers = headers;

this.storageTransport
.makeRequest(reqOpts as StorageRequestOptions, (err, body, resp) => {
if (err) {
Expand Down
30 changes: 22 additions & 8 deletions handwritten/storage/src/nodejs-common/service-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import {promisifyAll} from '@google-cloud/promisify';
import {EventEmitter} from 'events';
import {util} from './util.js';
import {Bucket} from '../bucket.js';
import {StorageRequestOptions, StorageTransport} from '../storage-transport.js';
import {
GaxiosError,
Expand Down Expand Up @@ -293,8 +292,8 @@ class ServiceObject<T, K extends BaseMetadata> extends EventEmitter {
(typeof this.methods.delete === 'object' && this.methods.delete) || {};

let url = `${this.baseUrl}/${this.id}`;
if (this.parent instanceof Bucket) {
url = `${this.parent.baseUrl}/${this.parent.id}${url}`;
if (this.parent && this.parent.constructor.name === 'Bucket') {
url = `${this.parent.baseUrl}/${(this.parent as any).id}${url}`;
}

this.storageTransport
Expand Down Expand Up @@ -440,20 +439,35 @@ class ServiceObject<T, K extends BaseMetadata> extends EventEmitter {
{};

let url = `${this.baseUrl}/${this.id}`;
if (this.parent instanceof Bucket) {
url = `${this.parent.baseUrl}/${this.parent.id}${url}`;
if (this.parent && this.parent.constructor.name === 'Bucket') {
url = `${this.parent.baseUrl}/${(this.parent as any).id}${url}`;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const encryptionHeaders = (this as any).encryptionKeyHeaders || {};

const headers = {
...encryptionHeaders,
...methodConfig.reqOpts?.headers,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...(options as any).headers,
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const query = {...options} as any;
delete query.headers;

this.storageTransport
.makeRequest<K>(
{
method: 'GET',
responseType: 'json',
url,
...methodConfig.reqOpts,
headers,
queryParameters: {
...methodConfig.reqOpts?.queryParameters,
...options,
...query,
},
},
(err, data, resp) => {
Expand Down Expand Up @@ -498,8 +512,8 @@ class ServiceObject<T, K extends BaseMetadata> extends EventEmitter {
{};

let url = `${this.baseUrl}/${this.name}`;
if (this.parent instanceof Bucket) {
url = `${this.parent.baseUrl}/${this.parent.name}${url}`;
if (this.parent && this.parent.constructor.name === 'Bucket') {
url = `${this.parent.baseUrl}/${(this.parent as any).name}${url}`;
}

const body = Object.assign({}, methodConfig.reqOpts?.body, metadata);
Expand Down
Loading
Loading