Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 11 additions & 11 deletions handwritten/storage/src/acl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -528,10 +528,10 @@ class Acl extends AclRoleAccessorMethods {
if (this.parent instanceof File) {
const file = this.parent as File;
const bucket = file.parent;
url = `${bucket.baseUrl}/${bucket.name}/${file.baseUrl}/${file.name}${url}`;
url = `/storage/v1/b/${bucket.name}/o/${encodeURIComponent(file.name)}${url}`;
} else if (this.parent instanceof Bucket) {
const bucket = this.parent as Bucket;
url = `${bucket.baseUrl}/${bucket.name}${url}`;
url = `/storage/v1/b/${bucket.name}${url}`;
}

this.storageTransport
Expand Down Expand Up @@ -644,14 +644,14 @@ class Acl extends AclRoleAccessorMethods {
query.userProject = options.userProject;
}

let url = `${this.pathPrefix}/${options.entity}`;
let url = `${this.pathPrefix}/${encodeURIComponent(options.entity)}`;
if (this.parent instanceof File) {
const file = this.parent as File;
const bucket = file.parent;
url = `${bucket.baseUrl}/${bucket.name}/${file.baseUrl}/${file.name}${url}`;
url = `/storage/v1/b/${bucket.name}/o/${encodeURIComponent(file.name)}${url}`;
} else if (this.parent instanceof Bucket) {
const bucket = this.parent as Bucket;
url = `${bucket.baseUrl}/${bucket.name}${url}`;
url = `/storage/v1/b/${bucket.name}${url}`;
}

this.storageTransport
Expand Down Expand Up @@ -768,7 +768,7 @@ class Acl extends AclRoleAccessorMethods {

let url = `${this.pathPrefix}`;
if (options) {
url = `${url}/${options.entity}`;
url = `${url}/${encodeURIComponent(options.entity)}`;
if (options.generation) {
query.generation = options.generation;
}
Expand All @@ -781,10 +781,10 @@ class Acl extends AclRoleAccessorMethods {
if (this.parent instanceof File) {
const file = this.parent as File;
const bucket = file.parent;
url = `${bucket.baseUrl}/${bucket.name}/${file.baseUrl}/${file.name}${url}`;
url = `/storage/v1/b/${bucket.name}/o/${encodeURIComponent(file.name)}${url}`;
} else if (this.parent instanceof Bucket) {
const bucket = this.parent as Bucket;
url = `${bucket.baseUrl}/${bucket.name}${url}`;
url = `/storage/v1/b/${bucket.name}${url}`;
}

this.storageTransport
Expand Down Expand Up @@ -888,14 +888,14 @@ class Acl extends AclRoleAccessorMethods {
query.userProject = options.userProject;
}

let url = `${this.pathPrefix}/${options.entity}`;
let url = `${this.pathPrefix}/${encodeURIComponent(options.entity)}`;
if (this.parent instanceof File) {
const file = this.parent as File;
const bucket = file.parent;
url = `${bucket.baseUrl}/${bucket.name}/${file.baseUrl}/${file.name}${url}`;
url = `/storage/v1/b/${bucket.name}/o/${encodeURIComponent(file.name)}${url}`;
} else if (this.parent instanceof Bucket) {
const bucket = this.parent as Bucket;
url = `${bucket.baseUrl}/${bucket.name}${url}`;
url = `/storage/v1/b/${bucket.name}${url}`;
}

this.storageTransport
Expand Down
10 changes: 8 additions & 2 deletions handwritten/storage/src/bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,7 @@ class Bucket extends ServiceObject<Bucket, BucketMetadata> {
super({
storageTransport: storage.storageTransport,
parent: storage,
baseUrl: '/b',
baseUrl: '/storage/v1/b',
id: name,
createMethod: storage.createBucket.bind(storage),
methods,
Expand Down Expand Up @@ -1688,7 +1688,7 @@ class Bucket extends ServiceObject<Bucket, BucketMetadata> {
.makeRequest(
{
method: 'POST',
url: '/compose',
url: `/storage/v1/b/${this.name}/o/${encodeURIComponent(destinationFile.name)}/compose`,
maxRetries,
body: JSON.stringify({
destination: {
Expand All @@ -1709,6 +1709,9 @@ class Bucket extends ServiceObject<Bucket, BucketMetadata> {
return sourceObject;
}),
}),
headers: {
'Content-Type': 'application/json',
},
queryParameters: options as unknown as StorageQueryParameters,
},
(err, resp) => {
Expand Down Expand Up @@ -2050,6 +2053,9 @@ class Bucket extends ServiceObject<Bucket, BucketMetadata> {
body: JSON.stringify(convertObjKeysToSnakeCase(body)),
queryParameters: query as unknown as StorageQueryParameters,
retry: false,
headers: {
'Content-Type': 'application/json',
},
},
(err, data, resp) => {
if (err) {
Expand Down
5 changes: 4 additions & 1 deletion handwritten/storage/src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Channel extends ServiceObject<Channel, BaseMetadata> {
const config = {
parent: storage,
storageTransport: storage.storageTransport,
baseUrl: '/channels',
baseUrl: '/storage/v1/channels',
id: '',
methods: {},
};
Expand Down Expand Up @@ -89,6 +89,9 @@ class Channel extends ServiceObject<Channel, BaseMetadata> {
method: 'POST',
url: `${this.baseUrl}/stop`,
body: JSON.stringify(this.metadata),
headers: {
'Content-Type': 'application/json',
},
responseType: 'json',
},
(err, data, resp) => {
Expand Down
113 changes: 74 additions & 39 deletions handwritten/storage/src/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ import {
StorageQueryParameters,
StorageRequestOptions,
} from './storage-transport.js';
import * as gaxios from 'gaxios';
import mime from 'mime';

export type GetExpirationDateResponse = [Date];
Expand Down Expand Up @@ -1363,13 +1362,24 @@ 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',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(newFile as any).encryptionKeyBase64 || '',
);
headers.set(
'x-goog-encryption-key-sha256',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(newFile as any).encryptionKeyHash || '',
);
} else if (options.destinationKmsKeyName !== undefined) {
query.destinationKmsKeyName = options.destinationKmsKeyName;
delete options.destinationKmsKeyName;
} else if (newFile.kmsKeyName !== undefined) {
query.destinationKmsKeyName = newFile.kmsKeyName;
}
headers.set('Content-Type', 'application/json');

if (query.destinationKmsKeyName) {
this.kmsKeyName = query.destinationKmsKeyName;
Expand Down Expand Up @@ -1399,7 +1409,7 @@ class File extends ServiceObject<File, FileMetadata> {
.makeRequest<RewriteResponse>(
{
method: 'POST',
url: `/b/${this.bucket.name}/o/${encodeURIComponent(this.name)}/rewriteTo/b/${
url: `/storage/v1/b/${this.bucket.name}/o/${encodeURIComponent(this.name)}/rewriteTo/b/${
destBucket.name
}/o/${encodeURIComponent(newFile.name)}`,
queryParameters: query as unknown as StorageQueryParameters,
Expand Down Expand Up @@ -1596,6 +1606,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 @@ -1609,7 +1621,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 @@ -1678,8 +1690,13 @@ class File extends ServiceObject<File, FileMetadata> {
const headers = {
'Accept-Encoding': 'gzip',
'Cache-Control': 'no-store',
...(this.encryptionKeyHeaders || {}),
} as Headers;

if (options.decompress === false) {
headers['Accept-Encoding'] = 'gzip';
}

if (rangeRequest) {
const start = typeof options.start === 'number' ? options.start : '0';
const end = typeof options.end === 'number' ? options.end : '';
Expand All @@ -1688,11 +1705,13 @@ class File extends ServiceObject<File, FileMetadata> {
}

const reqOpts: StorageRequestOptions = {
url: `${this.bucket.baseUrl}/${this.bucket.name}${this.baseUrl}/${this.name}`,
url: `/storage/v1/b/${this.bucket.name}/o/${encodeURIComponent(this.name)}`,
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 @@ -2368,6 +2387,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 @@ -3252,39 +3283,35 @@ class File extends ServiceObject<File, FileMetadata> {
*/

isPublic(callback?: IsPublicCallback): Promise<IsPublicResponse> | void {
// Build any custom headers based on the defined interceptors on the parent
// storage object and this object
const storageInterceptors = this.storage?.interceptors || [];
const fileInterceptors = this.interceptors || [];
const allInterceptors = storageInterceptors.concat(fileInterceptors);

for (const curInter of allInterceptors) {
gaxios.instance.interceptors.request.add(curInter);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const {callback: cb} = normalize<any, IsPublicCallback>(
undefined,
callback,
);

const url = `/${this.bucket.name}/${encodeURIComponent(this.name)}`;
this.storageTransport
.makeRequest(
{
method: 'GET',
url: url,
},
err => {
if (!err) {
cb(null, true);
return;
}

const status = err.response?.status;
if (status === 401 || status === 403) {
cb(null, false);
return;
}

gaxios
.request({
method: 'GET',
url: `${this.storage.apiEndpoint}/${
this.bucket.name
}/${encodeURIComponent(this.name)}`,
retryConfig: {
retry: this.storage.retryOptions.maxRetries,
noResponseRetries: this.storage.retryOptions.maxRetries,
maxRetryDelay: this.storage.retryOptions.maxRetryDelay,
retryDelayMultiplier: this.storage.retryOptions.retryDelayMultiplier,
shouldRetry: this.storage.retryOptions.retryableErrorFn,
totalTimeout: this.storage.retryOptions.totalTimeout,
cb(err);
},
})
.then(() => callback!(null, true))
.catch(err => {
if (err.status === 403) {
callback!(null, false);
} else {
callback!(err);
}
});
)
.catch(err => callback!(err));
}

makePrivate(
Expand Down Expand Up @@ -3630,7 +3657,7 @@ class File extends ServiceObject<File, FileMetadata> {
.makeRequest(
{
method: 'POST',
url: `/b/${this.bucket.name}/o/${encodeURIComponent(this.name)}/moveTo/o/${encodeURIComponent(newFile.name)}`,
url: `/storage/v1/b/${this.bucket.name}/o/${encodeURIComponent(this.name)}/moveTo/o/${encodeURIComponent(newFile.name)}`,
queryParameters: query as StorageQueryParameters,
body: JSON.stringify(options),
},
Expand Down Expand Up @@ -3961,7 +3988,7 @@ class File extends ServiceObject<File, FileMetadata> {
async restore(options: RestoreOptions): Promise<File> {
const file = await this.storageTransport.makeRequest<File>({
method: 'POST',
url: `/b/${this.bucket.name}/o/${encodeURIComponent(this.name)}/restore`,
url: `/storage/v1/b/${this.bucket.name}/o/${encodeURIComponent(this.name)}/restore`,
queryParameters: options as unknown as StorageQueryParameters,
});
return file as File;
Expand Down Expand Up @@ -4488,6 +4515,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
Loading
Loading